zoukankan      html  css  js  c++  java
  • 线程的查看以及利用gdb调试多线程

    1. 线程的查看

    首先创建两个线程:

    #include <stdio.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <string.h>
    
    void* pthread_run1(void* arg)
    {
        (void)arg;
    
        while(1)
        {
            printf("I am thread1,ID: %lu
    ",pthread_self());
            sleep(1);
        }
    }
    
    void* pthread_run2(void* arg)
    {
        (void)arg;
    
        while(1)
        {
            printf("I am thread2,ID: %lu
    ",pthread_self());
            sleep(1);
        }
    }
    
    
    int main()
    {
    
        pthread_t tid1;
        pthread_t tid2;
    
        pthread_create(&tid1,NULL,pthread_run1,NULL);
        pthread_create(&tid2,NULL,pthread_run2,NULL);
    
        printf("I am main thread
    ");
    
        pthread_join(tid1,NULL);
        pthread_join(tid2,NULL);
        return 0;
    }

    分析:上面程序中创建了两个线程,程序执行起来,main函数所在程序为主线程,在这个主线程中有两个新线程运行

    命令行查看:

    //查看当前运行的进程
    ps -aux | grep main
    //查看当前运行的轻量级进程
     ps -aL | grep -w main
    //查看主线程和新线程的关系
    pstree -p 主线程id

    //查看主线程和新线程的详细关系

    pstree -p user | grep main
    |-gnome-terminal-(4573)-+-bash(4583)---main(7991)-+-{main}(7992)
    |                                          | `-{main}(7993)

    附加:

    显示当前所有进程的进程号和进程id:

    pstree -p

    显示所有进程的所有详细信息,遇到相同的进程名可以压缩显示:

    pstree  -a

    2. 线程栈结构的查看

    2.1 安装pstack

    sudo apt-get install pstack

    2.2 显示线程堆栈信息

    $ ps -ef | grep main
    heah   8199 4583 0 08:51 pts/0 00:00:00 ./main

    $ sudo pstack 8199

    8199: ./main
    pstack: Input/output error
    failed to read target.

    安装的pstack有问题,自实现:

    #!/bin/sh
    
    if test $# -ne 1; then
        echo "Usage: `basename $0 .sh` <process-id>" 1>&2
        exit 1
    fi
    
    if test ! -r /proc/$1; then
        echo "Process $1 not found." 1>&2
        exit 1
    fi
    
    # GDB doesn't allow "thread apply all bt" when the process isn't
    # threaded; need to peek at the process to determine if that or the
    # simpler "bt" should be used.
    
    backtrace="bt"
    if test -d /proc/$1/task ; then
        # Newer kernel; has a task/ directory.
        if test `/bin/ls /proc/$1/task | /usr/bin/wc -l` -gt 1 2>/dev/null ; then
        backtrace="thread apply all bt"
        fi
    elif test -f /proc/$1/maps ; then
        # Older kernel; go by it loading libpthread.
        if /bin/grep -e libpthread /proc/$1/maps > /dev/null 2>&1 ; then
        backtrace="thread apply all bt"
        fi
    fi
    
    GDB=${GDB:-/usr/bin/gdb}
    
    if $GDB -nx --quiet --batch --readnever > /dev/null 2>&1; then
        readnever=--readnever
    else
        readnever=
    fi
    
    # Run GDB, strip out unwanted noise.
    $GDB --quiet $readnever -nx /proc/$1/exe $1 <<EOF 2>&1 | 
    set width 0
    set height 0
    set pagination no
    $backtrace
    EOF
    /bin/sed -n 
        -e 's/^((gdb) )*//' 
        -e '/^#/p' 
        -e '/^Thread/p'
    #end

    $ sudo mv mystack /usr/bin/pstack

    $ sudo pstack 8199

    3. 利用gdb查看线程信息

    将进程附加到gdb调试器当中,查看是否创建了新线程:gdb attach 主线程ID

    $sudo gdb attach 8199

    1. 查看线程的一些信息

    //1.查看进程:info inferiors
    //2.查看线程:info threads
    //3.查看线程栈结构:bt
    //4.切换线程:thread n(n代表第几个线程)

    4. 利用gdb调试多线程

      当程序没有启动,线程还没有执行,此时利用gdb调试多线程和调试普通程序一样,通过设置断点,运行,查看信息等等,在这里不在演示,最后会加上调试线程的命令

    总结调试多线程的命令

    命令

    命令 用法
    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的行为)以外,只有当前线程会执行
     
  • 相关阅读:
    Python3基础 函数 未指定返回值,返回NONE
    Python3基础 函数 有参数有返回值 对传入的参数加1
    Python3基础 函数 无参数无返回值 调用会输出hello world的函数
    Python3基础 函数 收集参数(tuple)+普通参数 的示例
    MVC中几种常用ActionResult
    sqlserver 中存储过程的基础知识记录
    常用的正则表达式方法2
    常用的正则表达式方法1
    vs2012运行项目报未能加载文件或程序集“System.Web.Mvc, Version=4.0.0.1,Culture=neutral”问题和解决方法
    怎样解决PowerDesigner15出现许可证过期问题?
  • 原文地址:https://www.cnblogs.com/fengtai/p/12181907.html
Copyright © 2011-2022 走看看