GDB & Multiple Threads

1. Thread Control

  
info threads
  
  
thread
  
  
thread <tid>
  
  
thread apply <tids> command

thread apply all command
  
  
set debug threads [on|off]
  

When set to ‘on’, GDB prints extra messages whenever threads are created or destroyed. If you press Ctrl+C to interrupt the target process, the process is not terminated immediately. Instead, the SIGINT is delivered to GDB, allowing you to decide whether to resume or terminate the target process.

2. Non-stop Mode

2.1 Enable & Disable

  
set non-stop [on|off]
show non-stop
  
  
set pagination off
set non-stop on
  
  
$ gdb -ex "set non-stop on" -ex "attach <pid>"
  

2.2 Continue & Interrupt

  
continue
continue -a
  
  
interrupt
interrupt -a
  

3. Asynchronous Execution

GDB has two ways to run programs: synchronous (foreground) and asynchronous (background).

Synchronous execution is especially useful in conjunction with non-stop mode for debugging programs with multiple threads.

  
continue &
continue -a &
  

4. Lab

  
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define NUM_THREADS 4

void* child_thread(void* arg) {
    while (1) {
        printf("Child thread, tid 0x%lx\n", pthread_self());
        sleep(7);
    }
    return NULL;
}

int main() {
    pthread_t tids[NUM_THREADS];
    for (int i = 0; i < NUM_THREADS; i++)
        pthread_create(&tids[i], NULL, child_thread, NULL);

    while (1) {
        printf("Main thread, tid %lu\n", pthread_self());
        sleep(11);
    }
    return 0;
}
  
  
$ gcc -g -o demo demo.c -pthread
  
  
./demo
  
  
$ gdb -ex "set non-stop on" -ex "attach `pidof demo`"
  
  
(gdb) show non-stop 
Controlling the inferior in non-stop mode is on.
  
  
(gdb) continue -a &

(gdb) info thread
  Id   Target Id                                Frame 
* 1    Thread 0x7f5705c93740 (LWP 33038) "demo" (running)
  2    Thread 0x7f5705c92640 (LWP 33039) "demo" (running)
  3    Thread 0x7f5705491640 (LWP 33040) "demo" (running)
  4    Thread 0x7f5704c90640 (LWP 33041) "demo" (running)
  5    Thread 0x7f570448f640 (LWP 33042) "demo" (running)
  
  
(gdb) thread 3
[Switching to thread 3 (Thread 0x7f5705491640 (LWP 33040))](running)

(gdb) interrupt
Thread 3 "demo" stopped.
0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5705490e00, rem=rem@entry=0x7f5705490e00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78      in ../sysdeps/unix/sysv/linux/clock_nanosleep.c

(gdb) info thread
  Id   Target Id                                Frame 
  1    Thread 0x7f5705c93740 (LWP 33038) "demo" (running)
  2    Thread 0x7f5705c92640 (LWP 33039) "demo" (running)
* 3    Thread 0x7f5705491640 (LWP 33040) "demo" 0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5705490e00, rem=rem@entry=0x7f5705490e00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
  4    Thread 0x7f5704c90640 (LWP 33041) "demo" (running)
  5    Thread 0x7f570448f640 (LWP 33042) "demo" (running)
  
  
(gdb) thread 3
[Switching to thread 3 (Thread 0x7f5705491640 (LWP 33040))]
#0  0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5705490e00, rem=rem@entry=0x7f5705490e00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78      in ../sysdeps/unix/sysv/linux/clock_nanosleep.c

(gdb) continue &
Continuing.
  
  
(gdb) interrupt -a
Thread 3 "demo" stopped.
0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5705490e00, rem=rem@entry=0x7f5705490e00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78      in ../sysdeps/unix/sysv/linux/clock_nanosleep.c

Thread 5 "demo" stopped.
0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f570448ee00, rem=rem@entry=0x7f570448ee00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78      in ../sysdeps/unix/sysv/linux/clock_nanosleep.c

Thread 1 "demo" stopped.
0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fff0bbb3d70, rem=rem@entry=0x7fff0bbb3d70) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78      in ../sysdeps/unix/sysv/linux/clock_nanosleep.c

Thread 4 "demo" stopped.
0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5704c8fe00, rem=rem@entry=0x7f5704c8fe00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78      in ../sysdeps/unix/sysv/linux/clock_nanosleep.c

Thread 2 "demo" stopped.
0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5705c91e00, rem=rem@entry=0x7f5705c91e00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78      in ../sysdeps/unix/sysv/linux/clock_nanosleep.c

(gdb) thread 2
[Switching to thread 2 (Thread 0x7f5705c92640 (LWP 33039))]
#0  0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5705c91e00, rem=rem@entry=0x7f5705c91e00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
78      in ../sysdeps/unix/sysv/linux/clock_nanosleep.c

(gdb) continue &
Continuing.

(gdb) info threads
  Id   Target Id                                Frame 
  1    Thread 0x7f5705c93740 (LWP 33038) "demo" 0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7fff0bbb3d70, rem=rem@entry=0x7fff0bbb3d70) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
* 2    Thread 0x7f5705c92640 (LWP 33039) "demo" (running)
  3    Thread 0x7f5705491640 (LWP 33040) "demo" 0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5705490e00, rem=rem@entry=0x7f5705490e00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
  4    Thread 0x7f5704c90640 (LWP 33041) "demo" 0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f5704c8fe00, rem=rem@entry=0x7f5704c8fe00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
  5    Thread 0x7f570448f640 (LWP 33042) "demo" 0x00007f5705d7b7f8 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7f570448ee00, rem=rem@entry=0x7f570448ee00) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
  

References