GDB Remote Debug

1. Usages

1.1. Launch Program

Launch a proram under gdbserver control.

    gdb connection program args...

Sample: Server starts ls program. Client connect to debug.

Server

gdbserver localhost:12345 ls
  

Client

(gdb) file ls
(gdb) target remote localhost:12345
  

1.2. Attach to Running Process

Attach gdbserver to a running process.

    gdb --attach connection pid

Sample: Server attachs to running vim process. Client connect to debug.

Server

vim
gdbserver --attach :12345 19832
  

Client

(gdb) file vim
(gdb) target remote :12345
  

1.3. Multi Mode

Start gdbsever in multi mode

    gdbserver --multi connection

Sample: Server starts in multi mode.

vim
gdbserver --multi :12345
  

Client runs vim program.

(gdb) target extended-remote :12345
(gdb) set remote exec-file vim
(gdb) start
(gdb) monitor exit
  

Client attachs to a running process.

(gdb) target extended-remote :12345
(gdb) attach 19832
(gdb) monitor exit
  

2. Applications

2.1. Debug Program Started By SystemD

2.1.1. Program

File /opt/demo/main.c.

#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>

int main(int argc, char** argv)
{
        openlog("main", LOG_PID | LOG_CONS, LOG_USER);
        syslog(LOG_INFO, "started");

        int n = 0;
        while (1)
        {
                syslog(LOG_INFO, "running... %d", n);
                n += 1;
                sleep(3);
        }

        closelog();
        return 0;
}
$ gcc -g main.c -o main

File /opt/demo/control.sh.

#!/bin/bash

start() {
    start-stop-daemon --start --background \
        --make-pidfile --pidfile /var/run/demo.pid \
        --exec /opt/demo/main
}

stop() {
    start-stop-daemon --stop --pidfile /var/run/demo.pid
}

case $1 in
    start)
        start;;
    stop)
        stop;;
    *)
        echo 'Usage: control.sh {start|stop}'
        exit 1;;
esac

exit 0

File /etc/systemd/system/demo.service.

Description=Demo Service
ExecStart=/opt/demo/control.sh start
ExecStop=/opt/demo/control.sh stop
Type=forking

2.1.2. Debug

Modify start() to launch the program with gdbserver.

start() {
    start-stop-daemon --start --background \
        --make-pidfile --pidfile /var/run/demo.pid \
        --exec /usr/bin/gdbserver localhost:5555 /opt/demo/main
}
$ gdb
(gdb) set tcp auto-retry on
(gdb) set tcp connect-timeout unlimited
(gdb) target remote localhost:5555
$ systemctl start demo
(gdb) info inferiors
  Num  Description       Connection                         Executable        
* 1    process 86099     1 (extended-remote localhost:5555) target:/opt/demo/main
(gdb) break main
Breakpoint 1 at 0x55555555519c: file main.c, line 7.

(gdb) continue
Continuing.
Breakpoint 1, main (argc=1, argv=0x7fffffffec78) at main.c:7
7               openlog("main", LOG_PID | LOG_CONS, LOG_USER);
(gdb) detach
Detaching from program: target:/opt/demo/main, process 86099
[Inferior 1 (process 86099) detached]