如果发生崩溃,我们使用以下函数转储堆栈以获取有关崩溃的更多信息:
static void dumpStack()
{
char buf[64];
pid_t pid = getpid();
sprintf( buf, "%d", pid );
pid_t fork_result = vfork();
int status;
if( fork_result == 0 )
execlp( "pstack", "pstack", buf, NULL );
else if( fork_result > 0 )
waitpid( fork_result, &status, 0 );
else
std::cerr << "vfork failed with err=%s" << strerror( errno ) << std::endl;
}
在上面的代码中,父级永远停留在 waitPid 上。我检查了它变成僵尸的子进程的状态:
Deepak@linuxPC:~$ ps aux | grep 21054
700048982 21054 0.0 0.0 0 0 pts/0 Z+ 03:01 0:00 [pstack] <defunct>
另外 child 打印出来的栈也不完整。它只打印一行并退出。
#0 0x00007f61cb48d26e in waitpid () from /lib64/libpthread.so.0
不确定为什么父级无法获得进程。
如果我遗漏了什么,你能帮忙吗
最佳答案
首先,您最好使用 backtrace() 函数,请参阅 How to automatically generate a stacktrace when my program crashes
至于您的代码,如果您在 64 位 Linux 上(很可能),pstack 将无法工作。对我来说,它出现了段错误。此外,我同意对 vfork() 和 execlp() 的评论。此外,您可能需要以 root 身份执行您的程序。下面的代码对我有用(打印父级的堆栈,但不确定是否非常有用):
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <iostream>
#include <system_error>
using std::cout;
static void dumpStack() {
char buf[64];
pid_t result;
pid_t pid = getpid();
sprintf(buf, "/proc/%d/stack", pid );
//cout << buf << '\n';
pid_t fork_result = vfork();
int status;
if( fork_result == 0 ) {
//execlp( "pstack", "pstack", buf, NULL );
cout << "Child before execlp\n";
execlp("cat", "cat", buf, NULL);
cout << "Child after execlp\n"; // Will not print, of course
} else if( fork_result > 0 ) {
result = waitpid( fork_result, &status, 0 );
if (result < 0) {
throw std::system_error(errno, std::generic_category());
}
} else {
std::cerr << "vfork failed with err=%s" << strerror( errno ) << std::endl;
}
cout << std::endl;
}
int main() {
dumpStack();
return 0;
}
关于c++ - Waitpid 等待已失效的子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57919205/