Mark Galeck Mark Galeck - 3 years ago 237
Python Question

How to attach gdb to a subprocess started from Python script?

I have the following Python 3 script

foobar.py
:

#!/usr/bin/python3

import subprocess
import sys

p = subprocess.Popen(["./foobar"], stdin=subprocess.PIPE, shell=False)
sys.stdin.read(1)
p.stdin.write("f".encode())
p.stdin.flush()
sys.stdin.read(1)


which starts the program
foobar
compiled from the following file
foobar.c
with
-g
option:

foobar.c
:

#include <stdio.h>
#include <stdlib.h>

int main() {
char c;

if (EOF == scanf("%c", &c)) {
perror(NULL);
exit(1);
}

printf("received char %c\n", c);
return(0);
}


I start the script, it waits for me to enter a character, I hit
Enter
, and I get
f
:

>./foobar.py

received char f


OK, what I would like, is to inspect
foobar
with the debugger
gdb
. That is what
sys.stdin.read(1)
is for: I hoped to start

>./foobar.py


and then, in another terminal, find out the process id of
foobar
, and run

>gdb attach
pid
-ex='b foobar.c:12'


then I was hoping to hit
Enter
in the first terminal as before, and then the C program would eat the input and stop at the line 12, which is
printf
, as requested.

But it does not work this way - I hit
Enter
and nothing happens, the program
foobar
does not budge, it still waits at
scanf
.

How to do it so that I can stop at
printf
?

Answer Source

How to do it so that I can stop at printf ?
gdb attach pid -ex='b foobar.c:12'

It's not clear what the exact meaning of gdb attach pid -ex ... is.

Did you forget to continue the inferior process (which is stopped by GDB attaching to it)?

This worked perfectly fine for me:

$ gdb -q -ex "attach $(pidof foobar)" -ex 'break foobar.c:12' -ex continue
Attaching to process 88748
Reading symbols from /tmp/stdin/foobar...done.
0x00007f9b78811330 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
Breakpoint 1 at 0x400664: file foobar.c, line 12.
Continuing.

... GDB just sits here (as expected). After I hit Enter in the foobar.py window:

Breakpoint 1, main () at foobar.c:12
12      printf("received char %c\n", c);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download