有时无法从/ proc / self / maps获得堆栈范围

时间:2014-11-13 16:27:34

标签: c++ c multithreading unix stack

我有一个问题。我试图从/ proc / self / maps pseudofile获得堆栈偏移范围。但我有时会有奇怪的事情。 这是我的代码

 fp = fopen("/proc/self/maps", "r");
    if (fp == NULL) {
        perror("Error opening file");
        return NULL;
    }
    while (fgets(line, 2048, fp) != NULL) {
        if (strstr(line, "stack") != NULL) {
            printf("%s", line);
        }
 }

如果您使用一个或多个线程启动程序,您可以查看此伪文件并获得类似这样的内容

7f20423a6000-7f2042ba6000 rw-p 00000000 00:00 0                          [stack:3936]
7fffbe95e000-7fffbe97f000 rw-p 00000000 00:00 0                          [stack]

这里的第一行是堆栈的线程,第二行是进程的堆栈。 但问题是有时我无法获得堆栈线程。它可能是第一次出现或出现在下一次执行中,因此无法确定。在某些方面,它根本没有显示堆栈的线程,我不认为问题在于发行版中伪文件的不同实现,而在其他方面。 请帮助解决这个问题

修改

我实际上在线程中调用了这个函数,所以我通过pthread_create(&tid, NULL, proc_stack, NULL);创建线程我一直在考虑这个问题。也许在线程启动后需要一些时间来更新这个伪文件,这只是我在这里看到的一个原因。

EDIT2

我试图强行打电话给睡眠,但这并没有帮助,但最奇怪的是,在一个发行版上它显示了线程堆栈,在另一个发行版上没有。

1 个答案:

答案 0 :(得分:1)

在我的系统上您的程序还没有显示第二个堆栈段,但似乎在 [heap] 上方分配了5个段,其中一个被使用对于线程堆栈(proc_stack()的局部变量存储在此段中)。

我用来检查代码(test.c):

#include <stdio.h>
#include <string.h>
#include <pthread.h>

void* proc_stack(void* p){
   FILE *fp;
   char line[2048];
   fp = fopen("/proc/self/maps", "r");
   if (fp == NULL) {
      perror("Error opening file");
      return NULL;
   }
   while (fgets(line, 2048, fp) != NULL) {
//      if (strstr(line, "stack") != NULL) {
         printf("%s", line);
//      }
   }
   printf("addr = %p %p\n", &fp, &line);
   return NULL;
}

int main(){
   pthread_t tid;
   void *rv;
   proc_stack( NULL );
   puts("main");
   pthread_create( &tid, NULL, proc_stack, NULL );
   pthread_join( tid, &rv );
   return 0;
}

gcc -Wall test.c -pthread一起编译。结果(删除了一些行):

...
01933000-01954000 rw-p 00000000 00:00 0                                  [heap]
...
7fff75be3000-7fff75c04000 rw-p 00000000 00:00 0                          [stack]
7fff75d97000-7fff75d98000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
addr = 0x7fff75c00e68 0x7fff75c00e70
main
...
01933000-01954000 rw-p 00000000 00:00 0                                  [heap]
7f3be0000000-7f3be0021000 rw-p 00000000 00:00 0 
7f3be0021000-7f3be4000000 ---p 00000000 00:00 0 
7f3be6b79000-7f3be6b7a000 rw-p 00000000 00:00 0 
7f3be6b7a000-7f3be6b7b000 ---p 00000000 00:00 0 
7f3be6b7b000-7f3be737b000 rw-p 00000000 00:00 0 
...
7fff75be3000-7fff75c04000 rw-p 00000000 00:00 0                          [stack]
7fff75d97000-7fff75d98000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
addr = 0x7f3be73796c8 0x7f3be73796d0