首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

[]打印出所有线程函数调用栈

2013-01-19 
[求助]打印出所有线程函数调用栈各位大虾们,小弟现在有个功能,希望在有需要的情况下,能让自己的主线程将其

[求助]打印出所有线程函数调用栈
各位大虾们,小弟现在有个功能,希望在有需要的情况下,能让自己的主线程将其它所有线程中的当前函数调用栈信息打印出来,也就是LOG其它线程的调用关系SNAPSHOT。
不知道大家有哪些方法能够实现啊!
前提:不CORE DUMP。
[解决办法]
/proc/pid/*  应该有你要的信息,
[解决办法]
linux下有个pstack命令,你可以看一下他的源码。
[解决办法]

最简单的测试:
$~/host-rd/tttt$ cat 1.c ; gcc -pthread -Wall -g 1.c ; ./a.out &
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <pthread.h>
#include <execinfo.h>
#include <sys/syscall.h>  

#define gettid() syscall(__NR_gettid) 

void do_backtrace(int s)
{
        void* buff[32] = {0};
        int n = 0;

        int nstack = backtrace(buff,32);
        char** callstack = backtrace_symbols(buff,nstack);

        for(n = 0; n < nstack; ++n)
        {
                printf("%d %d : %s\n", (int)gettid(), n, callstack[n]);
        }

        free(callstack);
        printf("do_backtrace done\n");
}

void* test_thread_proc(void* arg)
{
        while(1) {
                usleep(10000);
        }
return 0;
}

int main()
{
        pthread_t tid;
        signal(SIGUSR1, do_backtrace);
        pthread_create(&tid, NULL, test_thread_proc, NULL);
        while(1) {
                usleep(10000);
        }

return 0;
}

[1] 5327
$~/host-rd/tttt$ export XID=$!
$~/host-rd/tttt$ pushd /proc/$XID/task; for AA in *; do kill -USR1 $AA; sleep 1; done ; popd
/proc/5327/task ~/host-rd/tttt /proc/5294/task ~/host-rd/tttt
5327 0 : ./a.out() [0x400816]
5327 1 : /lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7ff93fb614a0]
5327 2 : /lib/x86_64-linux-gnu/libc.so.6(nanosleep+0x2d) [0x7ff93fbea83d]
5327 3 : /lib/x86_64-linux-gnu/libc.so.6(usleep+0x34) [0x7ff93fc18774]
5327 4 : ./a.out() [0x400918]
5327 5 : /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7ff93fb4c76d]
5327 6 : ./a.out() [0x4006e9]
do_backtrace done


5328 0 : ./a.out() [0x400816]
5328 1 : /lib/x86_64-linux-gnu/libc.so.6(+0x364a0) [0x7ff93fb614a0]
5328 2 : /lib/x86_64-linux-gnu/libc.so.6(nanosleep+0x2d) [0x7ff93fbea83d]
5328 3 : /lib/x86_64-linux-gnu/libc.so.6(usleep+0x34) [0x7ff93fc18774]
5328 4 : ./a.out() [0x4008da]
5328 5 : /lib/x86_64-linux-gnu/libpthread.so.0(+0x7e9a) [0x7ff93fef1e9a]
5328 6 : /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d) [0x7ff93fc1ecbd]
do_backtrace done
~/host-rd/tttt /proc/5294/task ~/host-rd/tttt


[解决办法]
attach 进程啊, 要看哪个线程信息的时候往该线程发 SIGINT 就是.
libthread_db 是用来获得进程的线程信息的, 具体干活的时候一样是用 ptrace 完成. 像我们简单用的时候, 就用不着 libthread_db 了, 直接读 /proc/$PID 就是...

热点排行