gdb 笔记(11) 您所在的位置:网站首页 《情感与形式》读书笔记 gdb 笔记(11)

gdb 笔记(11)

2024-02-21 14:52| 来源: 网络整理| 查看: 265

info 命令是一个复合指令,还可以用来查看当前进程的所有线程运行情况。

下面以 redis-server 进程为例来演示一下,使用 delete 命令删掉所有断点,然后使用 run 命令重启一下 redis-server,等程序正常启动后,我们按快捷键 Ctrl+C 中断程序,然后使用 info thread 命令来查看当前进程有哪些线程,分别中断在何处:

(gdb) delete Delete all breakpoints? (y or n) y (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /root/gdbtest/redis-4.0.11/src/redis-server [Thread debugging using libthread_db enabled] ...... 53062:M 10 Sep 17:11:10.810 * Ready to accept connections ^C Program received signal SIGINT, Interrupt. 0x00007ffff73ee923 in epoll_wait () from /lib64/libc.so.6 (gdb) info thread Id Target Id Frame 4 Thread 0x7fffef7fd700 (LWP 53065) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 3 Thread 0x7fffefffe700 (LWP 53064) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 2 Thread 0x7ffff07ff700 (LWP 53063) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 * 1 Thread 0x7ffff7fec780 (LWP 53062) "redis-server" 0x00007ffff73ee923 in epoll_wait () from /lib64/libc.so.6

通过 info thread 的输出可以知道 redis-server 正常启动后,一共产生了 4 个线程,包括一个主线程和三个工作线程,线程编号(Id 那一列)分别是 4、3、2、1。三个工作线程(2、3、4)分别阻塞在 Linux API pthread_cond_wait 处,而主线程(1)阻塞在 epoll_wait 处。

注意 虽然第一栏的名称叫 Id,但第一栏的数值不是线程的 Id,第三栏括号里的内容(如 LWP 53065)中,53065 这样的数值才是当前线程真正的 Id。那 LWP 是什么意思呢?在早期的 Linux 系统的内核里面,其实不存在真正的线程实现,当时所有的线程都是用进程来实现的,这些模拟线程的进程被称为 Light Weight Process(轻量级进程),后来 Linux 系统有了真正的线程实现,这个名字仍然被保留了下来。

读者可能会有疑问:怎么知道线程 1 就是主线程?线程 2、线程 3、线程 4 就是工作线程呢?是不是因为线程 1 前面有个星号(*)?错了,线程编号前面这个星号表示的是当前 GDB 作用于哪个线程,而不是主线程的意思。现在有 4 个线程,也就有 4 个调用堆栈,如果此时输入 backtrace 命令查看调用堆栈,由于当前 GDB 作用在线程 1,因此 backtrace 命令显示的一定是线程 1 的调用堆栈:

(gdb) bt #0 0x00007ffff73ee923 in epoll_wait () from /lib64/libc.so.6 #1 0x00000000004265df in aeApiPoll (tvp=0x7fffffffe300, eventLoop=0x7ffff08350a0) at ae_epoll.c:112 #2 aeProcessEvents (eventLoop=eventLoop@entry=0x7ffff08350a0, flags=flags@entry=11) at ae.c:411 #3 0x0000000000426aeb in aeMain (eventLoop=0x7ffff08350a0) at ae.c:501 #4 0x00000000004238ef in main (argc=1, argv=0x7fffffffe648) at server.c:3899

由此可见,堆栈 #4 的 main() 函数也证实了上面的说法,即线程编号为 1 的线程是主线程。

如何切换到其他线程呢?可以通过 thread 线程编号 切换到具体的线程上去。例如,想切换到线程 2 上去,只要输入 thread 2 即可,然后输入 bt 就能查看这个线程的调用堆栈了:

(gdb) info thread Id Target Id Frame 4 Thread 0x7fffef7fd700 (LWP 53065) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 3 Thread 0x7fffefffe700 (LWP 53064) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 2 Thread 0x7ffff07ff700 (LWP 53063) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 * 1 Thread 0x7ffff7fec780 (LWP 53062) "redis-server" 0x00007ffff73ee923 in epoll_wait () from /lib64/libc.so.6 (gdb) thread 2 [Switching to thread 2 (Thread 0x7ffff07ff700 (LWP 53063))] #0 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 (gdb) bt #0 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 #1 0x000000000047a91c in bioProcessBackgroundJobs (arg=0x0) at bio.c:176 #2 0x00007ffff76c0e25 in start_thread () from /lib64/libpthread.so.0 #3 0x00007ffff73ee34d in clone () from /lib64/libc.so.6

因此利用 info thread 命令就可以调试多线程程序。请注意,当把 GDB 当前作用的线程切换到线程 2 上之后,线程 2 前面就被加上了星号:

(gdb) info thread Id Target Id Frame 4 Thread 0x7fffef7fd700 (LWP 53065) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 3 Thread 0x7fffefffe700 (LWP 53064) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 * 2 Thread 0x7ffff07ff700 (LWP 53063) "redis-server" 0x00007ffff76c4945 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 1 Thread 0x7ffff7fec780 (LWP 53062) "redis-server" 0x00007ffff73ee923 in epoll_wait () from /lib64/libc.so.6

上面介绍的是 info 命令最常用的三种方法,更多关于 info 的组合命令在 GDB 中输入 help info 就可以查看:

(gdb) help info Generic command for showing things about the program being debugged. List of info subcommands: info address -- Describe where symbol SYM is stored info all-registers -- List of all registers and their contents info args -- Argument variables of current stack frame info auto-load -- Print current status of auto-loaded files info auto-load-scripts -- Print the list of automatically loaded Python scripts info auxv -- Display the inferior s auxiliary vector info bookmarks -- Status of user-settable bookmarks info breakpoints -- Status of specified breakpoints (all user-settable breakpoints if no argument) info checkpoints -- IDs of currently known checkpoints info classes -- All Objective-C classes info common -- Print out the values contained in a Fortran COMMON block info copying -- Conditions for redistributing copies of GDB info dcache -- Print information on the dcache performance info display -- Expressions to display when program stops info extensions -- All filename extensions associated with a source language info files -- Names of targets and files being debugged info float -- Print the status of the floating point unit info frame -- All about selected stack frame info frame-filter -- List all registered Python frame-filters info functions -- All function names info handle -- What debugger does when program gets various signals info inferiors -- IDs of specified inferiors (all inferiors if no argument) info line -- Core addresses of the code for a source line info locals -- Local variables of current stack frame info macro -- Show the definition of MACRO info macros -- Show the definitions of all macros at LINESPEC info mem -- Memory region attributes info os -- Show OS data ARG info pretty-printer -- GDB command to list all registered pretty-printers info probes -- Show available static probes info proc -- Show /proc process information about any running process info program -- Execution status of the program info record -- Info record options info registers -- List of integer registers and their contents info scope -- List the variables local to a scope ---Type to continue, or q to quit--- info selectors -- All Objective-C selectors info set -- Show all GDB settings info sharedlibrary -- Status of loaded shared object libraries info signals -- What debugger does when program gets various signals info skip -- Display the status of skips info source -- Information about the current source file info sources -- Source files in the program info stack -- Backtrace of the stack info static-tracepoint-markers -- List target static tracepoints markers info symbol -- Describe what symbol is at location ADDR info target -- Names of targets and files being debugged info tasks -- Provide information about all known Ada tasks info terminal -- Print inferior's saved terminal status info threads -- Display currently known threads info tracepoints -- Status of specified tracepoints (all tracepoints if no argument) info tvariables -- Status of trace state variables and their values info type-printers -- GDB command to list all registered type-printers info types -- All type names info variables -- All global and static variable names info vector -- Print the status of the vector unit info vtbl -- Show the virtual function table for a C++ object info warranty -- Various kinds of warranty you do not have info watchpoints -- Status of specified watchpoints (all watchpoints if no argument) info win -- List of all displayed windows Type "help info" followed by info subcommand name for full documentation. Type "apropos word" to search for commands related to "word". Command name abbreviations are allowed if unambiguous.

参考:https://download.csdn.net/columnTopic/5c0e2061edba1b6834591ebc



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有