linux gdb attach在线调试

进入调试:
ps命令查看进程id。 
执行gdb attach pid即可调试正在运行的程序。 
info proc显示当前程序可执行文件相关信息(name,pwd)

断点相关:
b pkt.c:22(在pkt.c文件的22行打断点) 
b eth_rcv (在函数eth_rcv入口打断点) 
info b;显示当前所有断点; 
d num;删除断点num; 
n num;向后执行num步

bt显示当前函数的调用过程;

打印变量值:
p temp;默认十进制打印 
p /x temp;按十六进制打印 
x 按十六进制格式显示变量。 
d 按十进制格式显示变量。 
u 按十六进制格式显示无符号整型。 
o 按八进制格式显示变量。 
t 按二进制格式显示变量。 
a 按十六进制格式显示变量。 
c 按字符格式显示变量。 
f 按浮点数格式显示变量。 
显示变量类型:whatis var;显示var变量的类型 
显示变量的结构体成员: ptype var ;显示var类型结构体的成员

gdb中的变量:
程序的变量和gdb的变量是可以交互的,gdb中的变量以开头,如开头,如i。

set $i=0
print a[$i++]
1
2
即可实现打印以a地址起始的内存中的值。

条件进入断点:
如:b arp_rcv if index = 1234(当index=1234时进入断点,注意是单等号)

查看内存:
x /x 以十六进制输出 
x /d 以十进制输出 
x /c 以单字符输出 
x /i 反汇编 – 通常,我们会使用 x/10i ip−20来查看当前的汇编(ip−20来查看当前的汇编(ip是指令寄存器) 
x /s 以字符串输出

打印指定内存起始100字节内容: 
x /100ua pkt->data

设置临时变量:
set i=msg−>msgdataprinti=msg−>msgdataprinti打印变量msg->msg_data指针; 
ptype $i 打印msg->msg_data类型

command命令:
自动化调试,把一组gdb的命令打包。执行到断点处时自动执行一系列命令。 
如:

(gdb) b ftm_pkt_rcv_from_app
Breakpoint 1 at 0x191a8: file ftm_pkt.c, line 204.
(gdb) command 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>p /x pmesg
>p /x pmesg->msg_data
>
>end
(gdb) c
Continuing.

Breakpoint 1, ftm_pkt_rcv_from_app (pmesg=pmesg@entry=0x45b2c) at ftm_pkt.c:204
204     ftm_pkt.c: No such file or directory.
$1 = 0x45b2c
$2 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, 0x59, 0x6d, 0x38, 0x9c, 0x74, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x12, 0x0, 0x0, 0x0,
  0x0, 0x0, 0x10, 0x0, 0x12, 0x0, 0x0, 0x47, 0x1, 0x3d, 0x0, 0xa, 0x1, 0x0, 0x8, 0x4, 0x0, 0x1, 0x0, 0x0, 0x0, 0x64, 0x1e, 0x81, 0x1, 0x2, 0x3, 0x4c,
  0xcc, 0x6a, 0x70, 0xf4, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x45, 0x0 <repeats 71 times>, 0x68, 0x61, 0xa, 0x0, 0x76,
  0x61, 0xa, 0x0 <repeats 101 times>, 0x4c, 0xcc, 0x6a, 0x70, 0xf4, 0x17, 0x64, 0x1e, 0x81, 0x1, 0x2, 0x3, 0x8, 0x0, 0x45, 0x0, 0x0, 0x3d, 0x21, 0xd3,
  0x40, 0x0, 0x40, 0x6, 0x8, 0x76, 0xc0, 0xa8, 0xc7, 0x65, 0xc0, 0xa8, 0xc7, 0xbb, 0xa, 0x5a, 0x22, 0x43, 0x29, 0x29, 0xcd, 0x77, 0x80, 0x2b, 0x6b,
  0x57, 0x50, 0x18, 0x39, 0x8, 0xb5, 0x75, 0x0, 0x0, 0x47, 0x4e, 0x55, 0x20, 0x67, 0x64, 0x62, 0x20, 0x28, 0x47, 0x44, 0x42, 0x29, 0x20, 0x37, 0x2e,
  0x34, 0x2e, 0x31, 0xd, 0xa, 0x78, 0x0 <repeats 202 times>, 0x63, 0x82, 0x53, 0x63, 0x35, 0x1, 0x1, 0x3d, 0x7, 0x1, 0xd4, 0xee, 0x7, 0x27...}
(gdb)


调用函数:

(gdb) call func() 


如: 

(gdb) call printf(“hello world!\n”);

重定向标准输出stdout和stderr:
1)先关闭 stdout ,和 stderr 对应的文件描述符。 

(gdb) call (int)close(1) 
(gdb) call (int)close(2) 


2)然后使用以下命令查看一下当前 gdb 窗口所在的虚拟终端。 

(gdb) shell tty 
/dev/pts/0 


3)这时再重新打开 stdout 和 stderr , 把它们和 gdb 窗口所在的虚拟终端关联起来。 

(gdb) p (int)open(“/dev/pts/0”, 2) 
1=1(gdb)p(int)open(“/dev/pts/0”,2)1=1(gdb)p(int)open(“/dev/pts/0”,2)2 = 2 


如果这两个命令执行结果不是如上结果(1和2),意味着 open 执行失败,需要重新进行 close 和 open. 
4)接下来,重新执行如下命令: 
call printf(“helllo world\n”);即可直接在gdb调试窗口看到打印信息。 
5)即时刷新 stdout 和 stderr 
调用 fflush强制刷新缓冲区: 

(gdb)call (int)fflush(0)

另外,如果把这里的 ”/dev/pts/0” 替换成目标文件名,便可将 stderr 和 stdout 重定向到该文件。使用shell模式下的命令:

(gdb) define tar 
End with a line saying just “end”.

shell tar 
end

(gdb)tar 即可使用shell模式下tar命令,类比可得到其他命令。

以下未验证:
watch div1==div2当变量div1yu div2相等时进入中断。 
info thread 查看当前进程的线程。 
thread 切换调试的线程为指定ID的线程。 
break file.c:100 thread all 在file.c文件第100行处为所有经过这里的线程设置断点。 
set scheduler-locking off|on|step,这个是问得最多的。在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。 
off 不锁定任何线程,也就是所有线程都执行,这是默认值。 
on 只有当前被调试程序会执行。 
step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

发布了34 篇原创文章 · 获赞 14 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/acliyu/article/details/86620438