我可以用 gdb 转储标准输入吗?
Can I dump stdin with gdb?
我正在调试一个用 C 编写的简单应用程序,并在接受用户输入的代码部分中发现了一个错误:
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:
}
这有点缩写,但关键是我正在使用 getchar() 从用户那里获取单个字符输入,然后根据该输入做出一些决定。
如果用户在 getchar() 提示时输入一个字符串,这会在程序中造成严重破坏,因为我的输入缓冲区有很多字符,并且(因为我在上面的结构上循环)每个后续循环迭代将执行剩余的字符,直到缓冲区为空。不用说,这是不受欢迎的行为。我想要用户的一个字符。我认为使用 fgets() 或通过在 getchar() 周围添加一些逻辑来确保它丢弃不需要的字符应该足够简单,只需使用第一个。
我的问题是:
我在 gdb 中调试此应用程序时是否可以转储标准输入的内容?
例如,假设我还没有弄清楚这个错误的来源,并试图弄清楚为什么当我在用户处输入 "hello world!" 时我的应用程序会吐出一堆 "garbage"提示而不是 'h'。如果我在 switch 语句之前中断,是否可以命令 gdb 转储标准输入,以便我可以看到输入缓冲区中还剩下什么(如果有的话)?
下面是我在 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
= 104 'h'
(gdb) print stdin
No symbol "stdin" in current context.
(gdb) ???
顺便说一句,这个应用示例摘自"Learn C the Hard Way"的练习19。
Is it possible to dump the contents of stdin while I am debugging this application in gdb
是的,但为此您需要了解您正在使用的 libc
的内部结构,并且您需要 libc
将调试信息编译到其中。
在 Linux 上,您将安装一个 libc6-debuginfo
或类似的软件包,然后打印 _IO_stdin
符号,该符号将包含指向包含缓冲数据的内部缓冲区的指针。
但是您使用的是 cygwin libc
,我不熟悉它的内部结构。
更新:
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?
通过预处理器运行以下源的最简单方法:
#include <stdio.h>
int main() { FILE *f = stdin; }
并查看预处理源的最后一行。如果 stdin
是 #define
d 到类似 _IO_stdin
的东西,if 将清晰可见。
我正在调试一个用 C 编写的简单应用程序,并在接受用户输入的代码部分中发现了一个错误:
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:
}
这有点缩写,但关键是我正在使用 getchar() 从用户那里获取单个字符输入,然后根据该输入做出一些决定。
如果用户在 getchar() 提示时输入一个字符串,这会在程序中造成严重破坏,因为我的输入缓冲区有很多字符,并且(因为我在上面的结构上循环)每个后续循环迭代将执行剩余的字符,直到缓冲区为空。不用说,这是不受欢迎的行为。我想要用户的一个字符。我认为使用 fgets() 或通过在 getchar() 周围添加一些逻辑来确保它丢弃不需要的字符应该足够简单,只需使用第一个。
我的问题是:
我在 gdb 中调试此应用程序时是否可以转储标准输入的内容?
例如,假设我还没有弄清楚这个错误的来源,并试图弄清楚为什么当我在用户处输入 "hello world!" 时我的应用程序会吐出一堆 "garbage"提示而不是 'h'。如果我在 switch 语句之前中断,是否可以命令 gdb 转储标准输入,以便我可以看到输入缓冲区中还剩下什么(如果有的话)?
下面是我在 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
= 104 'h'
(gdb) print stdin
No symbol "stdin" in current context.
(gdb) ???
顺便说一句,这个应用示例摘自"Learn C the Hard Way"的练习19。
Is it possible to dump the contents of stdin while I am debugging this application in gdb
是的,但为此您需要了解您正在使用的 libc
的内部结构,并且您需要 libc
将调试信息编译到其中。
在 Linux 上,您将安装一个 libc6-debuginfo
或类似的软件包,然后打印 _IO_stdin
符号,该符号将包含指向包含缓冲数据的内部缓冲区的指针。
但是您使用的是 cygwin libc
,我不熟悉它的内部结构。
更新:
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?
通过预处理器运行以下源的最简单方法:
#include <stdio.h>
int main() { FILE *f = stdin; }
并查看预处理源的最后一行。如果 stdin
是 #define
d 到类似 _IO_stdin
的东西,if 将清晰可见。