微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

你如何以编程方式从父级获取subprocess的堆栈跟踪?

假设我在程序中分支了一个subprocess。 在某个时候,我用kill(child,SIGSTOP)暂停subprocess,并想检查栈的内容。 有没有办法以编程方式从父级获取subprocess的堆栈跟踪?

我知道ptrace是追踪subprocess并检查其内存/寄存器的标准方式。 我也知道backtrace为调用线程提供了这个function。 有没有合并这些function的函数或库? 或者我需要手动走栈与ptrace ?

C ++内存泄漏检测方法

什么是linux命令来获得正在运行的进程的堆栈,而不必在debugging器中附加它?

Stack Walker for x64 Windows

从未捕获的exception获取堆栈跟踪?

如何在Windows上以编程方式从转储文件获取堆栈跟踪

回答我自己的问题 – 这是可行的。 你需要libunwind和ptrace 。 libunwind为ptrace提供了一个包装器,允许您展开远程目标。 以下是示例代码,运行NPB基准(cg,A类):

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <wait.h> #include <sys/ptrace.h> #include <libunwind.h> #include <libunwind-x86_64.h> #include <libunwind-ptrace.h> #include <signal.h> #define panic(X) fprintf(stderr,#X "n"); static unw_addr_space_t as; static struct UPT_info *ui; void do_backtrace(pid_t child) { ui = _UPT_create(child); if (!ui) { panic("_UPT_create Failed"); } ptrace(PTRACE_ATTACH,child,0); struct timespec t = { .tv_sec = 0,t.tv_nsec = 1000000 }; nanosleep(&t,NULL); unw_cursor_t c; int rc = unw_init_remote(&c,as,ui); if (rc != 0) { if (rc == UNW_EINVAL) { panic("unw_init_remote: UNW_EINVAL"); } else if (rc == UNW_EUNSPEC) { panic("unw_init_remote: UNW_EUNSPEC"); } else if (rc == UNW_EBADREG) { panic("unw_init_remote: UNW_EBADREG"); } else { panic("unw_init_remote: UNKNowN"); } } do { unw_word_t offset,pc; char fname[64]; unw_get_reg(&c,UNW_REG_IP,&pc); fname[0] = ''; (void) unw_get_proc_name(&c,fname,sizeof(fname),&offset); printf("n%p : (%s+0x%x) [%p]n",(void *)pc,(int) offset,(void *) pc); } while (unw_step(&c) > 0); ptrace(PTRACE_DETACH,0); _UPT_destroy(ui); } int main(int argc __attribute__((unused)),char **argv,char **envp) { as = unw_create_addr_space(&_UPT_accessors,0); if (!as) { panic("unw_create_addr_space Failed"); } pid_t child; child = fork(); if (!child) { execve("/home/#######/#######/my_utilities/child_bt/cg.Ax",argv,envp); return 0; } else { struct timespec t = { .tv_sec = 1,.tv_nsec = 0 }; nanosleep(&t,NULL); do_backtrace(child); int status; waitpid(child,&status,0); } return 0; }

输出

#######-######-desktop:~/popcorn/my_utilities/child_bt$ ./child_bt NAS Parallel Benchmarks (NPB3.3-SER) - CG Benchmark Size: 14000 Iterations: 15 Initialization time = 0.422 seconds iteration ||r|| zeta 1 0.26065081214763E-12 19.9997581277040 2 0.25753187736717E-14 17.1140495745506 3 0.25934878907518E-14 17.1296668946143 4 0.25626292684826E-14 17.1302113581193 5 0.25110613524700E-14 17.1302338856353 6 0.25581937582088E-14 17.1302349879482 7 0.25456477041068E-14 17.1302350498916 8 0.24494068328538E-14 17.1302350537510 0x400c85 : (conj_grad_+0x135) [0x400c85] 0x401ec8 : (MAIN__+0x739) [0x401ec8] 0x402b39 : (main+0x1d) [0x402b39] 0x7f8ee80c2ec5 : (__libc_start_main+0xf5) [0x7f8ee80c2ec5] 0x400a89 : (_start+0x29) [0x400a89] 9 0.24885235903729E-14 17.1302350540101 10 0.24771507610856E-14 17.1302350540284 11 0.24928441017003E-14 17.1302350540298 12 0.24443706061229E-14 17.1302350540299 13 0.24709361922612E-14 17.1302350540299 14 0.24381630450112E-14 17.1302350540299 15 0.24296673223448E-14 17.1302350540299 Benchmark completed VERIFICATION SUCCESSFUL Zeta is 0.1713023505403E+02 Error is 0.5122640033228E-13 CG Benchmark Completed. Class = A Size = 14000 Iterations = 15 Time in seconds = 1.01 Mop/s total = 1483.11 Operation type = floating point Verification = SUCCESSFUL Version = 3.3.1 Compile date = 16 Jul 2015 Compile options: F77 = gfortran FLINK = $(F77) F_LIB = (none) F_INC = (none) FFLAGS = -O FLINKFLAGS = -O RAND = randi8 Please send all errors/Feedbacks to: NPB Development Team [email protected]

我基于libunwind发行版的tests文件夹中的test-ptrace.c文件中的do_backtrace函数以及此博客中的代码

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐