Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在Solaris上获取回溯(函数和行号)?_C_Solaris_Stack Trace_Traceback_Pstack - Fatal编程技术网

C 如何在Solaris上获取回溯(函数和行号)?

C 如何在Solaris上获取回溯(函数和行号)?,c,solaris,stack-trace,traceback,pstack,C,Solaris,Stack Trace,Traceback,Pstack,我用C编写了一些代码,很高兴地将带有函数名和行号的完整回溯发送到日志文件中 这是通过在LINUX上混合使用回溯、回溯_符号以及dladdr和ADDR2LINE完成的。在Linux上也使用“execinfo.h” 因此,基本上如下所示: 回溯:行位置: signalErrorHandler /home/lynton/Desktop/TestThreadLeak/TestThreadLeak/./main.c:211 ?? ??:0 *__GI_raise /build/buildd/eglibc-

我用C编写了一些代码,很高兴地将带有函数名和行号的完整回溯发送到日志文件中

这是通过在LINUX上混合使用回溯、回溯_符号以及dladdr和ADDR2LINE完成的。在Linux上也使用“execinfo.h”

因此,基本上如下所示:

回溯:行位置:

signalErrorHandler
/home/lynton/Desktop/TestThreadLeak/TestThreadLeak/./main.c:211
??
??:0
*__GI_raise
/build/buildd/eglibc-2.12.1/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:64
*__GI_abort
/build/buildd/eglibc-2.12.1/stdlib/abort.c:94
__libc_message
/build/buildd/eglibc-2.12.1/libio/../sysdeps/unix/sysv/linux/libc_fatal.c:168
malloc_printerr
/build/buildd/eglibc-2.12.1/malloc/malloc.c:6283
*__GI___libc_free
/build/buildd/eglibc-2.12.1/malloc/malloc.c:3739
threadMainLoop
/home/lynton/Desktop/TestThreadLeak/TestThreadLeak/./main.c:260
start_thread
/build/buildd/eglibc-2.12.1/nptl/pthread_create.c:304
??
/build/buildd/eglibc-2.12.1/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:114
现在我已经将代码带到Solaris,我发现它不受支持-(

我在Solaris上尝试了pstack方法,得到如下结果:

15871:  ./exit_test
-----------------  lwp# 1 / thread# 1  --------------------
 ffffffff7efdaf48 lwp_wait (2, ffffffff7ffffb9c)
 ffffffff7efd34ac _thrp_join (2, 0, 0, 1, 0, ffffffff7ffffb9c) + 38
 00000001000012f0 main (1, ffffffff7ffffd28, ffffffff7ffffd38, 100101f68, 100000000, ffffffff7f500200) + 204
 0000000100000ba4 _start (0, 0, 0, 0, 0, 0) + 7c
-----------------  lwp# 2 / thread# 2  --------------------
 ffffffff7efdb210 waitid   (0, 3e01, ffffffff7eaf8c30, 3)
 ffffffff7efc9cbc waitpid (3e01, ffffffff7eaf8eb0, 0, 0, ffffffff7f100300, 0) + 64
 ffffffff7efbcc08 system (ffffffff7eaf9ff0, 1ad8, 1800, 0, ffffffff7f13c000, ffffffff7eaf8f18) + 394
 0000000100000fec signalErrorHandler (b, 0, ffffffff7eafbba0, 40000000, 0, 0) + 2bc
 ffffffff7efd6fdc __sighndlr (b, 0, ffffffff7eafbba0, 100000d30, 0, 0) + c
 ffffffff7efcab70 call_user_handler (ffffffff7f500a00, ffffffff7f500a00, ffffffff7eafbba0, 12, 0, 0) + 3e0
 ffffffff7efcad7c sigacthandler (0, 0, ffffffff7eafbba0, ffffffff7f500a00, 0, ffffffff7f13c000) + 68
 --- called from signal handler with signal 0 (SIGEXIT) ---
 ffffffff7ee0052c memcpy (ffffffff7ffffd28, 1fc000, 0, 0, 100001040, 0) + 30
 ffffffff7efd6eb0 _lwp_start (0, 0, 0, 0, 0, 0)
我怎样才能以某种方式使用上面的代码以编程的方式获得行号和函数名呢?我已经看到了一些关于“walkcontext”或“walkstack”的内容……有没有人能给我一些示例代码来获取行号等

另外,我在Linux上使用了ADDR2LINE,它工作得很好……有人能从上面的转储告诉我如何在Solaris上使用它吗?我无法让它工作-(

任何建议都将不胜感激

谢谢


林顿

首先,我要说的是,在2011年,C可能不是实现这一目标的最佳方式(取决于你的更大目标)

也就是说,请在下面找到一个使用
gaddr2line
的示例(这就是Solaris的拼写方式
addr2line

这个简短的程序只调用函数
foo()
,它依次调用
pstack(1)
(在第9行,通过
system(3C)
)。在程序的输出中,
pstack(1)
告诉我们调用
system()
时,函数
foo()
中的地址是0x00010724。最后,运行
gaddr2line(1)该地址上的
告诉我们,这对应于
foo.c
的第9行,我们已经完成了完整的循环

/tmp $ cat -n foo.c
     1  
     2  #include <stdio.h>
     3  #include <stdlib.h>
     4  #include <unistd.h>
     5  
     6  int foo() {
     7      char buf[64];
     8      snprintf(buf, 64, "/bin/pstack %i", getpid());
     9      return system(buf);
    10  }
    11  
    12  int main(int argc, char *argv[]) {
    13      return foo();
    14  }
    15  
/tmp $ gcc -g -o foo foo.c
/tmp $ 
/tmp $ ./foo 
15954:  ./foo
 ff2cd4d8 waitid   (0, 3e53, ffbff668, 3)
 ff2bce94 waitpid  (3e53, ffbff7bc, 0, 0, ffbff814, ff390140) + 60
 ff2afe20 system   (ffbff910, ff339bd0, 20000, 1, ff3303d8, ffbff814) + 2ec
 00010724 foo      (209b8, 1c00, ff335900, 4, ff392a00, ff2b6d6c) + 38
 00010748 main     (1, ffbffa34, ffbffa3c, 209dc, ff3900c0, 0) + c
 00010584 _start   (0, 0, 0, 0, 0, 0) + 5c
/tmp $ 
/tmp $ gaddr2line -e foo 00010724 
/tmp/foo.c:9
/tmp $ 

谢谢你的帮助,非常感谢;-)
/tmp $ cat -n bar.c
     1  
     2  #include <stdio.h>
     3  #include <stdlib.h>
     4  #include <unistd.h>
     5  #include <ucontext.h>
     6  #include <dlfcn.h>
     7  
     8  int walker(uintptr_t pc, int sig, void *usrarg) {
     9  
    10      Dl_info dlip;
    11  
    12      if(dladdr((void *)pc, &dlip)) {
    13          (void)printf(" %08lx %s %s\n", pc, dlip.dli_fname, dlip.dli_sname);
    14          return 0;
    15      } else {
    16          perror("dladdr()");
    17          return -1;
    18      }
    19  
    20  }
    21  
    22  int bar() {
    23  
    24      char buf[64];
    25      snprintf(buf, 64, "/bin/pstack %i", getpid());
    26      system(buf);
    27  
    28      (void)printf("\nprintstack()\n");
    29      printstack(0);
    30  
    31      ucontext_t ucp;
    32      if(getcontext(&ucp)) {
    33          perror("\ngetcontext()");
    34          return -1;
    35      } else {
    36          (void)printf("\nwalkcontext()\n");
    37          return walkcontext(&ucp, &walker, NULL);
    38      }
    39  
    40  }
    41  
    42  int main(int argc, char *argv[]) {
    43      return bar();
    44  }
    45  
/tmp $ gcc -g -o bar bar.c
/tmp $
/tmp $ ./bar 
16486:  ./bar
 ff2cd4d8 waitid   (0, 4067, ffbff4b8, 3)
 ff2bce94 waitpid  (4067, ffbff60c, 0, 0, ffbff664, ff390140) + 60
 ff2afe20 system   (ffbff928, ff339bd0, 20000, 1, ff3303d8, ffbff664) + 2ec
 000108b8 bar      (20c70, 1c00, ff335900, 4, ff392a00, ff2b6d6c) + 38
 00010968 main     (1, ffbffa4c, ffbffa54, 20c94, ff3900c0, 0) + c
 00010698 _start   (0, 0, 0, 0, 0, 0) + 5c

printstack()
/tmp/bar:bar+0x54
/tmp/bar:main+0xc
/tmp/bar:_start+0x5c

walkcontext()
 00010968 /tmp/bar main
 00010698 /tmp/bar _start