• gdb调试1--包括反汇编及文件编码设置


    一。编译

    gcc的完整编译过程大致为:预处理->编译->汇编->链接

    前三个步骤分别对应了-E、-S、-c三个选项。

    编译阶段命令截断后的产物
        C源程序
    预处理 gcc -E 替换了宏的C源程序(没有了#define,#include…), 删除了注释
    编译 gcc -S 汇编源程序
    汇编 gcc -c 目标文件,二进制文件, 允许有不在此文件中的外部变量、函数
    链接 gcc 可执行程序,一般由多个目标文件或库链接而成, 二进制文件,所有变量、函数都必须找得到

     objdump是linux下一款反汇编工具,能够反汇编目标文件、可执行文件。

    主要选项:

    objdump -f 
    显示文件头信息
    
    objdump -d 
    反汇编需要执行指令的那些section
    
    objdump -D 
    与-d类似,但反汇编中的所有section
    
    objdump -h 
    显示Section Header信息
    
    objdump -x 
    显示全部Header信息
    
    objdump -s 
    将所有段的内容以十六进制的方式打印出来

    gcc -c -o main.o main.c objdump -s -d main.o > main.o.txt

    gcc -o main main.c objdump -s -d main > main.txt
    因为 linux 下目标文件和可执行文件的内容格式是一样的, 所以 objdump 既可以反汇编可执行文件也可以反汇编目标文件。

    $ g++ main.cpp -o xmain

    $ ./xmain 

     

    $ file xmain
    xmain: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=86d2a0552a2e36ac27d4c233c9ddfd462e0e599d, not stripped

    $nm xmain

    0000000000601068 B __bss_start
    0000000000601190 b completed.6973
    0000000000601191 b _ZStL8__ioinit
    U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4

    $ strip xmain
    $ nm xmain

    : no symbols

     在实际的开发中, 经常需要对动态库.so进行strip操作, 减少占地空间。 而在调试的时候(比如用addr2line), 就需要符号了。 因此, 通常的做法是: strip前的库用来调试, strip后的库用来实际发布, 他们两者有对应关系。 一旦发布的strip后的库出了问题, 就可以找对应的未strip的库来定位。

     

    二。调试

    $ gcc -g main.cpp -o xmain

     $ gdb xmain

    (gdb) help
    List of classes of commands:

    aliases -- Aliases of other commands
    breakpoints -- Making program stop at certain points
    data -- Examining data
    files -- Specifying and examining files
    internals -- Maintenance commands
    obscure -- Obscure features
    running -- Running the program
    stack -- Examining the stack
    status -- Status inquiries
    support -- Support facilities
    tracepoints -- Tracing of program execution without stopping the program
    user-defined -- User-defined commands

    Type "help" followed by a class name for a list of commands in that class.
    Type "help all" for the list of all commands.
    Type "help" followed by command name for full documentation.
    Type "apropos word" to search for commands related to "word".
    Command name abbreviations are allowed if unambiguous.

    查看编码:

    (gdb) set target-charset

    设置编码:

    (gdb) set charset UTF-8

    显示汇编

    layout asm

    显示汇编和源码

    layout split

    运行一个程序

    (gdb) run
    Starting program: /test/xmain

    栈追踪

    (gdb) backtrace
    No stack.
    (gdb) where
    No stack.
    (gdb) bt
    No stack.

    检查变量

    (gdb) print $1
    $2 = 0

    (gdb) print array[1]
    $4 = {data = 0x400a9a "neil", key = 4}

    GDB将命令的结果保存在伪变量$<number>中,最后一次操作的结果总是$,倒数第二次的结果为$$

    (gdb) print array[0]@5  //@<number> 打印number个数组元素
    $5 = {{data = 0x400a95 "bill", key = 3}, {data = 0x400a9a "neil", key = 4}, {
    data = 0x400a9f "john", key = 2}, {data = 0x400aa4 "rick", key = 5}, {
    data = 0x400aa9 "alex", key = 1}}

    列出程序源码

    (gdb) list
    37 {"rick", 5},
    38 {"alex",1}
    39 };

    (gdb) cont
    Continuing.

    Breakpoint 1, BubbleSort (dat=0x601080 <array>, n=5) at main.cpp:21
    21 item t = dat[j];


    40
    41
    42 int main()
    43 {
    44 //int len = sizeof(array);
    45 //cout << len << endl;
    46 BubbleSort(array, 5);

    会打印出围绕当前位置前后的一段代码,如果继续使用list,将显示更多的代码。

    也可以给list提供一个行号或函数名作为参数

    eg。

    (gdb) list BubbleSort
    6 const char *data;
    7 int key;
    8 }item;
    9
    10 void BubbleSort(item *dat, int n)
    11 {
    12 bool flag = true;
    13 int i=0;
    14 while(flag)
    15 {

    设置断点

    (gdb) help breakpoint
    Making program stop at certain points.

    List of commands:

    awatch -- Set a watchpoint for an expression
    break -- Set breakpoint at specified line or function
    break-range -- Set a breakpoint for an address range
    catch -- Set catchpoints to catch events
    catch assert -- Catch failed Ada assertions
    catch catch -- Catch an exception
    catch exception -- Catch Ada exceptions
    catch exec -- Catch calls to exec
    catch fork -- Catch calls to fork
    catch load -- Catch loads of shared libraries
    catch rethrow -- Catch an exception
    catch signal -- Catch signals by their names and/or numbers
    catch syscall -- Catch system calls by their names and/or numbers
    catch throw -- Catch an exception
    catch unload -- Catch unloads of shared libraries
    catch vfork -- Catch calls to vfork
    clear -- Clear breakpoint at specified line or function
    commands -- Set commands to be executed when a breakpoint is hit
    condition -- Specify breakpoint number N to break only if COND is true
    ---Type <return> to continue, or q <return> to quit---

    (gdb) break 21
    Breakpoint 1 at 0x400894: file main.cpp, line 21.
    (gdb) run
    Starting program:/xmain
    warning: File "/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".

    Breakpoint 1, BubbleSort (dat=0x601080 <array>, n=5) at main.cpp:21
    21 item t = dat[j];

    (gdb) cont
    Continuing.

    Breakpoint 1, BubbleSort (dat=0x601080 <array>, n=5) at main.cpp:21
    21 item t = dat[j];

    display在每次程序停在断点处时自动显示数组的内容

    (gdb) display array[0]@5
    1: array[0]@5 = {{data = 0x400a95 "bill", key = 3}, {data = 0x400a9f "john",
    key = 2}, {data = 0x400a9a "neil", key = 4}, {data = 0x400aa4 "rick",
    key = 5}, {data = 0x400aa9 "alex", key = 1}}

    也可以修改断点设置,使程序不是在断点处停下来,而只是显示要查看的数据,然后继续执行。

    (gdb) commands
    Type commands for breakpoint(s) 1, one per line.
    End with a line saying just "end".
    >cont
    >end
    //(gdb)
    (gdb) cont
    Continuing.

    Breakpoint 1, BubbleSort (dat=0x601080 <array>, n=5) at main.cpp:21
    21 item t = dat[j];
    1: array[0]@5 = {{data = 0x400a9f "john", key = 2}, {data = 0x400a95 "bill",
    key = 3}, {data = 0x400a9a "neil", key = 4}, {data = 0x400aa9 "alex",
    key = 1}, {data = 0x400aa4 "rick", key = 5}}

    Breakpoint 1, BubbleSort (dat=0x601080 <array>, n=5) at main.cpp:21
    21 item t = dat[j];
    1: array[0]@5 = {{data = 0x400a9f "john", key = 2}, {data = 0x400a95 "bill",
    key = 3}, {data = 0x400aa9 "alex", key = 1}, {data = 0x400a9a "neil",
    key = 4}, {data = 0x400aa4 "rick", key = 5}}

    Breakpoint 1, BubbleSort (dat=0x601080 <array>, n=5) at main.cpp:21
    21 item t = dat[j];
    1: array[0]@5 = {{data = 0x400a9f "john", key = 2}, {data = 0x400aa9 "alex",
    key = 1}, {data = 0x400a95 "bill", key = 3}, {data = 0x400a9a "neil",
    key = 4}, {data = 0x400aa4 "rick", key = 5}}
    1
    2
    3
    4
    5
    [Inferior 1 (process 13323) exited normally]

    用调试器打补丁

    info显示设置的断点及displa

    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    1: y array[0]@5
    (gdb) inf
    inferior info
    (gdb) info break
    Num Type Disp Enb Address What
    1 breakpoint keep y 0x0000000000400894 in BubbleSort(item*, int)
    at main.cpp:21
    breakpoint already hit 6 times
    cont

    (gdb) break 23
    Breakpoint 2 at 0x4008ef: file main.cpp, line 23.
    (gdb) commands 2
    Type commands for breakpoint(s) 2, one per line.
    End with a line saying just "end".
    >set variable n = n +1
    >cont
    >end
    (gdb) run
    Starting program:/xmain

    Breakpoint 2, BubbleSort (dat=0x601080 <array>, n=5) at main.cpp:23
    23 dat[j+1] = t;

    Breakpoint 2, BubbleSort (dat=0x601080 <array>, n=6) at main.cpp:23
    23 dat[j+1] = t;

    Breakpoint 2, BubbleSort (dat=0x601080 <array>, n=7) at main.cpp:23
    23 dat[j+1] = t;

    Breakpoint 2, BubbleSort (dat=0x601080 <array>, n=8) at main.cpp:23
    23 dat[j+1] = t;

    Breakpoint 2, BubbleSort (dat=0x601080 <array>, n=9) at main.cpp:23
    23 dat[j+1] = t;

    Breakpoint 2, BubbleSort (dat=0x601080 <array>, n=10) at main.cpp:23
    23 dat[j+1] = t;

    Breakpoint 2, BubbleSort (dat=0x601080 <array>, n=11) at main.cpp:23
    23 dat[j+1] = t;

    lint:清理程序中的垃圾

    splint:http://www.splint.org

    断言

    assert.h

    void assert(int expression);

    如果在处理某个头文件时已经定义了NDEBUG,就不定义assert宏。在编译期间使用-DNDEBUG关闭断言,或者把#define NDEBUG发到每个#include <assert.h>之前。

    $ gcc -g main.cpp -lefence -o xmain

     

  • 相关阅读:
    Bate版本控制报告
    【探路者】第五周立会报告6(总第32次)
    【探路者】第五周立会报告5(总第31次)
    【探路者】第五周立会报告4(总第30次)
    【探路者】第五周立会报告3(总第29次)
    【探路者】第五周立会报告2(总第28次)
    例行报告
    【探路者】第五周立会报告1(总第27次)
    【探路者】第四周立会报告7(总第26次)
    “Hello world!”团队第三周贡献分规则
  • 原文地址:https://www.cnblogs.com/guxuanqing/p/4888964.html
Copyright © 2020-2023  润新知