如何理解"/proc/[pid]/stack"?

13
根据proc手册:
/proc/[pid]/stack(自Linux 2.6.29起)提供了该进程内核栈中函数调用的符号跟踪。仅当内核使用CONFIG_STACKTRACE配置选项构建时,才提供此文件。
因此我编写了一个测试程序:
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>

void *thread_func(void *p_arg)
{
        pid_t pid = fork();
        if (pid > 0) {
            wait(NULL);
            return 0;
        } else if (pid == 0) {
            sleep(1000);
            return 0;
        }
        return NULL;
}
int main(void)
{
        pthread_t t1, t2;

        pthread_create(&t1, NULL, thread_func, "Thread 1");
        pthread_create(&t2, NULL, thread_func, "Thread 2");

        sleep(1000);
        return 0;
}

运行后,使用pstack检查进程的线程:

linux-uibj:~ # pstack 24976
Thread 3 (Thread 0x7fd6e4ed5700 (LWP 24977)):
#0  0x00007fd6e528d3f4 in wait () from /lib64/libpthread.so.0
#1  0x0000000000400744 in thread_func ()
#2  0x00007fd6e52860a4 in start_thread () from /lib64/libpthread.so.0
#3  0x00007fd6e4fbb7fd in clone () from /lib64/libc.so.6
Thread 2 (Thread 0x7fd6e46d4700 (LWP 24978)):
#0  0x00007fd6e528d3f4 in wait () from /lib64/libpthread.so.0
#1  0x0000000000400744 in thread_func ()
#2  0x00007fd6e52860a4 in start_thread () from /lib64/libpthread.so.0
#3  0x00007fd6e4fbb7fd in clone () from /lib64/libc.so.6
Thread 1 (Thread 0x7fd6e569f700 (LWP 24976)):
#0  0x00007fd6e4f8d6cd in nanosleep () from /lib64/libc.so.6
#1  0x00007fd6e4f8d564 in sleep () from /lib64/libc.so.6
#2  0x00000000004007b1 in main ()

同时,检查 /proc/24976/stack

linux-uibj:~ # cat /proc/24976/stack
[<ffffffff804ba1a7>] system_call_fastpath+0x16/0x1b
[<00007fd6e4f8d6cd>] 0x7fd6e4f8d6cd
[<ffffffffffffffff>] 0xffffffffffffffff
24976进程有3个线程,它们都在系统调用(nanosleepwait)上被阻塞,所以现在所有的3个线程都在kernel空间中工作,并且成为了内核线程,是吗?如果是这样,那么/proc/[pid]/stack文件中应该有3个栈。但是看起来在/proc/[pid]/stack文件中只有一个栈。

我应该如何理解/proc/[pid]/stack

3个回答

6
我应该如何理解 /proc/[pid]/stack
procman页面中可以找到以下内容:
有其他有用的伪路径: [stack] 初始进程(也称为主线程)的堆栈。
紧接着是:
[stack:[tid]] (自Linux 3.4起) 线程的堆栈(其中[tid]是线程ID),对应于/proc/[pid]/task/[tid]/path。
这似乎是你要寻找的。

5
根据您的提示,我得到了答案:在Linux上,线程实际上是一个进程,因此 /proc/[tid]/stack 将获取线程的内核栈信息,或者使用 /proc/[pid]/task/[tid]/stack - Nan Xiao

1
南小是正确的。 线程内核模式堆栈在/proc/[PID]/task/[TID]/stack下。 你正在检查/proc/[PID]/stack,那是主线程堆栈,所以你只有一个。其他在任务文件夹下。

-1

这是针对睡眠锁的。您还可以查看perf -g,以查看包括高系统时间在内的自旋锁。


这个答案中的"That is for sleep locks"是指什么? - tink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接