你好,有必要学习如何通过gdb调试多线程应用程序......假设有这样一个应用程序有几个线程:
int main() {
static int i =0;
std::thread([](){ while(true) { ++i; std::this_thread::sleep_for( std::chrono::milliseconds(700)); std::cout << "hello\n";}}).detach();
std::thread([](){ while(true) { std::this_thread::sleep_for(std::chrono::milliseconds(600)); std::cout << "my\n";}}).detach();
std::thread([](){ while(true) { std::this_thread::sleep_for(std::chrono::milliseconds(900)); std::cout << "world\n";}}).detach();
std::thread([](){ while(true) { std::this_thread::sleep_for(std::chrono::milliseconds(700)); std::cout << "ro\n";}}).join();
}
连接 gdb -p number_of_pid 进程:
Type "apropos word" to search for commands related to "word".
Attaching to process 9208
[New LWP 9209]
[New LWP 9210]
[New LWP 9211]
[New LWP 9212]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
0x00007f1bae990acd in pthread_join () from /lib64/libpthread.so.0
并且应用程序停止...告诉我如何在调试器中查看变量 i 的值,如果我们一附加 gdb,那么一切都停止,如果我们接下来执行,那么假设某行中的 br,然后n,然后一切顺利 和以前一样,变量 i 的值(通过打印)无法显示...
给年轻情妇的基本注意事项
对于调试(至少对于舒适的调试),有必要使用调试信息进行构建,在 gcc 中,密钥用于
-g
:您可以立即在 gdb 下启动该进程:
或绑定到已经运行的进程:
在第一种情况下,启动调试器后,必须使用命令
run
或启动进程本身r
可以随时
SIGINT
使用 'om 或换句话说Ctrl+暂停该过程C。定义设置
在任意点停止后,值得看看我们在哪里,为此有命令
backtrace
(b
) 和info threads
(i th
)如您所见,gdb 现在位于
pthread_join()
主线程的上下文中。堆栈框架变化和可变打印
要打印变量(
print
),您需要切换到它所在的框架,为此有一个命令frame
(f
),同时您可以看到列表(list
):其中 2 in
frame 2
是输出中感兴趣的帧的数量bt
。单步穿流
要逐步调试特定线程,您需要使用命令
thread
(thr
) 将 gdb 切换到其上下文:每个线程都有自己的栈,所以再看一遍也不会是多余的
backtrace
,如果有必要,跳转到想要的帧。之后,您可以使用
next
/step
(n
/s
) 以通常的方式调试流:有几点值得一提:
n
所有线程都立即启动,因此您几乎可以在每个命令之后看到额外的输出。对于后续阅读/查看,我推荐至少入门“使用 GDB 调试”