zoukankan      html  css  js  c++  java
  • linux下的C语言开发 GDB的例子

      在很多人的眼里,C语言和linux常常是分不开的。这其中的原因很多,其中最重要的一部分我认为是linux本身就是C语言的杰出作品。当然,linux操作系统本身对C语言的支持也是相当到位的。作为一个真正的程序员来说,如果没有在linux下面用C语言编写过完整的程序,那么只能说他对C语言本身的理解还相关肤浅,对系统本身的认识也不够到位。作为程序员来说,linux系统为我们提供了很多理想的环境,这其中包括了下面几个方面,
        
        (1)完善的编译环境,包括gcc、as、ld等编译、链接工具
        (2)强大的调试环境,主要是gdb工具
        (3)丰富的自动编译工具,主要是make工具
        (4)多样化的os选择,ubuntu、redflag等等
        (5)浩瀚的开源代码库

        当然,不管我怎么说,最终朋友们还是应该自己勇敢地跨出前进的第一步。如果还没有过Linux编程经验的朋友可以首先在自己的pc上面安装一个虚拟机,然后就可以在shell下面编写自己的C语言代码了。

    [cpp] view plain copy
     
    1. #include <stdio.h>  
    2.   
    3. int main()  
    4. {  
    5.     printf("hello! ");  
    6.     return 1;  
    7. }    

        编写完上面的代码后,你需要做的就是两个步骤:1、输入 gcc hello.c -o hello;2、输入./hello。如果一切正常的话,此时你应该会在屏幕上看到一行hello的打印。如果你看到了,那么恭喜你,你已经可以开始linux的c语言编程之旅了。

        当然,我们不会满足于这么简单的打印功能。下面就可以编写一个简单的迭代函数,

    [cpp] view plain copy
     
    1. #include <stdio.h>  
    2.   
    3. int iterate(int value)  
    4. {  
    5.     if(1 == value)  
    6.         return 1;  
    7.     return iterate(value - 1) + value;  
    8. }  
    9.   
    10. int main()  
    11. {  
    12.     printf("%d ", iterate(10));  
    13.     return 1;      
    14. }  

        此时,同样我们需要重复上面的步骤:1、输入gcc hello.c -o hello;2、输入./hello。当然此时如果一切OK的话,你就会看到屏幕会有55这个数的输出。本来1到10的数据之和就是55, 这说明我们的程序是正确的。

      

    编写代码过程中少不了调试。在windows下面,我们有visual studio工具。在Linux下面呢,实际上除了gdb工具之外,你没有别的选择。那么,怎么用gdb进行调试呢?我们可以一步一步来试试看。

    [cpp] view plain copy
     
    1. #include <stdio.h>  
    2.   
    3. int iterate(int value)  
    4. {  
    5.     if(1 == value)  
    6.         return 1;  
    7.   
    8.     return iterate(value - 1) + value;  
    9. }  
    10.   
    11. int main()  
    12. {  
    13.     printf("%d ", iterate(10));  
    14.     return 1;  
    15. }  

        既然需要调试,那么生成的可执行文件就需要包含调试的信息,这里应该怎么做呢?很简单,输入 gcc test.c -g -o test。输入命令之后,如果没有编译和链接方面的错误,你就可以看到 可执行文件test了。

        调试的步骤基本如下所示,


    (01) 首先,输入gdb test
    (02) 进入到gdb的调试界面之后,输入list,即可看到test.c源文件
    (03) 设置断点,输入 b main 
    (04) 启动test程序,输入run 
    (05) 程序在main开始的地方设置了断点,所以程序在printf处断住
    (06) 这时候,可以单步跟踪。s单步可以进入到函数,而n单步则越过函数
    (07) 如果希望从断点处继续运行程序,输入c
    (08) 希望程序运行到函数结束,输入finish
    (09) 查看断点信息,输入 info break
    (10) 如果希望查看堆栈信息,输入bt
    (11) 希望查看内存,输入 x/64xh + 内存地址
    (12) 删除断点,则输入delete break + 断点序号
    (13) 希望查看函数局部变量的数值,可以输入print + 变量名

    (14)希望修改内存值,直接输入 print  + *地址 = 数值
    (15) 希望实时打印变量的数值,可以输入display + 变量名
    (16) 查看函数的汇编代码,输入 disassemble + 函数名
    (17) 退出调试输入quit即可



        当然, 还会有一些朋友对程序的反汇编感兴趣,那么他需要两个步骤:1、gcc hello.c -g -o hello;2、objdump -S -d ./hello。之所以在gcc编译的时候加上-g是为了添加调试信息,objdump中的-S选项是为了在显示汇编代码的时候同时显示原来的C语言源代码。

    [cpp] view plain copy
     
      1. int iterate(int value)  
      2. {  
      3.  8048374:       55                      push   %ebp  
      4.  8048375:       89 e5                   mov    %esp,%ebp  
      5.  8048377:       83 ec 08                sub    $0x8,%esp  
      6.     if(1 == value)  
      7.  804837a:       83 7d 08 01             cmpl   $0x1,0x8(%ebp)  
      8.  804837e:       75 09                   jne    8048389 <iterate+0x15>  
      9.         return 1;  
      10.  8048380:       c7 45 fc 01 00 00 00    movl   $0x1,0xfffffffc(%ebp)  
      11.  8048387:       eb 16                   jmp    804839f <iterate+0x2b>  
      12.     return iterate(value -1) + value;  
      13.  8048389:       8b 45 08                mov    0x8(%ebp),%eax  
      14.  804838c:       83 e8 01                sub    $0x1,%eax  
      15.  804838f:       89 04 24                mov    %eax,(%esp)  
      16.  8048392:       e8 dd ff ff ff          call   8048374 <iterate>  
      17.  8048397:       8b 55 08                mov    0x8(%ebp),%edx  
      18.  804839a:       01 c2                   add    %eax,%edx  
      19.  804839c:       89 55 fc                mov    %edx,0xfffffffc(%ebp)  
      20.  804839f:       8b 45 fc                mov    0xfffffffc(%ebp),%eax  
      21. }  
      22.  80483a2:       c9                      leave  
      23.  80483a3:       c3                      ret
  • 相关阅读:
    delphi验证码识别之如何识别高级验证码
    delphi验证码识别学习之图像的灰度化、二值化及反色
    js 数字,金额 用逗号 隔开。数字格式化
    fedora linux 下安装pwntcha[验证码开源]
    C#的多线程机制探索4
    【一天的作息时间】.....程序员们,好好看看
    我的图像之路之CAPTCHA 和 break CAPTCHA
    C#格式化字符串
    struts2拦截器
    java动态代理(JDK和cglib)
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/7372296.html
Copyright © 2011-2022 走看看