2

I have the following code (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);
}

I compile with gcc -g main.c -o main -lpthread. I am using GDB for debugging. What I want is to place a breakpoint at the second line of PrintHello, i.e. at tid = (long)threadid, and have the execution stop there (whatever the thread) and let me do stuff like look at the value of variable threadid.

I want to achieve this in Emacs' GDB implementation - which we may assume for the purposes of this question as simply GDB (don't worry that it's run inside Emacs). So far I can place the breakpoint at the desired line, and sometimes the little arrow showing the current line where the program is at does indeed stop at this line:

arrow

However when I type into the GDB prompt print threadid I get back No symbol "threadid" in current context. and the arrow jumps immediately to some breakpoint that I set in main():

im2

My guess is that this occurs because the "pausing" of program execution happens for the main thread, which is not the thread running PrintHello. PrintHello is run by thread t - since this is not the thread paused by GDB, it prints the hello world message and exists immediately. By the time I get around to typing print threadid, this thread is already dead and the program is back in main()... hence the effect.

I tried to resolve this by typing something like break <LineNumber> thread <ThreadID> but this is no good since in this program the created threads last for a split second. So I am never actually at a point where info thread shows anything except the main thread. It's simply not humanly possible to "catch" the program at a point where there is the main thread and a newly created thread running PrintHello - since this situation lasts for I guess a few microseconds.

Please help me to achieve this simple debug objective of halting execution of whatever thread is executing PrintHello at the line tid = (long)threadid;.

asked Dec 21, 2016 at 15:50

1 Answer 1

1

Solved it, there wasn't much a problem after all. Here are instructions, if anyone has a similar issue:

  1. Compile with gcc -ggdb main.c -o main -lpthread (yes, that's -ggdb and not -g, it appears to make a difference)
  2. Run the debugger with gdb main or, in Emacs, with M-x gdb (and the command gdb -i=mi main)
    • Hugely important here: Emacs has by default the variable gdb-non-stop-setting set to t, which means it tries to run GDB in non-stop mode. According to docs, this is NOT what I want - I want all-stop mode. Thus, either do a set-variable or put (setq gdb-non-stop-setting nil) in your init file (e.g. ~/.emacs.d/init.el). Only once this is done should you launch M-x gdb from inside Emacs...
  3. (gdb) b 9 to set the breakpoint to line 9
  4. (gdb) r to run the program. Execution will stop when one of the threads reaches line 9, i.e. tid = (long)threadid;. All other threads will also stop! Perfect!
  5. (gdb) c to continue. Execution will stop when another thread reaches line 9. Great!
  6. Continue doing whatever, we have the desired behavior now :)
answered Dec 21, 2016 at 17:21
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.