gnu gdb

举报
黄生 发表于 2022/11/22 23:19:01 2022/11/22
【摘要】 如果编译时没有-g参数,则不能实现基于C源码的符号调试功能,看不到程序的函数名、变量名,显示的全是运行时的内存地址。strip - Discard symbols from object files.如果一个目标被strip了的话,在去dbg他,就不好了一些命令执行会抱怨没有符号表。Reading symbols from /root/pgm…(no debugging symbols fo...

如果编译时没有-g参数,则不能实现基于C源码的符号调试功能,
看不到程序的函数名、变量名,显示的全是运行时的内存地址。

strip - Discard symbols from object files.
如果一个目标被strip了的话,在去dbg他,就不好了
一些gdb命令执行会抱怨没有符号表。
Reading symbols from /root/pgm...(no debugging symbols found)...done.
(gdb) b 20
No symbol table is loaded.  Use the "file" command.

即使带了-g,没有strip,源码文件是需要在位的,否则
Reading symbols from /root/td...done.
(gdb) l
15      td.c: No such file or directory.

条件满足时,我们来dbg它。l看一下代码

22      int main (int argc, char **argv) {
23          char buf[BS], clear[BS];
24          struct ip *iph = (struct ip *) buf;

然后b main设置断点 再run起来

(gdb) b main
Breakpoint 1 at 0x409ad7: file td.c, line 24.
(gdb) r
Starting program: /root/td

Breakpoint 1, main (argc=1, argv=0x7fffffffe5b8) at td.c:24
24          struct ip *iph = (struct ip *) buf;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-317.el7.x86_64

//然后再打一个断点,想继续运行到断点,但是却退出了。因为中间执行了fork
(gdb) b 65
Breakpoint 2 at 0x409c07: file td.c, line 65.
(gdb) c
Continuing.
[Detaching after fork from child process 2615]
[Inferior 1 (process 2604) exited normally]

//没关系,可以再attach上去子进程2615
//也可以再开始时就设置跟踪子进程 set follow-fork-mode child

(gdb) set follow-fork-mode child
(gdb) b 65
Breakpoint 2 at 0x409c07: file td.c, line 65.
(gdb) c
Continuing.
[Attaching after process 3687 fork to child process 3687]
[New inferior 2 (process 3687)]
[Detaching after fork from parent process 3682]
[Inferior 1 (process 3682) detached]
[Switching to process 3687]

Breakpoint 2, main (argc=1, argv=0x7fffffffe5a8) at td.c:65
65              FD_ZERO (&rfds);

有些程序是要带参数启动的,要这样使用-args参数来说明,如果不用,gdb把后面也看做要调试的程序
gdb -args ./mypgm -h xx -p yy

//看变量值的时候,可以指定想要的格式,比如p/c opt
(gdb) p opt
$2 = 104
(gdb) p/x opt
$4 = 0x68
(gdb) p /c opt
$5 = 104 'h'

/*可以执行一个shell命令,如 shell date
都是单步调试,二者区别;s 是step into 的意思;n 是 step over

变量的类型是什么?*/
(gdb) whatis opt
type = int

//修改变量的值。使用set var更好一下,可避免变量名和gdb自己的参数重名导致的意外情况
(gdb) print opt='h'
$4 = 104
(gdb) set var opt='h'

/*当ip是一个指针char *时,怎么查看;直接查看是没有问题的,但是当加上一些格式后,就要注意客体
涉及展示长度的选项 show print elements*/
(gdb) p /c ip
$12 = 240 '\360'
(gdb) p /x ip
$13 = 0x7fffffffe7f0
(gdb) whatis ip
type = char *
(gdb) p ip
$14 = 0x7fffffffe7f0 "h1"
(gdb) p/c *ip
$16 = 104 'h'

//不想在这个函数里纠缠了,继续执行完函数
(gdb) finish
Run till exit from #0  isip (ip=0x7fffffffe7f0 "h1") at ip.c:40
0x0000000000407a6e in resolve (host=0x7fffffffe7f0 "h1") at ip.c:20
20          if (isip (host))
Value returned is $17 = 1

//查看结构体
(gdb) p udh
$1 = (struct udp *) 0x7fffffffa3a4
(gdb) p *udh
$2 = {src = 8693, dst = 11631, len = 0, sum = 42922}
(gdb) set print pretty on
(gdb) p *udh
$3 = {
  src = 8693,
  dst = 11631,
  len = 0,
  sum = 42922
}
(gdb) ptype udh
type = struct udp {
    u16 src;
    u16 dst;
    u16 len;
    u16 sum;
} *

//看某变量或类型的大小
(gdb) p sizeof(unsigned long)
$19 = 8

一些其他的
info b/th (break thread)
bt 函数调用栈,当前在哪里
help 层层递进的帮助
记得开头不记得后续,或不想打时用TAB键
info locals 看本地变量,全部的

其他的其他
输入h1,用sscanf解析输入(预期点分数字的IP形式),然后判断输入是否为IP(错误的变成了0.0.0.0);
如果是IP,用inet_addr()来转换成binary data in network byte order(这个函数本就有缺陷,返回-1也是0xffffffff)
最终将h1错误的变成255.255.255.255

一个疑问,.h文件修改了,make没有检测到变化,因此没有进行重新编译

if (select (usock + 1, &rfds, NULL, NULL, NULL) < 1)1个参数 nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

fd_set *readfds, fd_set *writefds, fd_set *exceptfds
Three independent sets of file descriptors are watched. 不要watch的就设置NULL

if (FD_ISSET (tsock, &rfds))

FD_ZERO()  clears  a  set.
FD_SET() and FD_CLR() respectively add and remove a given file descriptor from a set.
FD_ISSET() tests to see if a file descriptor is part of the set; this is useful after select() returns.
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。