简单Pthread的例程中的GDB断点?

时间:2016-12-21 15:50:46

标签: c debugging gdb pthreads

我有以下代码(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中运行)。到目前为止,我可以将断点放在所需的行上,有时显示程序所在的当前行的小箭头确实停在此行:

arrow

然而,当我输入GDB提示符threadid时,我返回print threadid并且箭头立即跳转到我在main()中设置的某个断点:

im2

我猜这是因为&#34;暂停&#34;程序执行发生在主线程上,而不是运行No symbol "threadid" in current context.的线程。 PrintHello由线程PrintHello运行 - 因为这不是GDB暂停的线程,它会打印hello world消息并立即存在。当我开始输入t时,这个线程已经死了,程序又回到了main()...因此效果。

我尝试通过键入类似print threadid的内容来解决此问题,但这并不好,因为在此程序中,创建的线程持续一秒钟。所以我实际上从来没有break <LineNumber> thread <ThreadID>显示除主线程之外的任何内容。只是没有人类可能抓住&#34;该程序存在主线程和新创建的线程运行info thread - 因为这种情况持续了几个微秒。

请帮助我实现这个简单的调试目标,即停止执行PrintHelloPrintHello处执行的任何线程。

1 个答案:

答案 0 :(得分:1)

解决了它,毕竟没有太大的问题。以下是说明,如果有人有类似的问题:

  1. gcc -ggdb main.c -o main -lpthread汇编(是的,那是-ggdb而不是-g,似乎有所作为)
  2. 使用gdb main运行调试器,或者在Emacs中运行M-x gdb(以及命令gdb -i=mi main
    • 非常重要:默认情况下,Emacs有变量gdb-non-stop-setting set to t,这意味着它尝试以非停止模式运行GDB。根据文档,这不是我想要的 - 我想要全停模式。因此,要么在您的初始文件中执行set-variable或放置(setq gdb-non-stop-setting nil)(例如~/.emacs.d/init.el)。只有在完成此操作后,才能从Emacs ...
    • 中启动M-x gdb
  3. (gdb) b 9将断点设置为第9行
  4. (gdb) r运行程序。当其中一个线程到达第9行时执行将停止,即tid = (long)threadid;。所有其他线程也将停止!完美!
  5. (gdb) c继续。当另一个线程到达第9行时,执行将停止。很棒!
  6. 继续做任何事情,我们现在有了理想的行为:)