linux gdb core 内存,[Linux]GDB调试技巧

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

命令行参数

gdb有下面几种运行方式:1

2

3

4

5

6gdb [options] [executable-file [core-file or process-id]]

// 2. 带参数运行程序

gdb [options] --args executable-file [inferior-arguments ...]

// 3. redhat等含有用于调试python的工具

// gdb [options] [--python|-P] script-file [script-arguments ...]

几个值得注意的参数:1

2

3

4

5

6

7

8

9

10

11

12

13

14// 和上面的类似,使用参数指定的

--args Arguments after executable-file are passed to inferior

--core=COREFILE Analyze the core dump COREFILE.

--pid=PID Attach to running process PID.

--exec=EXECFILE Use EXECFILE as the executable.

// 远程调试

-b BAUDRATE Set serial port baud rate used for remote debugging.

-l TIMEOUT Set timeout in seconds for remote debugging.

// 运行某个文件中的gdb指令

--command=FILE, -x Execute GDB commands from FILE.

// 运行某gdb指令,如gdb a.out -ex r开启文件并立即运行

--eval-command=COMMAND, -ex Execute a single GDB command.

--directory=DIR Search for source files in DIR.

--se=FILE Use FILE as symbol file and executable file.

简单的例子:coredump分析

gdb的一大用处是通过coredump文件分析程序哪里发生了错误。首先要打开coredump生成开关:1

2

3

4// 可以先运行 ulimit -a 查看所有限制,或者运行 ulimit -c 查看当前coredump设置

// 设置成无限可能会生成数GB的coredump文件

// 这条命令重启后无效

ulimit -c unlimited

coredump文件会默认生成在程序相同目录下。如果没有对应文件,可以查看/etc/sysctl.conf:1

2

3

4// 生成目录格式,%e 程序名 %p 进程id %s 信号 %t 时间 %e 命令名

kernel.core_pattern =/data/coredump/core%e%p

// 1表示使用procid命名,0表示不使用

kernel.core_uses_pid= 0

我们先编写一个简单的c程序main.c,它试图从非法地址读取数据:1

2

3

4int (){

int a = *((int *)NULL);

return 0;

}

编译,一定要加上-g选项:1gcc -o test_worker main.c -g

运行,果然dump:1

2./test_worker

Segmentation fault (core dumped)

然后使用第一节里的第一种方式启动, 携带coredump文件:1gdb ./test_worker core.xxx.xxx

进去后就能看到dump的地方以及原因。使用bt查看coredump时栈顶的信息:1

2

3

4

5

6

7Core was generated by `./t'.

Program terminated with signal 11, Segmentation fault.

#0 0x0000000000400564 in main () at t.c:13

13 int a = *((int *)NULL);

Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.4.x86_64

(gdb) bt

#0 0x0000000000400564 in main () at t.c:13

GDB的用法

GDB启动时会读取二进制文件的符号表,然后进入调试命令行。这里可以运行各种命令查看程序的符号表、变量、内存值以及控制程序的运行。

控制命令file 加载一个二进制文件,直接进入gdb时可以用这个加载。参数为文件名。

run (或者r) 从头运行程序一直到断点。没有断点会一直运行结束,或者直到遇到异常。可以r < a.in 重定向输入输出。

continue (或者c) 运行程序一直到下一个断点。

next/step (或者n/s) 单步调试,next不会在行内进入函数体,step则会跳入函数体。 参数为跳多行。

until (或者 u) 直接跳出当前循环。(但是还是会被断点卡住)。参数为跳到指定行。

finish 直接运行到函数返回

call 运行某函数,参数为函数和参数,如 call foo(2, "hello")

回车键 重复上个指令

断点break n (或者b) 在第n行打断点

b main.c:n 指定文件打断点; b main 指定函数入口处打断点; b main:label 指定函数的标签处打断点

b n if i == 5 满足条件打断点,对循环尤其有效。

info b 查看断点号和信息,或者 i b

delete no (或者d) 删除对应编号的断点; d breakpoints 删除所有断点

clear lineno 删除对应行的断点

disable/enable no 屏蔽/使用对应编号的断点

查看代码和变量list (或者l) 列出10行源文件。每次从上次结束的地方开始列。

list lineno 列出某行的前后源码;l main 列出某函数的源码

print exp (或者p) 打印任意变量、表达式、函数、字符串、数组的值

display exp 每次单步完打印该表达式

watch exp 如果该表达式值改变了,打印并停止程序

whatis 查询变量,函数的类型

info (或者i) 查询信息 i locals 所有变量的值 i args 所有参数的值 i function 函数信息 i frame 栈信息

i program 程序信息 i threads 线程信息

堆栈bt 查看栈信息; bt n 栈顶n层;bt -n 栈底n层1

2

3(gdb) bt

#0 foot () at t.c:7

#1 0x0000000000400525 in main () at t.c:15

frame (或者f)查看帧信息。上面一个#号(一层)是一帧。

frame n 查看第n帧 ;up n 上面n帧; down n 下面n帧;frame addr 查看某地址的帧

info frame n/addr 帧详细信息

ip是下条命令的地址(pc),bp是栈底的地址,sp是栈顶的地址。

64位机的帧信息:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15(gdb) i f 0

// 帧地址

Stack frame at 0x7fffffffe560:

// rip:帧PC 帧函数名 saved rip:caller帧PC

rip = 0x4004fd in foot (t.c:7); saved rip 0x400525

// caller帧地址

called by frame at 0x7fffffffe570

source language c.

// 帧参数地址

Arglist at 0x7fffffffe550, args:

// 帧局部变量地址,caller的栈顶地址

Locals at 0x7fffffffe550, Previous frame sp is 0x7fffffffe560

// 帧寄存器列表

Saved registers:

rbp at 0x7fffffffe550, rip at 0x7fffffffe558

32位机的帧信息:1

2

3

4

5

6

7

8

9

10

11

12(gdb) i f

Stack level 0, frame at 0xbffff630:

// eip:帧PC 帧函数名 saved eip:caller帧PC

eip = 0x80483e4 in main (a.c:8); saved eip = 0xb7e31637

source language c.

// 帧参数地址

Arglist at 0xbffff628, args:

// 帧局部变量地址,caller的栈顶地址

Locals at 0xbffff628, Previous frame sp is 0xbffff630

// 帧寄存器列表

Saved registers:

ebp at 0xbffff628, eip at 0xbffff62c

内存

gdb中使用x命令来打印内存的值,格式为x/nfu addr。

含义为以f格式打印从addr开始的n个长度单元为u的内存值。参数具体含义如下:

a)n:输出单元的个数。

b)f:是输出格式。比如x是以16进制形式输出,o是以8进制形式输出,等等。

c)u:标明一个单元的长度。b是一个bytes,h是两个bytes(halfword),w是四个bytes(word),g是八个bytes(giant word)。

比如对一个字符串arr查看内存:(这个数组越界踩掉了总共10 char的内容,每个char在32位机上是32bit)1

2

3

4

5

6

7

8

9(gdb) p arr

$4 = "

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值