gdb使用

来源:互联网 发布:能够翻译文档软件 编辑:程序博客网 时间:2024/06/10 20:46

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));     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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
$ gdb gdbThreadTest//调试gdbThreadTest
  • 1
  • 1

加断点

(gdb) break 7Breakpoint 1 at 0x400a19: file kangThread.cpp, line 7.(gdb) break 35Breakpoint 2 at 0x400b35: file kangThread.cpp, line 35.(gdb) info breakNum     Type           Disp Enb Address            What1       breakpoint     keep y   0x0000000000400a19 in ThreadFun(void*) at kangThread.cpp:72       breakpoint     keep y   0x0000000000400b35 in main() at kangThread.cpp:35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

开始运行

(gdb) rStarting 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_printersImportError: No module named 'libstdcxx'[New Thread 0x7ffff6fd5700 (LWP 2773)][Switching to Thread 0x7ffff6fd5700 (LWP 2773)]Breakpoint 1, ThreadFun (arg=0x602010) at kangThread.cpp:7warning: Source file is more recent than executable.7       int *value=static_cast<int*> (arg);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

查看线程信息

(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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

(gdb) n8       std::cout<<"This is thread"<<*value<<std::endl;(gdb) p *value$2 = 1
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

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

(gdb) cContinuing.1[Switching to Thread 0x7ffff67d4700 (LWP 2774)]Breakpoint 1, ThreadFun (arg=0x602030) at kangThread.cpp:77       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:77       int *value=static_cast<int*> (arg);(gdb) n8       std::cout<<"This is thread"<<*value<<std::endl;(gdb) p *value$3 = 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

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

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

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


原创粉丝点击