zoukankan      html  css  js  c++  java
  • 每天学点GDB 7

    使用GDB进行多线程调试,查看互斥变量。

    演示源码如下

    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    
    static void* thread_func(void* args);
    pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
    int sum = 0;
    #define MAX_NUM 10000
    
    int main(int argc, char** argv) {
      int seq = 0;
      pthread_t thread_handle;
      for ( seq = 0; seq < 5; seq++) {
        int* tmp_seq = (int*)malloc(sizeof(int));
        *tmp_seq = seq;
        pthread_create(&thread_handle, NULL, thread_func, tmp_seq);
      }
      while ( 1 ) sleep(20);
      return 0;
    }
    
    static void* thread_func(void* args) {
      int thread_seq = *(int*)args;
      free(args);
      
      while ( 1 ) 
        {
          sleep(thread_seq + 2);
          pthread_mutex_lock(&g_mutex);
          if ( sum < MAX_NUM ) 
          sum++;
          else
        sum = 0;
          printf("in thread %d, sum is %d\n", thread_seq, sum);
          pthread_mutex_unlock(&g_mutex);
        }
    
    }

    编译

    gcc -o demo -g demo.c -lpthread

    运行效果如下

    in thread 0, sum is 1
    in thread 1, sum is 2
    in thread 2, sum is 3
    in thread 0, sum is 4
    in thread 3, sum is 5
    in thread 4, sum is 6
    in thread 1, sum is 7
    in thread 0, sum is 8
    in thread 2, sum is 9

    使用GDB进行调试

    gdb ./demo
    设置断点
    gdb) br 32

    查看运行的线程

    gdb) info threads
     Id   Target Id         Frame 
      6    Thread 0xb5c9eb40 (LWP 914) "demo" 0xb7fdd416 in __kernel_vsyscall ()
      5    Thread 0xb649fb40 (LWP 913) "demo" 0xb7fdd416 in __kernel_vsyscall ()
      4    Thread 0xb6ca0b40 (LWP 912) "demo" 0xb7fdd416 in __kernel_vsyscall ()
      3    Thread 0xb74a1b40 (LWP 911) "demo" 0xb7fdd416 in __kernel_vsyscall ()
    * 2    Thread 0xb7ca2b40 (LWP 910) "demo" thread_func (args=0x804a008) at demo.cpp:32
      1    Thread 0xb7ca4700 (LWP 906) "demo" 0xb7fdd416 in __kernel_vsyscall ()

    查看当前线程的函数调用堆栈

    gdb) bt full

    查看哪个线程拥有互斥变量,首先需要知道pthread_mutex_t的具体结构是什么,

    gdb) whatis g_mutex
    type = pthread_mutex_t
    gdb) set print pretty #让GDB输出效果排版的好看一些 gdb) ptype g_mutex type
    = union pthread_mutex_t { pthread_mutex_t::__pthread_mutex_s __data; char __size[24]; long __align; }

    打印出g_mutex的具体内容

    gdb) p g_mutex
    $2 = {
      __data = {
        __lock = 1, 
        __count = 0, 
        __owner = 910, 
        __kind = 0, 
        __nusers = 1, 
        {
          __spins = 0, 
          __list = {
            __next = 0x0
          }
        }
      }, 
      __size = "\001\000\000\000\000\000\000\000\216\003\000\000\000\000\000\000\001\000\000\000\000\000\000", 
      __align = 1
    }

    各位看官,注意上述输出中,owner表示当前拥有g_mutex的线程。

    那么谁是910呢,上面用”info threads"只输出了1,2,3,4,5,6无法对应,ok. 用点top小技巧,

    top -H -p 906

    906表示demo的进程ID,-H表示打印出所有的线程。

    当前拥有g_mutex是910,那么应该是第二号线程,即thread_seq为0的线程。

    如果想在程序运行的时候知道当前线程中类似于top输出的pid值,可以通过如下方法。

    /*#method 1*/
    pid_t gettid(void);
    
    /**************************************
    *#method 2 using the following system call 
    **************************************/
    
    #include <sys/syscall.h>
    pid_t tid = (pid_t) syscall (SYS_gettid);

     最后需要提醒的是,当设定断点停下来的时候,其它线程其实还是可以继续运行的。如果只想让当前线程可以运行,其它的全部停下来的话。请用下列的指令。

    gdb) set scheduler-locking on

    关于这个内容,可以参考链接http://sourceware.org/gdb/onlinedocs/gdb/All_002dStop-Mode.html

     转载时请注明出处,谢谢。

  • 相关阅读:
    Android中getLocationOnScreen和getLocationInWindow 获取屏幕大小
    Android Scroller类的详细分析
    This tag and its children can be replaced by one <TextView/> and a compound drawable
    Activity生命周期之我见
    ViewPager的使用方法和实现过程
    Android提高第九篇之GridView和SQLite实现分页表格
    关闭对话框,OnClose和OnCancel
    iOS: 学习笔记, 透过Boolean看Swift(译自: https://developer.apple.com/swift/blog/ Aug 5, 2014 Boolean)
    回复有关“清理哲学上的垃圾、雾霾......”的评议
    Android图片裁剪之自由裁剪
  • 原文地址:https://www.cnblogs.com/hseagle/p/3040316.html
Copyright © 2011-2022 走看看