zoukankan      html  css  js  c++  java
  • 调试利器GDB(上)

    什么是GDB:

    GDB应用:

    静态分析工具与动态分析工具:

    GDB启动方式:

    GDB启动之后会有一个交互式的命令行,可以输入GDB特定的命令让GDB去工作。

    gdb test.out意思是这一次gdb启动关注的是test.out这个进程。

    gdb test.out core意思是程序崩溃时产生core文件。

    动态连接:

    gdb test.out pid意思是gdb去跟踪test.out这个程序文件对应的进程号为pid的进程。

    应用示例一:

    应用示例二:

    实验:

    test.c程序如下:

     1 #include <stdio.h>
     2 #include <unistd.h>
     3 
     4 extern int* g_pointer;
     5 extern void func();
     6 
     7 void test_1()
     8 {
     9     printf("test_1() : %p
    ", test_1);
    10 }
    11 
    12 void test_2()
    13 {
    14     printf("test_2() : %p
    ", test_2);
    15 }
    16 
    17 void test_3()
    18 {
    19     printf("test_3() : %p
    ", test_3);
    20 }
    21 
    22 int main(int argc, char *argv[])
    23 {
    24     typedef void(TFunc)();
    25     TFunc* fa[] = {test_1, test_2, test_3};
    26     int i = 0;
    27     
    28     printf("main() : begin...
    ");
    29     
    30     for(i=0; i<argc; i++)
    31     {
    32         printf("argv[%d] = %s
    ", i, argv[i]);
    33     }
    34     
    35     for(i=0; i<100; i++)
    36     {
    37         fa[i%3]();
    38         sleep(argc > 1);
    39     }
    40 
    41     printf("g_pointer = %p
    ", g_pointer);
    42 
    43     func();
    44     
    45     printf("main() : end...
    ");
    46 
    47     return 0;
    48 }

    func.c如下:

     1 #include <stdio.h>
     2 
     3 int* g_pointer;
     4 
     5 void func()
     6 {
     7     *g_pointer = (int)"D.T.Software";
     8 
     9     return;
    10 }

    test程序直接运行会产生段错误:

    如果想使用gdb调试,那么程序编译时需要带上调试信息,即:

    gcc  -g  test.c func.c -o test.out

    然后使用命令 ulimit  -c unlimited,这条命令的意思就是在程序崩溃的时候产生core文件。

    再次运行程序结果如下:

    可以看到产生了core文件。

     下一步就可以借助gdb进行调试了。

    可以看到gdb给我们指出了问题,在func.c的第七行。

     

    g_pointer是指向0地址处的。

    单独运行gdb并载入test.out:

    输入run,结果如下:

    gdb会动态的跟踪进程的执行,发现向0地址写东西会立即告诉我们。

    再次进行如下的实验:

     ctrl+c可以让test.out进程暂停,如果想继续执行,敲入continue:

    gdb动态连接的实验:

    先启动test.out进程:

    在另一个中端里面使用ps  aux查看进程号,然后跟踪这个进程:

    attach到test.out进程后,这个进程就暂停执行了。

    敲入continue继续执行:

    执行到最后结果如下:

    gdb断点调试:

    软件断点只对加载到内存中执行的程序有效。

    在flash中执行的程序只能打硬件断点。

    break设置的断点总是有效的,tbreak设置的断点只有一次有效。

    断点相关操作:

    delete删除断点可以指定断点的号,1,2,n都是短点号。

    硬件断点应用:

    实验:

    run命令启动程序后继续向下执行,start启动程序后立即暂停:

    可以看到start启动后自动设置了一个临时断点。停止在了main函数的入口处。

    打断点:

    next会执行下一条指令。

    我们不可能用next一直执行下去,需要有其他的手段。

    打印一下i的值:

    $1、$2代表第一次打印和第二次打印。

    我们将i的值设置为了100,再次执行next:

    可以看到执行了两次next之后程序到了第41行。

    设置一个一次性断点,并继续执行:

    程序到了第43行,但是还没有调用func函数。

    我们可以通过命令跳过第43行func函数的执行:

     跳过func函数,程序没有崩溃,这说明我们之前的程序崩溃发生在func函数中。

    在进行第二次调试:

    程序到了第25行,我们通过tbreak打一个断点,通过函数名字打断点,然后continue继续执行:

     程序停下来了,停在了func函数的第7行:

    在第一次调试时,我们确定了是func函数出现了问题,为了确认就是func函数内部出了问题,现在我们通过return强制func函数返回:

    返回后继续执行:

    启动第三次调试:

    当前系统只支持一个硬件断点。

    打硬件断点,并继续执行:

    程序停在了func的第七行:

     打印并设置g_pointer的值:

    敲continue继续执行:

    可以看到程序正常结束了,没有产生崩溃。

    小结:

  • 相关阅读:
    【40讲系列1】数组、链表
    更改凭证类型
    将公司代码设置给生产性的(不能删除业务数据的配置)
    使用参考过账
    查看凭证行项目
    查看凭证过账行项目
    预制凭证
    做凭证时凭证日期等于过账日期
    英语-20210302
    自动计算税额
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9821098.html
Copyright © 2011-2022 走看看