ThreadStacks - C/C++ 进程堆栈追踪库


MIT
跨平台
C/C++

软件简介

ThreadStacks 可用于检查与 ThreadStacks 库链接的活动进程的所有线程。粗略地说,ThreadStacks 为C / C ++
程序提供了相当于 Golang 的 runtime.Stack()。除了编程访问堆栈跟踪之外,ThreadStacks 还提供了 jmap
样式实用程序,其中 kill -35 可用于让实时进程将其所有线程的堆栈跟踪写入 stderr。

ThreadStacks 是适用于测试和生产环境的主要调试工具,它帮助调试堆栈中某些最关键服务的各种问题,包括内存数据库和集群管理器。

设计思路

以下步骤来收集线程的堆栈跟踪:

  1. 找到正在运行的线程列表(T1,T2,T3)。这是通过让’/ proc / self / task’目录的子目录完成的。

  2. 为每个线程分配一个内存插槽以写入其堆栈跟踪(M1,M2,M3)。请注意,从信号处理程序分配内存不是异步信号安全的,因此预先分配内存。

  3. 发送实时信号给每个发现的线程并等待他们的应答。相应的存储器插槽和ack文件描述符是实时信号有效负载的一部分。

  4. 线程的信号处理程序使用 libunwind 来计算它们的堆栈跟踪,并在各自的内存插槽中写入基于原始指令指针的堆栈跟踪。

  5. 在将堆栈跟踪写入指定的内存插槽后,每个线程都会通过管道回退到收集器线程。

  6. 在接收到所有 acks(与步骤#1中检测到的线程数相同)后,收集器线程将对栈跟踪进行唯一化和符号化。

使用

进程可以链接到 ThreadStacks 库并安装’StackTraceSignal’类中定义的两个信号处理程序,以便能够实时检查其堆栈跟踪:

thoughtspot::StackTraceSignal::InstallInternalHandler()
thoughtspot::StackTraceSignal::InstallExternalHandler()

在安装了上述两个信号处理器之后,’StackTraceCollector’类可以用来收集堆栈跟踪,例如,来自REST处理程序。

构建

ThreadStacks 使用 bazel 作为其构建系统,并依赖于’glog’、’gflags’和’googletests’项目作为远程 bazel
项目。

bazel build //threadstacks/...

测试:

bazel test //...