[skill][gdb] gdb 多线程调试

中文快速入门:

http://coolshell.cn/articles/3643.html

进阶:

多线程怎么调试:

  分 all-stop 和 non-stop 两个模式。

  all-stop 模式下,一个断点。所以线程全部终止运行。

  使用 set non-stop on命令可以进入non-stop模式。其他线程不会受到一个线程停止的影响。

例如:non-stop模式下设置了一个中断: 其他线程正常运行。

(gdb) info thread
  Id   Target Id         Frame
  5    Thread 0x7fffb45fc700 (LWP 10101) "lcore-slave-7" (running)
* 4    Thread 0x7fffb4dfd700 (LWP 10100) "lcore-slave-6" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  3    Thread 0x7fffb55fe700 (LWP 10099) "lcore-slave-3" (running)
  2    Thread 0x7fffb5dff700 (LWP 10098) "eal-intr-thread" (running)
  1    Thread 0x7ffff7fef8c0 (LWP 10097) "l3fwd" (running)
(gdb) 

例如:all-stop模式下,scheduler-locking off 时:一个线程中断,所有线程都中断

Breakpoint 6, lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
177                             nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
(gdb) info thread
  Id   Target Id         Frame
* 5    Thread 0x7fffb45fc700 (LWP 10108) "lcore-slave-7" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  4    Thread 0x7fffb4dfd700 (LWP 10107) "lcore-slave-6" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  3    Thread 0x7fffb55fe700 (LWP 10106) "lcore-slave-3" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  2    Thread 0x7fffb5dff700 (LWP 10105) "eal-intr-thread" 0x00007ffff71e62c3 in epoll_wait () from /lib64/libc.so.6
  1    Thread 0x7ffff7fef8c0 (LWP 10104) "l3fwd" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
(gdb) show non-stop
Controlling the inferior in non-stop mode is off.
(gdb) show scheduler-locking
Mode for locking scheduler during execution is "off".
(gdb) (gdb) c Continuing.[Switching to Thread 0x7fffb4dfd700 (LWP 10107)]

Breakpoint 6, lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177177                             nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,(gdb) info thread              Id   Target Id         Frame    5    Thread 0x7fffb45fc700 (LWP 10108) "lcore-slave-7" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177* 4    Thread 0x7fffb4dfd700 (LWP 10107) "lcore-slave-6" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177  3    Thread 0x7fffb55fe700 (LWP 10106) "lcore-slave-3" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177  2    Thread 0x7fffb5dff700 (LWP 10105) "eal-intr-thread" 0x00007ffff71e62c3 in epoll_wait () from /lib64/libc.so.6  1    Thread 0x7ffff7fef8c0 (LWP 10104) "l3fwd" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177(gdb) cContinuing.

scheduler-locking 等于 on时。线程的调试,单步执行。其他线程都不运行改变其当前执行位置。

(gdb) thread 1
[Switching to thread 1 (Thread 0x7ffff7fef8c0 (LWP 10104))]
#0  lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
177                             nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
(gdb) info thread
  Id   Target Id         Frame
  5    Thread 0x7fffb45fc700 (LWP 10108) "lcore-slave-7" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:179
  4    Thread 0x7fffb4dfd700 (LWP 10107) "lcore-slave-6" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:156
  3    Thread 0x7fffb55fe700 (LWP 10106) "lcore-slave-3" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  2    Thread 0x7fffb5dff700 (LWP 10105) "eal-intr-thread" 0x00007ffff71e62c3 in epoll_wait () from /lib64/libc.so.6
* 1    Thread 0x7ffff7fef8c0 (LWP 10104) "l3fwd" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
(gdb) n
179                             if (nb_rx == 0)
(gdb) n
180                                     continue;
(gdb) n
174                     for (i = 0; i < qconf->n_rx_queue; ++i) {
(gdb) info thread
  Id   Target Id         Frame
  5    Thread 0x7fffb45fc700 (LWP 10108) "lcore-slave-7" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:179
  4    Thread 0x7fffb4dfd700 (LWP 10107) "lcore-slave-6" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:156
  3    Thread 0x7fffb55fe700 (LWP 10106) "lcore-slave-3" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  2    Thread 0x7fffb5dff700 (LWP 10105) "eal-intr-thread" 0x00007ffff71e62c3 in epoll_wait () from /lib64/libc.so.6
* 1    Thread 0x7ffff7fef8c0 (LWP 10104) "l3fwd" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:174
(gdb) 

当 scheduler-locking 切换成 off,当进程执行一个next,其他进程就都执行了,并且被中断到其他线程里。承接上图代码:

如果每一个线程里都有中断,这种情况下,完全无法进行单步调试。

(gdb) set scheduler-locking off
(gdb) info thread
  Id   Target Id         Frame
  5    Thread 0x7fffb45fc700 (LWP 10108) "lcore-slave-7" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:179
  4    Thread 0x7fffb4dfd700 (LWP 10107) "lcore-slave-6" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:156
  3    Thread 0x7fffb55fe700 (LWP 10106) "lcore-slave-3" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  2    Thread 0x7fffb5dff700 (LWP 10105) "eal-intr-thread" 0x00007ffff71e62c3 in epoll_wait () from /lib64/libc.so.6
* 1    Thread 0x7ffff7fef8c0 (LWP 10104) "l3fwd" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:174
(gdb) n
[Switching to Thread 0x7fffb4dfd700 (LWP 10107)]

Breakpoint 6, lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
177                             nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
(gdb) info thread
  Id   Target Id         Frame
  5    Thread 0x7fffb45fc700 (LWP 10108) "lcore-slave-7" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
* 4    Thread 0x7fffb4dfd700 (LWP 10107) "lcore-slave-6" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  3    Thread 0x7fffb55fe700 (LWP 10106) "lcore-slave-3" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:177
  2    Thread 0x7fffb5dff700 (LWP 10105) "eal-intr-thread" 0x00007ffff71e62c3 in epoll_wait () from /lib64/libc.so.6
  1    Thread 0x7ffff7fef8c0 (LWP 10104) "l3fwd" lpm_main_loop (dummy=0x0) at /root/src/sdk/@dpdk/dpdk-stable-16.07.1/examples/l3fwd/l3fwd_lpm.c:174
(gdb) 

还有一个step模式。含义是:当用"step"命令调试线程时,其它线程不会执行,但是用其它命令(比如"next")调试线程时,其它线程也许会执行。

应该是还有一些特殊情况的,不过含义既如此!

  https://sourceware.org/gdb/current/onlinedocs/gdb/Thread-Stops.html#Thread-Stops

总结一下:

  1. 对整个进程全局调试,即哪里有中断就断到哪里。断的时候,整个进程停止执行。

    此时,使用默认设置: non-step = off  scheduler-locking = off

  2. 需要专心调试一个线程,其他线程保持正常运行状态。

    使用 non-step = on

  3. 需要专心调试一个线程,其他线程保持停止状态,并且不影响当前线程。

    使用 non-stop = off  scheduler-locking = on

  4. 还没遇到我需要这个场景的时候

    使用 non-stop = off  scheduler-locking = step

inferiors 是什么?

  http://moss.cs.iit.edu/cs351/gdb-inferiors.html

时间: 2024-10-26 22:53:33

[skill][gdb] gdb 多线程调试的相关文章

gdb 多线程调试

gdb 多线程调试 http://hi.baidu.com/hcq11/blog/item/9f5bfc6e696209d680cb4a25.html http://hi.baidu.com/litto/blog/item/759389dd198111375882dd1e.html http://blogold.chinaunix.net/u3/94700/showart_2389432.html   <推荐阅读> 先介绍一下GDB多线程调试的基本命令. info threads 显示当前可调

GDB常用调试命令以及多进程多线程调试

转载自:http://blog.csdn.net/freeelinux/article/details/53700266 一:普通命令 1.list命令 list  linenum      显示程序第linenum行周围的程序 list  function      显示函数名为function的函数的源程序 list                      显示当前行后面的源程序 list -                    显示当前行前面的源程序 2.run(r) 运行命令. ru

GDB多线程调试分析

0x00: 在Linux系统上Gdb提供了一组多线程调试命令,如表所示: 多线程调试的主要任务是准确及时地捕捉被调试程序线程状态的变化的事件,并且GDB针对根据捕捉到的事件做出相应的操作,其实最终的结果就是维护一根叫thread list的链表.上面的调试命令都是基于thread list链表来实现的,后面会有讲到. 0x01:Gdb在linux平台多线程调试实现主要依赖下面三个文件 thread.c:文件它的任务非常简单,就是多线程调试命令子集的实现,比如info threads.当用户在gd

gdb多线程调试

死锁:一种情形,此时执行程序中两个或多个线程发生永久堵塞(等待),每个线程都在等待被 其他线程占用并堵塞了的资源.例如,如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象. gdb调试死锁的方法: gdb attach pid thread apply all bt 找到_lll_lock_wait 锁等待的地方. 然后查找该锁被哪个线程锁住了. 例如: 查看哪个线程拥有互斥体 (gdb) print AccountA_mutex $1 = {__

GDB 多线程调试:只停止断点的线程,其他线程任然执行; 或只运行某些线程 其他线程中断

多线程调试之痛 调试器(如VS2008和老版GDB)往往只支持all-stop模式,调试多线程程序时,如果某个线程断在一个断点上,你的调试器会让整个程序freeze,直到你continue这个线程,程序中的其他线程才会继续运行.这个限制使得被调试的程序不能够像真实环境中那样运行--当某个线程断在一个断点上,让其他线程并行运行. GDBv7.0引入的non-stop模式使得这个问题迎刃而解.在这个模式下, 当某个或多个线程断在一个断点上,其他线程仍会并行运行 你可以选择某个被断的线程,并让它继续运

Linux学习——Gdb基本调试方法&amp;&amp;多线程调试

1.Gdb的基本调试 示例代码 //e.c #include <stdio.h> void debug(char *str) { printf("debug info :%s\n",str ); } int main(int argc,char *argv[]){ int i,j; j=0; for(i=0;i<10;i++){ j+=5; printf("now a=%d\n", j); } } 1 2 3 4 5 6 7 8 9 10 11 1

使用gdb进行程序调试1-在GDB中运行程序

在GDB中运行程序 一.启动程序 如果在启动gdb时没有指明程序,可以使用命令file或exec-file加载程序: run(r): run(r)命令使程序启动,可以在run命令中指明程序参数:值得注意的是,首次运行run后,如果再次执行run并且不带参数,会以之前的参数运行程序. set args: 指定程序的参数.set args后,run可以不带参数而以指定的参数运行程序.如果set args不太参数,清楚程序参数,执行run后程序不太参数运行. 在加载程序后,如果程序重新编译,gdb会根

gdb 远程qemu-arm调试

把 c 编译成 arm 指令的可运行文件 /usr/bin/arm-linux-gnueabi-g++ hello.cpp cat hello.cpp #include <stdio.h> void crash(){ char *a=0; *a=0; } int main() { printf("hello world\n"); crash(); printf("after crash\n"); } 直接执行报错.由于 host 是 linux x86

gdb 和 addr2line 调试 crash(包含如何调试so里面的crash)

嵌入式编程中会遇到各种crash的问题. 对于这样的问题,有两种调试方法: addr2line  和 gdb. 第一章   先讲解下gcc 编译加不加 -g 对程序的影响, 还有strip. //1.1.cpp #include <iostream> using namespace std; bool IsUnique() {         int k = 0, m = 0;         k = k/m;      //这里会crash         return true; } in