1

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 attachpid-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 ?

6
  • you have to send p.stdin.write("f\n".encode()). Alternately p.stdin.close(). That should work. Commented Oct 1, 2017 at 15:25
  • @Jean-FrançoisFabre well, that's cheating... I can't do that. I have the programs foobar.py and foobar.c as given, and they work as shown above. So, they should also work under the debugger - I can insert sys.stdin.read(1) to "stop" so I can attach the debugger, but that's all I can do. I can't go around and change other things. That is the whole point of using the debugger, rather than inserting "print" statements, that you don't change your code. The code above is just an SSCCE, you understand? The "real" code is far bigger. Commented Oct 1, 2017 at 15:28
  • not that's not: scanf expects a char + linefeed. So it's not possible to make those both work with the .py and .c code. you can challenge anyone here to make that work, not possible, because of the way scanf processes input. Commented Oct 1, 2017 at 15:32
  • @Jean-FrançoisFabre what do you mean - I did get them to work, just like I shown above. It's not about challenging or arguing, it's about checking one's question prior to posting. Commented Oct 1, 2017 at 15:39
  • the problem is that gdb prevents the stream to be closed. by starting without gdb, the input stream is closed & flushed and the C program recieves f+EOF. With the debugger, it doesn't receive EOF or linefeed. Commented Oct 1, 2017 at 16:56

1 Answer 1

1

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);
Sign up to request clarification or add additional context in comments.

3 Comments

"did you forget to continue" - well I assumed, that since the process was already running, it does not get "stopped", is that right, does it get stopped by gdb attaching while it is running?
When you see the (gdb) prompt, the inferior process is stopped (at least in default all-stop mode). And yes, gdb -ex "attach ..." will immediately stop the attached-to process.
thank you ! that was it, I did not realize, I needed -ex continue . Previously, I did use continue and the whole thing fell through, without stopping at all, I must have done something else wrong. Now, I do it and "somehow" it works.

Your Answer

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.