gdb调试1--包括反汇编及文件编码设置
一。编译
获取预编译宏:gcc -E -dM -</dev/nullgcc的完整编译过程大致为:预处理->编译->汇编->链接
前三个步骤分别对应了-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