root@TDMP:~# gdb /bin/hello GNU gdb (GDB) 8.3.1 Copyright (C) 2019 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "arm-brcm-linux-gnueabi". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>.
For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from /bin/hello...
(gdb) set detach-on-fork off # 设置 gdb 在 fork 之后继续保留控制这两个进程
(gdb) r # 等效于 run 命令,开始运行 Starting program: /bin/hello [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/libthread_db.so.1". [New inferior 2 (process 5488)] [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/libthread_db.so.1". [Inferior 1 (process 5485) exited normally]
(gdb) info inferiors # 显示所有进程 Num Description Executable * 1 <null> /bin/hello 2 process 5488 /bin/hello
(gdb) inferior 2 # 切换到进程2 [Switching to inferior 2 [process 5488] (/bin/hello)] [Switching to thread 2.1 (process 5488)] Reading symbols from /bin/hello... Reading symbols from /usr/lib/libjson.so.0... Reading symbols from /lib/libpthread.so.0... Reading symbols from /lib/libsecurity.so... Reading symbols from /usr/lib/libcyassl.so.5... Reading symbols from /usr/lib/libz.so.1... Reading symbols from /lib/libbcm_flashutil.so... Reading symbols from /lib/libbcm_boardctl.so... Reading symbols from /lib/libbcm_util.so... Reading symbols from /lib/libgen_util.so... Reading symbols from /lib/libsys_util.so... Reading symbols from /lib/libethswctl.so... Reading symbols from /lib/libc.so.6... Reading symbols from /lib/ld-linux.so.3... Reading symbols from /lib/libm.so.6... #0 0xf75ae2c8 in fork () from /lib/libc.so.6
(gdb) b wacAddWhitelist # 等效于 break wacAddWhitelist, 在 wacAddWhitelist 函数开头打断点 Breakpoint 1 at 0x2311c4: wacAddWhitelist. (2 locations)
(gdb) c Continuing. [New Thread 0xf73c3460 (LWP 22[ 487.008626] gpio 17 request failed. 14)] [New Th[ 487.013850] gpio 10 request failed. ...... 60 (LWP 2215)] [New Thread 0xf63c3460 (LWP 2216)] ...... [New Thread 0xf5bc3460 (LWP 2217)] ...... Can not resume the parent process over vfork in the foreground while holding the child stopped. Try "set detach-on-fork" or "set schedule-multiple".
(gdb) bt # 等效于 backtrace,打印栈回溯信息,可知在 vfork 处暂停 #0 0xf75ae560 in vfork () from /lib/libc.so.6 #1 0x0029ab14 in doSystemExec (cmdline=0x33bf84 "insmod slp_gpio.ko", sync=1) at systemOps.c:83 #2 0x0029ad50 in systemExec (cmdline=0x33bf84 "insmod slp_gpio.ko") at systemOps.c:142 #3 0x002917b4 in gpioInit () at gpio.c:215 #4 0x002db7c8 in __libc_csu_init () #5 0xf7528b08 in __libc_start_main () from /lib/libc.so.6 #6 0x0003f2e4 in _start () Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) set detach-on-fork on # 子进程(或者父进程,依赖于 follow-fork-mode 的值)会 detach 然后独立运行
(gdb) c # 继续运行直到在 wacAddWhitelist 入口处暂停 Continuing. ...... [Detaching after vfork from child process 4737]
Thread 2.1 "hello" hit Breakpoint 2, wacAddWhitelist (item=0xfffefad8) at wlanAC.c:98 98 wlanAC.c: No such file or directory.
(gdb) bt ## 栈回溯显示确实是在 wacAddWhitelist 暂停 #0 wacAddWhitelist (item=0xfffefad8) at wlanAC.c:98 #1 0x00232740 in wacSyncWhitelistFromFlash () at wlanAC.c:631 #2 0x00231838 in wacEnableOperation () at wlanAC.c:302 #3 0x00233b34 in wacStart () at wlanAC.c:1034 #4 0x002431e4 in ctrlModuleStart () at control.c:672 #5 0x002436d0 in ctrlPowerOn () at control.c:895 #6 0x002da9b0 in main (argc=1, argv=0xfffefe54) at main.c:103
(gdb) watch index # 设置当 index 变量发生变化时暂停 Watchpoint 2: index
(gdb) c # 继续运行 Continuing.
Thread 2.1 "hello" hit Watchpoint 5: index
Old value = 4147980344 New value = 0 wacAddWhitelist (item=0xfffefad8) at wlanAC.c:101 101 in wlanAC.c
GDB 常用命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
r 直接调到断点处,没有设置断点的话直接运行程序 b fun 设置一个断点breakpoint在函数”fun”的最开始 b N 在当前运行源文件的第N行设置断点 b file.c:N 在当前源文件file.c的第N行设置断点 d N 删掉delete第N行的断点 info break 显示所有断点信息 c 继续(continue)运行程序,一直到下一个断点或程序结束 f 运行直到当前函数(function)结束 s 按step调试1行,会进入函数体 s N 按step调试接下来的N行 n 调试1行,与按s命令不同的是此处不进入函数体 p var 输出(print)变量”var”的值 set var=val 设置变量”var”的值 bt 打印调用堆栈(stack trace) q 退出gdb