1
votes

I am debugging a simple application written in C and have found a bug in a section of code that takes user input:

char ch = getchar();  // get user choice
getchar();            // discard ENT

switch(ch) {          // switch user choice
    case -1:
        return 0;
        break;
    case 'n':
        // do something
        break;
    default:
}

This is somewhat abbreviated, but the point is that I am using getchar() to get a single character input from the user and then making some decision based on that input.

If the user enters a string when prompted by getchar() this causes havoc within the program because my input buffer has a number of characters and (as I am looping on the above structure) each subsequent loop iteration will execute on remaining characters until the buffer is empty. Needless to say, this is undesired behavior. I want one character from the user. I think it should be simple enough to fix this using fgets() or by adding some logic around getchar() that makes sure it discards unwanted characters, just using the first.

My question, using this above application as a simple example, is:

Is it possible to dump the contents of stdin while I am debugging this application in gdb?

For instance, say I had not figured out the source of this bug and was trying to figure out why my application would spit out a bunch of "garbage" when I enter "hello world!" at the user prompt instead of 'h'. If I break just before the switch statement, is it possible to command gdb to dump stdin so that I can see what (if anything) is left in the input buffer?

Below is a sample of where I would be in gdb:

Reading symbols from /cygdrive/c/Users/OwenS.BCI/Desktop/ex19.exe...done.
(gdb) break ex19.c:147
Breakpoint 1 at 0x4015b8: file ex19.c, line 147.
(gdb) run
Starting program: /cygdrive/c/Users/OwenS.BCI/Desktop/ex19.exe
[New Thread 784.0x1d98]
[New Thread 784.0xdc0]
You enter the The great hall.

> hello world!

Breakpoint 1, process_input (game=0x8003b390) at ex19.c:148
148             switch(ch) {
(gdb) print ch
$1 = 104 'h'
(gdb) print stdin
No symbol "stdin" in current context.
(gdb) ???

By the way, this application example is taken from exercise 19 of "Learn C the Hard Way".

1
Why not use fgets(s,10,stdin) and then use the first char, ch= *s;?Paul Ogilvie
Very possible, but my question is not how to fix the code. Rather, I was using it as an example to illustrate why I might want to dump stdin with gdb.Kin3TiX

1 Answers

2
votes

Is it possible to dump the contents of stdin while I am debugging this application in gdb

Yes, but to do so you need to know the internals of libc that you are using, and you need that libc to have debugging info compiled into it.

On Linux, you would install a libc6-debuginfo or similar package, then print the _IO_stdin symbol, which would contain pointers to internal buffers containing buffered data.

But you are using cygwin libc, and I am not familiar with its internals.

Update:

I believe I understand how to compile the cygwin DLL to allow debugging in it's version of libc, but any advice on how I might go about figuring out the relevant debugging symbol?

The easiest way it to run the following source through preprocessor:

#include <stdio.h>
int main() { FILE *f = stdin; }

and look at the last line of the preprocessed source. If stdin is #defined to something like _IO_stdin, if will be clearly visible.