如何使用gdb从不同的线程获取ruby backtrace

时间:2018-02-26 02:56:14

标签: ruby gdb ruby-thread

我有一个产生两个线程的ruby程序。很少,它似乎挂在主线上,我试图用gdb来找出原因。

使用博文here,我使用gdb附加到流程,并调用rb_backtrace()来获取回溯。

问题是,回溯总是来自其中一个生成的工作线程,而不是我遇到挂起的主线程。

有没有办法从特定线程获得回溯?

我尝试使用gdb命令info threadsthread 2来更改活动线程,但它没有任何效果。我也尝试在gdb中使用ruby_eval定义,如here所述,但每当我尝试评估一行ruby代码时,我都会收到错误No symbol table is loaded. Use the "file" command.因为我正在处理嵌入式系统,我不能轻易地用gdb符号重新编译ruby。

1 个答案:

答案 0 :(得分:2)

rb_backtrace() 指的是您可以覆盖的全局 ruby_current_thread 变量:

# Make a note of the old thread pointer so you can put it back.
(gdb) p ruby_current_thread
$1 = (rb_thread_t *) 0x5619dfe485e0

(gdb) set ruby_current_thread = 0x5619efb7d3a0

(gdb) p ruby_current_thread
$2 = (rb_thread_t *) 0x5619efb7d3a0

# Write the backtrace to stderr
(gdb) call (void) rb_backtrace()

ruby 线程指针(上面的0x5619efb7d3a0)可以在您感兴趣的本地线程的 GDB 回溯中找到,例如。

#7  0x00005619de86cf96 in vm_exec (th=th@entry=0x5619efb7d3a0) at vm.c:1693

在让进程恢复之前将 ruby_current_thread 设置回其原始值。在 Ruby 2.3.8 上测试。