gdb

您所在的位置:网站首页 暴力破解过程视频大全集在线观看 gdb

gdb

2023-03-24 00:10| 来源: 网络整理| 查看: 265

1. 概述2. 启用 GDB 调试3. 退出 GDB4. 常用命令5. 常用命令示例5.1 run 命令5.2 continue 命令5.3 break 命令5.4 info break、enable、disable 和 delete 命令5.5 backtrace 和 frame 命令5.6 list 命令5.7 print 和 ptype 命令5.8 whatis 和 ptype 命令5.9 thread 命令5.10 next、step 命令5.11 return、finish 命令5.12 until 命令5.13 jump 命令5.14 disassemble 命令5.15 set args 和 show args 命令5.16 tbreak 命令5.17 watch 命令5.18 call 命令5.19 help 命令6. GDB 多线程调试6.1 概述6.2 一些命令6.3 一些术语6.4 设置线程锁7. 参考文档

1. 概述

GDB 全称 “GNU symbolic debugger”,从名称上不难看出,它诞生于 GNU 计划(同时诞生的还有 GCC、Emacs 等),是 Linux 下常用的程序调试器。发展至今,GDB 已经迭代了诸多个版本,当下的 GDB 支持调试多种编程语言编写的程序,包括 C、C++、Go、Objective-C、OpenCL、Ada 等。实际场景中,GDB 更常用来调试 C 和 C++ 程序。一般来说,GDB 主要帮助我们完成以下四个方面的功能:

启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。在某个指定的地方或条件下暂停程序。当程序被停住时,可以检查此时你的程序中所发生的事。在程序执行过程中修改程序中的变量或条件,将一个 bug 产生的影响修正从而测试其他 bug。

使用 GDB 调试程序,有以下两点需要注意:

要使用 GDB 调试某个程序,该程序编译时必须加上编译选项 -g,否则该程序是不包含调试信息的;GCC 编译器支持 -O 和 -g 一起参与编译。GCC 编译过程对进行优化的程度可分为 5 个等级,分别为 : -O/-O0: 不做任何优化,这是默认的编译选项 ;-O1:使用能减少目标文件大小以及执行时间并且不会使编译时间明显增加的优化。 该模式在编译大型程序的时候会花费更多的时间和内存。在 -O1 下:编译会尝试减少代 码体积和代码运行时间,但是并不执行会花费大量时间的优化操作。-O2:包含 -O1 的优化并增加了不需要在目标文件大小和执行速度上进行折衷的优化。 GCC 执行几乎所有支持的操作但不包括空间和速度之间权衡的优化,编译器不执行循环 展开以及函数内联。这是推荐的优化等级,除非你有特殊的需求。 -O2 会比 -O1 启用多 一些标记。与 -O1 比较该优化 -O2 将会花费更多的编译时间当然也会生成性能更好的代 码。-O3:打开所有 -O2 的优化选项并且增加 -finline-functions, -funswitch-loops,-fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize 优化选项。这是最高最危险 的优化等级。用这个选项会延长编译代码的时间,并且在使用 gcc4.x 的系统里不应全局 启用。自从 3.x 版本以来 gcc 的行为已经有了极大地改变。在 3.x,,-O3 生成的代码也只 是比 -O2 快一点点而已,而 gcc4.x 中还未必更快。用 -O3 来编译所有的 软件包将产生更 大体积更耗内存的二进制文件,大大增加编译失败的机会或不可预知的程序行为(包括 错误)。这样做将得不偿失,记住过犹不及。在 gcc 4.x. 中使用 -O3 是不推荐的。-Os:专门优化目标文件大小 , 执行所有的不增加目标文件大小的 -O2 优化选项。同时 -Os 还会执行更加优化程序空间的选项。这对于磁盘空间极其紧张或者 CPU 缓存较小的 机器非常有用。但也可能产生些许问题,因此软件树中的大部分 ebuild 都过滤掉这个等 级的优化。使用 -Os 是不推荐的。

2. 启用 GDB 调试

GDB 调试主要有三种方式:

直接调试目标程序:gdb ./hello_server附加进程 id:gdb attach pid调试 core 文件:gdb filename corename

3. 退出 GDB 可以用命令:q(quit 的缩写)或者 Ctr + d 退出 GDB。如果 GDB attach 某个进程,退出 GDB 之前要用命令 detach 解除附加进程。

4. 常用命令 命令名称 命令缩写 命令说明 run r 运行一个待调试的程序 continue c 让暂停的程序继续运行 next n 运行到下一行 step s 单步执行,遇到函数会进入 until u 运行到指定行停下来 finish fi 结束当前调用函数,回到上一层调用函数处 return return 结束当前调用函数并返回指定值,到上一层函数调用处 jump j 将当前程序执行流跳转到指定行或地址 print p 打印变量或寄存器值 backtrace bt 查看当前线程的调用堆栈 frame f 切换到当前调用线程的指定堆栈 thread thread 切换到指定线程 break b 添加断点 tbreak tb 添加临时断点 delete d 删除断点 enable enable 启用某个断点 disable disable 禁用某个断点 watch watch 监视某一个变量或内存地址的值是否发生变化 list l 显示源码 info i 查看断点 / 线程等信息 ptype ptype 查看变量类型 disassemble dis 查看汇编代码 set args set args 设置程序启动命令行参数 show args show args 查看设置的命令行参数

5. 常用命令示例

5.1 run 命令

默认情况下,以 gdb ./filename 方式启用 GDB 调试只是附加了一个调试文件,并没有启动这个程序,需要输入 run 命令(简写为 r)启动这个程序:

[root@localhost src]# gdb ./redis-serverGNU gdb (GDB) 8.0Copyright (C) 2017 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it....此处省略很多行...Type "apropos word" to search for commands related to "word"...Reading symbols from ./redis-server...done.(gdb) rStarting program: /data/redis-5.0.3/src/redis-server [Thread debugging using libthread_db enabled]...此处省略很多行...34628:M 09 Nov 2020 00:10:16.318 * DB loaded from disk: 0.000 seconds

以上是以 redis-server 程序为例,输入 r 后启动了 redis 服务器,在 GDB 界面按 Ctrl + C 让 GDB 中断下来,再次输入 r 命令,GDB 会询问是否重启程序,输入 y(或 yes):

34628:M 09 Nov 2020 00:10:16.318 * Ready to accept connections^CThread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /data/redis-5.0.3/src/redis-server [Thread debugging using libthread_db enabled]

退出 GDB,会提示用户要关闭当前调试进程,是否继续退出:

34636:M 09 Nov 2020 00:10:31.427 * Ready to accept connections^CThread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) qA debugging session is active. Inferior 1 [process 34636] will be killed.Quit anyway? (y or n) y[root@localhost src]#

5.2 continue 命令

当 GDB 触发断点或者使用 Ctrl + C 命令中断下来后,想让程序继续运行,只要输入 continue(简写为 c)命令即可。

34839:M 09 Nov 2020 00:37:56.364 * DB loaded from disk: 0.000 seconds34839:M 09 Nov 2020 00:37:56.364 * Ready to accept connections^CThread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) cContinuing.34839:M 09 Nov 2020 00:46:16.004 * 100 changes in 300 seconds. Saving...34839:M 09 Nov 2020 00:46:16.046 * Background saving started by pid 34887

5.3 break 命令

break 命令(简写为 b)用于添加断点,可以使用以下几种方式添加断点:

break FunctionName,在函数的入口处添加一个断点;break LineNo,在当前文件行号为LineNo处添加断点;break FileName:LineNo,在FileName文件行号为LineNo处添加一个断点;break FileName:FunctionName,在FileName文件的FunctionName函数的入口处添加断点;break -/+offset,在当前程序暂停位置的前 / 后 offset 行处下断点;

break … if cond,下条件断点;

分别举例介绍以上几种下断点方法:

在main函数入口处下断点: 35274:M 09 Nov 2020 01:46:16.910 * Ready to accept connections^CThread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) b mainBreakpoint 1 at 0x430890: file server.c, line 4003.(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /data/redis-5.0.3/src/redis-server [Thread debugging using libthread_db enabled]Using host libthread_db library "/lib64/libthread_db.so.1".Breakpoint 1, main (argc=1, argv=0x7fffffffe648) at server.c:40034003 int main(int argc, char **argv) {(gdb) 在当前文件的4041行下断点: (gdb) b 4041Breakpoint 2 at 0x4308bc: file server.c, line 4041.(gdb) info bNum Type Disp Enb Address What1 breakpoint keep y 0x0000000000430890 in main at server.c:4003 breakpoint already hit 1 time2 breakpoint keep y 0x00000000004308bc in main at server.c:4041(gdb) cContinuing.Breakpoint 2, main (argc=1, argv=0x7fffffffe648) at server.c:40414041 zmalloc_set_oom_handler(redisOutOfMemoryHandler);(gdb)

3. redis-server的默认端口是6379,绑定端口是需要调用bind函数,搜到该函数调用位置是在 anet.c 文件的 441 行:

在这里添加一个断点:

3208:M 09 Nov 2020 18:33:14.205 * DB loaded from disk: 0.000 seconds3208:M 09 Nov 2020 18:33:14.205 * Ready to accept connections^CThread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) b anet.c:441Breakpoint 1 at 0x429b72: file anet.c, line 441.(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /data/redis-5.0.3/src/redis-server [Thread debugging using libthread_db enabled]Using host libthread_db library "/lib64/libthread_db.so.1".3232:C 09 Nov 2020 18:38:18.129 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo3232:C 09 Nov 2020 18:38:18.129 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=3232, just started3232:C 09 Nov 2020 18:38:18.129 # Warning: no config file specified, using the default config. In order to specify a config file use /data/redis-5.0.3/src/redis-server /path/to/redis.conf3232:M 09 Nov 2020 18:38:18.129 * Increased maximum number of open files to 10032 (it was originally set to 4096).Breakpoint 1, anetListen (err=0x7b4320 "", s=6, sa=0x9c5ee0, len=28, backlog=511) at anet.c:441441 if (bind(s,sa,len) == -1) {(gdb) 也可以选择在某个文件的某个函数的入口处添加断点,以hset命令的回调函数为例: struct redisCommand redisCommandTable[] = { //此处省略之前的命令注册代码 {"hset",hsetCommand,-4,"wmF",0,NULL,1,1,1,0,0}, //此处省略之后的命令注册代码};

查到是 t_hash.c 文件的hsetCommand函数,在此处下断点:

3232:M 09 Nov 2020 18:40:49.044 * DB loaded from disk: 0.000 seconds3232:M 09 Nov 2020 18:40:49.044 * Ready to accept connections^CThread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) b t_hash.c:hsetCommandBreakpoint 2 at 0x45e870: file t_hash.c, line 530.(gdb) cContinuing.

然后通过 redis 客户端redis-cli连上redis-server,并输入一条hset命令:

[root@localhost ~]# redis-cli127.0.0.1:6379> hset maptest key1 value1(integer) 1(3.54s)

断点被触发:

Thread 1 "redis-server" hit Breakpoint 2, hsetCommand (c=0x7ffff7b0d0c0) at t_hash.c:530530 void hsetCommand(client *c) {(gdb) cContinuing.

5.4 info break、enable、disable 和 delete 命令

命令格式及作用:

info break,也可简写为 i b,作用是显示当前所有断点信息;disable 断点编号,禁用某个断点,使得断点不会被触发;enable 断点编号,启用某个被禁用的断点;delete 断点编号,删除某个断点。 (gdb) info bNum Type Disp Enb Address What1 breakpoint keep y 0x0000000000430890 in main at server.c:4003 breakpoint already hit 1 time2 breakpoint keep y 0x00000000004308bc in main at server.c:4041 breakpoint already hit 1 time3 breakpoint keep y 0x0000000000429b72 in anetListen at anet.c:441 breakpoint already hit 2 times4 breakpoint keep y 0x000000000045e870 in hsetCommand at t_hash.c:530(gdb) disable 4(gdb) info bNum Type Disp Enb Address What1 breakpoint keep y 0x0000000000430890 in main at server.c:4003 breakpoint already hit 1 time2 breakpoint keep y 0x00000000004308bc in main at server.c:4041 breakpoint already hit 1 time3 breakpoint keep y 0x0000000000429b72 in anetListen at anet.c:441 breakpoint already hit 2 times4 breakpoint keep n 0x000000000045e870 in hsetCommand at t_hash.c:530(gdb) enable 4(gdb) info bNum Type Disp Enb Address What1 breakpoint keep y 0x0000000000430890 in main at server.c:4003 breakpoint already hit 1 time2 breakpoint keep y 0x00000000004308bc in main at server.c:4041 breakpoint already hit 1 time3 breakpoint keep y 0x0000000000429b72 in anetListen at anet.c:441 breakpoint already hit 2 times4 breakpoint keep y 0x000000000045e870 in hsetCommand at t_hash.c:530(gdb) delete 3(gdb) info bNum Type Disp Enb Address What1 breakpoint keep y 0x0000000000430890 in main at server.c:4003 breakpoint already hit 1 time2 breakpoint keep y 0x00000000004308bc in main at server.c:4041 breakpoint already hit 1 time4 breakpoint keep y 0x000000000045e870 in hsetCommand at t_hash.c:530

断点信息中第四列 Enb,当断点启动时是 y,断点被禁用后是 n。

5.5 backtrace 和 frame 命令

命令格式及作用:

backtrace,也可简写为 bt,用于查看当前调用堆栈。frame 堆栈编号,也可简写为 f 堆栈编号,用于切换到其他堆栈处。 Thread 1 "redis-server" hit Breakpoint 4, hsetCommand (c=0x7ffff7b0d0c0) at t_hash.c:530530 void hsetCommand(client *c) {(gdb) bt#0 hsetCommand (c=0x7ffff7b0d0c0) at t_hash.c:530#1 0x000000000042d320 in call (c=0x7ffff7b0d0c0, flags=15) at server.c:2437#2 0x000000000043168d in processCommand (c=0x7ffff7b0d0c0) at server.c:2729#3 0x000000000043e7af in processInputBuffer (c=0x7ffff7b0d0c0) at networking.c:1446#4 0x00000000004288d3 in aeProcessEvents (eventLoop=0x7ffff7a300a0, flags=11) at ae.c:443#5 0x0000000000428bfb in aeMain (eventLoop=0x7ffff7a300a0) at ae.c:501#6 0x0000000000430d9e in main (argc=, argv=0x7fffffffe648) at server.c:4197(gdb) f 1#1 0x000000000042d320 in call (c=0x7ffff7b0d0c0, flags=15) at server.c:24372437 c->cmd->proc(c);(gdb) f 2#2 0x000000000043168d in processCommand (c=0x7ffff7b0d0c0) at server.c:27292729 call(c,CMD_CALL_FULL);(gdb) f 3#3 0x000000000043e7af in processInputBuffer (c=0x7ffff7b0d0c0) at networking.c:14461446 if (processCommand(c) == C_OK) {(gdb) f 4#4 0x00000000004288d3 in aeProcessEvents (eventLoop=0x7ffff7a300a0, flags=11) at ae.c:443443 fe->rfileProc(eventLoop,fd,fe->clientData,mask);(gdb) f 5#5 0x0000000000428bfb in aeMain (eventLoop=0x7ffff7a300a0) at ae.c:501501 aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);(gdb) f 6#6 0x0000000000430d9e in main (argc=, argv=0x7fffffffe648) at server.c:41974197 aeMain(server.el);(gdb) cContinuing.

5.6 list 命令

命令格式及作用:

list,输出上一次 list 命令显示的代码后面的代码,如果是第一次执行 list 命令,则会显示当前正在执行代码位置附近的代码;list -,带一个减号,显示上一次 list 命令显示的代码前面的代码;list LineNo,显示当前代码文件第 LineNo 行附近的代码;list FileName:LineNo,显示 FileName 文件第 LineNo 行附近的代码;list FunctionName,显示当前文件的 FunctionName 函数附近的代码;list FileName:FunctionName,显示 FileName 文件的 FunctionName 函数附件的代码;list from,to,其中from和to是具体的代码位置,显示这之间的代码;

list命令默认只会输出 10 行源代码,也可以使用如下命令修改:

show listsize,查看 list 命令显示的代码行数;set listsize count,设置 list 命令显示的代码行数为 count;

5.7 print 和 ptype 命令

命令格式及作用:

print param,用于在调试过程中查看变量的值;print param=value,用于在调试过程中修改变量的值;print a+b+c,可以进行一定的表达式计算,这里是计算 a、b、c 三个变量之和;print func(),输出func函数执行的结果,常见的用途是打印系统函数执行失败原因:print strerror(errno);print *this,在 c++ 对象中,可以输出当前对象的各成员变量的值; 8099:M 10 Nov 2020 04:06:23.436 * DB loaded from disk: 0.000 seconds8099:M 10 Nov 2020 04:06:23.436 * Ready to accept connections^CThread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) b listenToPortBreakpoint 1 at 0x42fa20: file server.c, line 1913.(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /data/redis-5.0.3/src/redis-server [Thread debugging using libthread_db enabled]Using host libthread_db library "/lib64/libthread_db.so.1".8107:C 10 Nov 2020 04:06:32.413 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo8107:C 10 Nov 2020 04:06:32.413 # Redis version=5.0.3, bits=64, commit=00000000, modified=0, pid=8107, just started8107:C 10 Nov 2020 04:06:32.413 # Warning: no config file specified, using the default config. In order to specify a config file use /data/redis-5.0.3/src/redis-server /path/to/redis.conf8107:M 10 Nov 2020 04:06:32.414 * Increased maximum number of open files to 10032 (it was originally set to 4096).Breakpoint 1, listenToPort (port=6379, fds=0x7b424c , count=0x7b428c ) at server.c:19131913 int listenToPort(int port, int *fds, int *count) {(gdb) p port$1 = 6379(gdb) p port=6378$2 = 6378(gdb) cContinuing.

如上所示,在listenToPort函数入口处下断点,输入 r,redis-server 重启时触发断点,打印得到 port 的值为 6379,再通过 **p port=6378** 将监听的端口改成 6378,redis-server 启动后查询端口监听情况:

[root@localhost ~]# netstat -apn | grep redis-servertcp 0 0 0.0.0.0:6378 0.0.0.0:* LISTEN 8131/redis-server * tcp 0 0 :::6378 :::* LISTEN 8131/redis-server * [root@localhost ~]#

5.8 whatis 和 ptype 命令

命令格式及功能:

whatis val,用于查看变量类型;ptype val,作用和 whatis 类似,但功能更强大,可以查看复合数据类型,会打印出该类型的成员变量。

5.9 thread 命令

命令格式及作用:

info thread,查看当前进程的所有线程运行情况;thread 线程编号,切换到具体编号的线程上去; 14139:M 10 Nov 2020 22:55:24.849 * DB loaded from disk: 0.000 seconds14139:M 10 Nov 2020 22:55:24.849 * Ready to accept connections^CThread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) info thread Id Target Id Frame * 1 Thread 0x7ffff7feaf40 (LWP 14139) "redis-server" 0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6 2 Thread 0x7ffff176a700 (LWP 14140) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 3 Thread 0x7fffeef69700 (LWP 14141) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 4 Thread 0x7fffec768700 (LWP 14142) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0(gdb) thread 3[Switching to thread 3 (Thread 0x7fffeef69700 (LWP 14141))]#0 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0(gdb) info thread Id Target Id Frame 1 Thread 0x7ffff7feaf40 (LWP 14139) "redis-server" 0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6 2 Thread 0x7ffff176a700 (LWP 14140) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0* 3 Thread 0x7fffeef69700 (LWP 14141) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 4 Thread 0x7fffec768700 (LWP 14142) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0(gdb) cContinuing.

从以上可以看出,前面带 号的是当前所在线程,第一列 Id 指的是线程编号,后面括号中 LWP 14139,LWP(Light Weight Process)表示轻量级进程,即我们所说的线程,线程 ID 为 *14139。

目前通过 info thread 可知 redis-server 一共启动了 4 个线程,其中 1 个主线程,3 个工作线程,通过 bt 命令可知线程 1 是主线程,因为其调用堆栈最顶层是 main 函数。

Thread 1 "redis-server" received signal SIGINT, Interrupt.0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6(gdb) info thread Id Target Id Frame * 1 Thread 0x7ffff7feaf40 (LWP 14139) "redis-server" 0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6 2 Thread 0x7ffff176a700 (LWP 14140) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 3 Thread 0x7fffeef69700 (LWP 14141) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 4 Thread 0x7fffec768700 (LWP 14142) "redis-server" 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0(gdb) bt#0 0x00000038212e9243 in epoll_wait () from /lib64/libc.so.6#1 0x000000000042875e in aeApiPoll (tvp=, eventLoop=0x7ffff7a300a0) at ae_epoll.c:112#2 aeProcessEvents (eventLoop=0x7ffff7a300a0, flags=11) at ae.c:411#3 0x0000000000428bfb in aeMain (eventLoop=0x7ffff7a300a0) at ae.c:501#4 0x0000000000430d9e in main (argc=, argv=0x7fffffffe648) at server.c:4197(gdb) thread 2[Switching to thread 2 (Thread 0x7ffff176a700 (LWP 14140))]#0 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0(gdb) bt#0 0x000000382160b68c in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0#1 0x0000000000483346 in bioProcessBackgroundJobs (arg=0x0) at bio.c:176#2 0x0000003821607aa1 in start_thread () from /lib64/libpthread.so.0#3 0x00000038212e8c4d in clone () from /lib64/libc.so.6(gdb) cContinuing.

5.10 next、step 命令

next 和 step 都是单步执行,但也有差别:

next 是 单步步过(step over),即遇到函数直接跳过,不进入函数内部。step 是 单步步入(step into),即遇到函数会进入函数内部。

5.11 return、finish 命令

return 和 finish 都是退出函数,但也有差别:

return 命令是立即退出当前函数,剩下的代码不会执行了,return 还可以指定函数的返回值。finish 命令是会继续执行完该函数剩余代码再正常退出。

5.12 until 命令

以下是 GDB 对 until 命令的解释:

(gdb) help until Execute until the program reaches a source line greater than the current or a specified location (same args as break command) within the current frame.

该命令使得程序执行到指定位置停下来,命令参数和 break 命令一样。

5.13 jump 命令

命令格式及作用:

jump LineNo,跳转到代码的 LineNo 行的位置;jump +10,跳转到距离当前代码下 10 行的位置;

jump *0x12345678,跳转到 0x12345678 地址的代码处,地址前要加星号;

jump 命令有两点需要注意的:

中间跳过的代码是不会执行的;跳到的位置后如果没有断点,那么 GDB 会自动继续往后执行; #include using std::cout;using std::endl;int main() { int a = 0; cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3