我有以下代码(source):
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid) {
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld\n", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
pthread_t threads[NUM_THREADS];
int rc;
long t;
for (t=0; t<NUM_THREADS; t++) {
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
// wait for all threads to die
pthread_exit(NULL);
}
我使用gcc -g main.c -o main -lpthread
进行编译。我正在使用GDB进行调试。我想要的是在PrintHello的第二行放置一个断点,即在tid = (long)threadid
,并在那里执行停止(无论线程是什么)让我做一些事情,比如查看变量{{1}的值}。
我想在Emacs&#39;中实现这一目标。 GDB实现 - 我们可以将此问题视为简单的GDB(不要担心它在Emacs中运行)。到目前为止,我可以将断点放在所需的行上,有时显示程序所在的当前行的小箭头确实停在此行:
然而,当我输入GDB提示符threadid
时,我返回print threadid
并且箭头立即跳转到我在main()中设置的某个断点:
我猜这是因为&#34;暂停&#34;程序执行发生在主线程上,而不是运行No symbol "threadid" in current context.
的线程。 PrintHello
由线程PrintHello
运行 - 因为这不是GDB暂停的线程,它会打印hello world消息并立即存在。当我开始输入t
时,这个线程已经死了,程序又回到了main()...因此效果。
我尝试通过键入类似print threadid
的内容来解决此问题,但这并不好,因为在此程序中,创建的线程持续一秒钟。所以我实际上从来没有break <LineNumber> thread <ThreadID>
显示除主线程之外的任何内容。只是没有人类可能抓住&#34;该程序存在主线程和新创建的线程运行info thread
- 因为这种情况持续了几个微秒。
请帮助我实现这个简单的调试目标,即停止执行PrintHello
行PrintHello
处执行的任何线程。
答案 0 :(得分:1)
解决了它,毕竟没有太大的问题。以下是说明,如果有人有类似的问题:
gcc -ggdb main.c -o main -lpthread
汇编(是的,那是-ggdb
而不是-g
,似乎有所作为)gdb main
运行调试器,或者在Emacs中运行M-x gdb
(以及命令gdb -i=mi main
)
gdb-non-stop-setting
set to t
,这意味着它尝试以非停止模式运行GDB。根据文档,这不是我想要的 - 我想要全停模式。因此,要么在您的初始文件中执行set-variable
或放置(setq gdb-non-stop-setting nil)
(例如~/.emacs.d/init.el
)。只有在完成此操作后,才能从Emacs ... M-x gdb
(gdb) b 9
将断点设置为第9行(gdb) r
运行程序。当其中一个线程到达第9行时执行将停止,即tid = (long)threadid;
。所有其他线程也将停止!完美!(gdb) c
继续。当另一个线程到达第9行时,执行将停止。很棒!