码迷,mamicode.com
首页 > 数据库 > 详细

gdb调试多线程

时间:2015-08-25 23:47:41      阅读:345      评论:0      收藏:0      [点我收藏+]

标签:gdb   linux   多线程   

gdb使用

gdb是非常强大的调试工具,在文本模式下使用。使用方法可以参考陈皓的两篇文章
用GDB调试程序(一)
用GDB调试程序(二)

gdb常用命令在下表列出:

命令 描述
backtrace(或bt) 查看各级函数调用及参数
finish 连续运行到当前函数返回为止,然后停下来等待命令
frame(或f) 帧编号 选择栈帧
info(或i) locals 查看当前栈帧局部变量的值
list(或l) 列出源代码,接着上次的位置往下列,每次列10行
list 行号 列出从第几行开始的源代码
list 函数名 列出某个函数的源代码
next(或n) 执行下一行语句
print(或p) 打印表达式的值,通过表达式可以修改变量的值或者调用函数
quit(或q) 退出gdb调试环境
set var 修改变量的值
start 开始执行程序,停在main函数第一行语句前面等待命令
step(或s) 执行下一行语句,如果有函数调用则进入到函数中

gdb与多线程

在多线程编程时,当我们需要调试时,有时需要控制某些线程停在断点,有些线程继续执行。有时需要控制线程的运行顺序。有时需要中断某个线程,切换到其他线程。这些都可以通过gdb实现。

先来看一下gdb调试多线程常用命令:

  • info threads:显示可以调试的所有线程。gdb会为每个线程分配一个ID(和tid不同),编号一般从1开始。后面的ID是指这个ID。

  • thread ID:切换当前调试的线程为指定ID的线程。

  • break FileName.cpp:LinuNum thread all:所有线程都在文件FileName.cpp的第LineNum行有断点。

  • thread apply ID1 ID2 IDN command:多个线程执行gdb命令command。

  • thread apply all command:所有线程都执行command命令。

  • set scheduler-locking off|on|step:在调式某一个线程时,其他线程是否执行。off,不锁定任何线程,默认值。on,锁定其他线程,只有当前线程执行。step,在step(单步)时,只有被调试线程运行。

  • set non-stop on/off:当调式一个线程时,其他线程是否运行。

  • set pagination on/off:在使用backtrace时,在分页时是否停止。

  • set target-async on/ff:同步和异步。同步,gdb在输出提示符之前等待程序报告一些线程已经终止的信息。而异步的则是直接返回。

来看一个例子:
gdbTest.cpp。程序很简单,只是让两个线程执行函数ThreadFun,在函数中打印传入的参数。

#include <iostream>
#include <pthread.h>

void* ThreadFun(void* arg)
{
    int *value=static_cast<int*> (arg);
    std::cout<<"This is thread"<<*value<<std::endl;
    pthread_exit(0);
}

int main()
{
    int  ret=0;
    pthread_t thread_id1,thread_id2;

    int* v1=new int(1);
    int* v2=new int(2);
    ret = pthread_create(&thread_id1, NULL, ThreadFun, static_cast<void*>(v1)); //这里笔误,应为thread_id1 就是调试这里的错误
    if (ret)
    {
        std::cout<<"Create pthread error!"<<std::endl;
        return 1;
    }

    ret = pthread_create(&thread_id2, NULL, ThreadFun, static_cast<void*>(v2));
    if (ret)
    {
        std::cout<<"Create pthread error!"<<std::endl;
        return 1;
    }

    pthread_join(thread_id1, NULL);
    pthread_join(thread_id2, NULL);

    return 0;
}
$ gdb gdbThreadTest//调试gdbThreadTest

加断点

(gdb) break 7
Breakpoint 1 at 0x400a19: file kangThread.cpp, line 7.
(gdb) break 35
Breakpoint 2 at 0x400b35: file kangThread.cpp, line 35.
(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400a19 in ThreadFun(void*) at kangThread.cpp:7
2       breakpoint     keep y   0x0000000000400b35 in main() at kangThread.cpp:35

开始运行

(gdb) r
Starting program: /home/kang/src/mulThread/kangThread 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Traceback (most recent call last):
  File "/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19-gdb.py", line 63, in <module>
    from libstdcxx.v6.printers import register_libstdcxx_printers
ImportError: No module named ‘libstdcxx‘
[New Thread 0x7ffff6fd5700 (LWP 2773)]
[Switching to Thread 0x7ffff6fd5700 (LWP 2773)]

Breakpoint 1, ThreadFun (arg=0x602010) at kangThread.cpp:7
warning: Source file is more recent than executable.
7       int *value=static_cast<int*> (arg);

查看线程信息

(gdb) info thread
[New Thread 0x7ffff67d4700 (LWP 2774)]
  Id   Target Id         Frame 
  3    Thread 0x7ffff67d4700 (LWP 2774) "kangThread" clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:81
* 2    Thread 0x7ffff6fd5700 (LWP 2773) "kangThread" ThreadFun (arg=0x602010) at kangThread.cpp:7
  1    Thread 0x7ffff7fda780 (LWP 2769) "kangThread" clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:81

可以看到ID为2的线程执行到了断点Breakpoint 1。可以看一下value的值

(gdb) n
8       std::cout<<"This is thread"<<*value<<std::endl;
(gdb) p *value
$2 = 1

切换到线程3,看一下线程3执行到了哪里

(gdb) c
Continuing.
1
[Switching to Thread 0x7ffff67d4700 (LWP 2774)]

Breakpoint 1, ThreadFun (arg=0x602030) at kangThread.cpp:7
7       int *value=static_cast<int*> (arg);
(gdb) info thread
  Id   Target Id         Frame 
* 3    Thread 0x7ffff67d4700 (LWP 2774) "kangThread" ThreadFun (arg=0x602030) at kangThread.cpp:7
  2    Thread 0x7ffff6fd5700 (LWP 2773) "kangThread" __GI__dl_debug_state () at dl-debug.c:74
  1    Thread 0x7ffff7fda780 (LWP 2769) "kangThread" 0x00007ffff7bc566b in pthread_join (threadid=140737337186048, 
    thread_return=0x0) at pthread_join.c:92
(gdb) thread 3
[Switching to thread 3 (Thread 0x7ffff67d4700 (LWP 2774))]
#0  ThreadFun (arg=0x602030) at kangThread.cpp:7
7       int *value=static_cast<int*> (arg);
(gdb) n
8       std::cout<<"This is thread"<<*value<<std::endl;
(gdb) p *value
$3 = 2

可以看出线程3的value为2。

还有其他许多命令和方法,要在实践中慢慢熟悉。

版权声明:本文为博主原创文章,未经博主允许不得转载。

gdb调试多线程

标签:gdb   linux   多线程   

原文地址:http://blog.csdn.net/kangroger/article/details/47986197

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!