GDB调试多线程

GDB是*nix下常用的调试工具,可以提供及其复杂的调试功能,功能十分强大。这里展示一下GDB调试多线程的常规方法。
常用命令:
info threads :显示当前可以调试的所有线程。
thread IDx : IDx请用上述命令中的线程ID替换,该命令用于切换被调试的线程,请注意GDB只能调试一个执行序列,也就一个传统意义上的进程
break file.c:20 thread all:在file.c中的第20行,为所有经过这里的线程设置断点
set scheduler-locking off|on|step:线程之间是并行执行的,step之类的命令会对所有线程生效。该命令就是提供了一种只对单一线程生效的解决方式。选项off表示不锁定任何进程,也就是默认情况。on表示命令只对当前线程生效。step表示在单步的时候,除了next过一个函数的情况以外,只对当前线程执行。

使用举例:

应用1,下面代码会产生coredump,我们调试之。

#include <stdio.h>
#include <pthread.h>

int a(void){
    sleep(2);
    return 0;
}

int b(){
    a();
    return 0;
}

int c(){
    b();
    return 0;
}
void *myThread1(void)
{
    int i=9;
    while(i>0)
    {
        printf("Our 1st pthread,created by chn89.\n");
        sleep(2);
        i--;
        c();
    }
    pthread_exit(0);
}

void *myThread2(void)
{
    int i=5;
    while(i>0)
    {
        printf("Our 2st pthread,created by chn89.\n");
        sleep(2);
        i--;
    }
    pthread_exit(0);
}

int main()
{
    int  ret=0;
    pthread_t thread_id1,thread_id2;
  
    ret = pthread_create(&thread_id1, NULL, (void*)myThread1, NULL); //这里笔误,应为thread_id1 就是调试这里的错误
    if (ret)
    {
        printf("Create pthread error!\n");
        return 1;
    }
  
    ret = pthread_create(&thread_id2, NULL, (void*)myThread2, NULL);
    if (ret)
    {
        printf("Create pthread error!\n");
        return 1;
    }
  
    pthread_join(thread_id1, NULL);
    pthread_join(thread_id2, NULL);
  
    return 0;
}
编译之 gcc pthread_gdb.c -g  -lpthread
执行会提示segment错误,并提示产生coredump。但是却没有产生。需要执行ulimit -c unlimited。再执行一次,才真正的产生了coredump文件。
执行gdb a.out corefile 并执行bt查看执行backtrace,显示第49行执行错误。也就是初步怀疑线程1运行有问题。
执行
   gdb a.out
  (gdb) b 49
  (gdb) thread 2 //主线程是1
  (gdb) c
之后发现线程2工作正常,同理对线程2,也正常。按理pthread_join()是库函数不应该有问题,仔细检查发现,XX的笔误。这里提供了单独调试线程的方法,各位可以一试。

应用2,代码是修正笔误的上述代码,这里假设上述代码已经处于运行状态,但是跑飞了,需要确定各线程执行位置。

gdb a.out	pid -- pid是运行的进程号
(gdb) thread 2
(gdb) bt
#0  0x00855416 in __kernel_vsyscall ()
#1  0x00bf1086 in nanosleep () from /lib/libc.so.6
#2  0x00bf0ea4 in sleep () from /lib/libc.so.6
#3  0x08048516 in a () at pthread_gdb.c:5
#4  0x08048528 in b () at pthread_gdb.c:10
#5  0x0804853a in c () at pthread_gdb.c:15
#6  0x08048571 in myThread1 () at pthread_gdb.c:26
#7  0x00cede99 in start_thread () from /lib/libpthread.so.0
#8  0x00c2cd2e in clone () from /lib/libc.so.6
可以看出线程1的backtrace,正在执行函数a中的sleep呢。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值