【问题标题】:GDB breakpoint in routine of a simple Pthread?简单Pthread例程中的GDB断点?
【发布时间】:2016-12-22 01:21:22
【问题描述】:

我有以下代码 (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,并让执行停止在那里(无论线程),让我做一些事情,比如查看变量 threadid 的值。

我想在 Emacs 的 GDB 实现中实现这一点——出于这个问题的目的,我们可以假设它只是 GDB(不要担心它在 Emacs 中运行)。到目前为止,我可以将断点放在所需的行,有时显示程序所在行的小箭头确实会停在这一行:

但是,当我在 GDB 提示符 print threadid 中输入时,我会返回 No symbol "threadid" in current context.,并且箭头会立即跳转到我在 main() 中设置的某个断点:

我的猜测是,这是因为程序执行的“暂停”发生在主线程上,而不是运行PrintHello 的线程。 PrintHello 由线程 t 运行 - 因为这不是 GDB 暂停的线程,所以它打印 hello world 消息并立即存在。当我开始输入 print threadid 时,这个线程已经死了,程序又回到了 main()... 因此效果。

我试图通过输入break &lt;LineNumber&gt; thread &lt;ThreadID&gt; 之类的内容来解决这个问题,但这并不好,因为在这个程序中,创建的线程会持续一瞬间。所以我实际上从来没有处于info thread 显示除主线程之外的任何内容的地步。在主线程和新创建的线程运行 PrintHello 的点上“捕获”程序是人类不可能的——因为我猜这种情况会持续几微秒。

请帮助我实现这个简单的调试目标,即在tid = (long)threadid; 行停止执行正在执行的任何线程PrintHello

【问题讨论】:

    标签: c debugging gdb pthreads


    【解决方案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-settingset 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. 继续做任何事情,我们现在有所需的行为:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      相关资源
      最近更新 更多