zoukankan      html  css  js  c++  java
  • GDB 调试多线程程序的总结

    gdb 中step、next与finish的区别

    step 就是单步执行,遇到子函数就进入并且继续单步执行;在其他调试其中相当于step-into命令,作用是移动到下一个可执行的代码行。如果当前行是一个函数调用,则调试器进入函数并停止在函数体的第一行。step可以帮助初步揭开代码位置的谜团,例如:函数调用和函数本身可能在不同的文件中。

    next 是在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为一步。在其他调试器中相当于step-over,作用是在同一个调用栈层中移动到下一个可执行的代码行。调试器不会进入函数体。如果当前行是函数的最后一行,则,next将进入下一个栈层,并在调用函数的下一行停止。

    finish 就是但单步执行到子函数内时,用step out就可以执行完子函数余下部分,并返回到上一层函数。在其他调试器中相当于step-out,作用是在栈中前进到到下一层,并在调用函数的下一行停止。

    多线程的gdb调试

    假设现在有一个主线程创建了一个子线程。

    gdb调试时,设置断点,单步调试到pthread_create处的时候,这时候会创建子线程,会出现如下信息

    [New Thread 0x7ffff6fd1700 (LWP 6376)]
    

    默认情况下,gdb只跟踪主线程,新创建的线程都被阻塞在pthread_create函数处。

    info threads 可以调试的所有线程,gdb会为每个线程分配一个ID,这个ID和线程ID不同,ID号一般从1开始。

    如下,表示当前有两个线程1和2,*表示跟踪主线程1

    (gdb) info threads
      Id   Target Id         Frame 
      2    Thread 0x7ffff6fd1700 (LWP 6376) "test" 0x00007ffff70d0851 in clone ()
       from /lib64/libc.so.6
    * 1    Thread 0x7ffff7fee740 (LWP 6375) "test" main (argc=1, argv=0x7fffffffe2d8) at test.cpp:31
    

    thread ID 切换当前调试的线程为指定ID号,ID是gdb分配的序号,不是线程TID。

    set scheduler-locking off|on on锁定其他线程,只有当前选择调试的线程执行,off表示不锁定任何线程,当运行到断点处,将所有的线程都暂停下来,直到指定某个线程继续执行,如果在当前线程下使用continue的话会启动所有线程(GDB默认)。

    多线程调试控制指令

    thread apply ID1 ID2 ...IDn gdb_command 指定多个线程执行gdb中的command指令

    thread apply all command 指定所有线程执行gdb中的command指令

    non-stop模式

    上面说过一个线程中断在一个断点上,其他所有的线程都会被freeze。新版本的GDB中,引入了non-stop模式,在这个模式下:

    1. 当某个或多个线程在一个断点上,其他线程仍会并行运行

    2. 你可以选择某个被中断的线程,只让他运行。

    3. non-stop模式表示不停止模式,除了断点有关的进程会被停下来,其他线程会继续执行。

    设置non-stop模式,打开gdb后,在开始r之前,首先连续输入下面的指令

    set target-async 1
    set pagination off
    set non-stop on
    

    总结调试多线程的命令

    info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程

    thread ID(1,2,3…) 切换当前调试的线程为指定ID的线程

    break thread_test.c:123 thread all(例:在相应函数的位置设置断点break pthread_run1) 在所有线程中相应的行上设置断点

    thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command

    thread apply all command 让所有被调试线程执行GDB命令command

    set scheduler-locking 选项 command 设置线程是以什么方式来执行命令

    set scheduler-locking off 不锁定任何线程,也就是所有线程都执行,这是默认值

    set scheduler-locking on 只有当前被调试程序会执行

    set scheduler-locking on step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行

    线程池调试技巧

    调试进程池和线程池中的程序一个不错的方法,是将池中的个数减少至1,观察是否正确,然后逐步增加线程数量,调试线程的同步是否正确

  • 相关阅读:
    关于Jonathan S. Weissman与RIT(罗切斯特理工学院,位于纽约)
    jQuery获取元素值以及设置元素值总结
    页面跳转
    Node JS复制文件
    js获取当前日期并格式yyy-MM-dd
    Json文件删除元素
    HTML页面间传值
    计算机实用但冷门快捷键
    NodejS---require的机制
    Node某个JS导出方法变量以及在其他地方引用的例子
  • 原文地址:https://www.cnblogs.com/WindSun/p/12785322.html
Copyright © 2011-2022 走看看