在linux平台上用c/c++打印进程的所有线程堆栈跟踪

Posted

技术标签:

【中文标题】在linux平台上用c/c++打印进程的所有线程堆栈跟踪【英文标题】:print all threads stack trace of a process in c/c++ on linux platform 【发布时间】:2017-07-04 08:01:46 【问题描述】:

我想要的是获取所有线程的堆栈跟踪,以便使用 c/c++ 运行进程。

我知道获取堆栈跟踪的不同方式:

    我们有 backtrace() api,但问题是它只提供当前线程的堆栈跟踪。有谁知道如何将它与每个正在运行的线程关联起来?

    我尝试的第二种方法是使用 pstack 命令。 pstack 将输入作为正在运行的进程的 pid 显示所有线程的所有堆栈。但问题在于它不是 C/C++ api,所以我们不能在我们的代码中使用它。 (当我学习时)pstack是一个shell文件,它又使用了gdb的bt命令。

有没有人知道不同的方法可以帮助我获取所有线程的堆栈跟踪以运行进程?

【问题讨论】:

我将在gdb中使用thread apply all bt 您使用的是 pthreads 还是其他线程实现? 【参考方案1】:

也许你可以使用ptrace。附加到所有线程(打印堆栈跟踪的线程除外),您可以使用PTRACE_GETREGS 获取寄存器值。然后您可以进行堆栈展开(也许您需要存储在 .elf 文件中的信息才能可靠地执行此操作)。请注意,如果线程只是在创建/销毁其堆栈帧,则必须特别小心。您可能需要来自 elf 的调试信息才能可靠地执行此操作(如果您的代码编译时使用省略的帧指针,您肯定需要这些信息)。

手工做这件事并不容易,但肯定可以做到。

【讨论】:

谢谢您的回复,我在一个线程中使用 pthread_kill 将 SIGUSR2 发送到其他线程,当该线程接收到信号时,它会传递给用户定义的信号处理函数。在该函数中,使用 backtrace() 打印线程堆栈。

以上是关于在linux平台上用c/c++打印进程的所有线程堆栈跟踪的主要内容,如果未能解决你的问题,请参考以下文章

如何打印Linux上进程拥有的所有线程的线程ID

在 Linux 上用 C 语言读写串口

.NET跨平台实践:用C#开发Linux守护进程

.NET跨平台实践:用C#开发Linux守护进程(转)

.NET跨平台实践:用C#开发Linux守护进程-Daemon

Linux C/C++代码 使用gdb进行coredump调试