C 我可以用gdb转储stdin吗?

C 我可以用gdb转储stdin吗?,c,debugging,gdb,stdin,C,Debugging,Gdb,Stdin,我正在调试一个用C编写的简单应用程序,在接受用户输入的代码部分发现了一个bug: char ch = getchar(); // get user choice getchar(); // discard ENT switch(ch) { // switch user choice case -1: return 0; break; case 'n': // do something

我正在调试一个用C编写的简单应用程序,在接受用户输入的代码部分发现了一个bug:

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中调试此应用程序时,是否可以转储stdin的内容?

例如,假设我没有找出这个bug的来源,并且试图弄清楚为什么我的应用程序在用户提示下输入“helloworld!”而不是“h”时会吐出一堆“垃圾”。如果我在switch语句之前中断,是否可以命令gdb转储stdin,这样我就可以看到输入缓冲区中还剩下什么(如果有的话)

下面是我在gdb的位置示例:

从/cygdrive/c/Users/OwenS.BCI/Desktop/ex19.exe读取符号…完成。
(gdb)中断ex19.c:147
0x4015b8处的断点1:文件ex19.c,第147行。
(gdb)运行
启动程序:/cygdrive/c/Users/OwenS.BCI/Desktop/ex19.exe
[新螺纹784.0x1d98]
[新螺纹784.0xdc0]
你进入大厅。
>你好,世界!
断点1,在ex19处处理输入(game=0x8003b390)。c:148
148开关(ch){
(gdb)打印
$1=104“小时”
(gdb)打印标准
当前上下文中没有符号“stdin”。
(gdb)???
顺便说一下,这个应用程序示例取自“艰苦学习C”的练习19

当我在gdb中调试这个应用程序时,是否可以转储stdin的内容

是的,但要做到这一点,您需要了解正在使用的
libc
的内部结构,并且需要
libc
将调试信息编译到其中

在Linux上,您将安装一个
libc6 debuginfo
或类似的软件包,然后打印
\u IO\u stdin
符号,该符号将包含指向包含缓冲数据的内部缓冲区的指针

但是您使用的是cygwin
libc
,我不熟悉它的内部结构

更新:


我相信我了解如何编译cygwin DLL以允许在其版本的libc中进行调试,但有没有关于如何找出相关调试符号的建议

通过预处理器运行以下源代码的最简单方法:

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

并查看预处理源代码的最后一行。如果
stdin
,则将
d定义为类似
\u IO\u stdin
,如果它将清晰可见。

为什么不使用
fgets(s,10,stdin)
然后使用第一个字符,
ch=*s;
?很有可能,但我的问题不是如何修复代码。相反,我用它作为例子来说明为什么我可能想用gdb转储stdin。我想这就是我要找的信息,谢谢!我会深入研究一下。我相信我理解如何编译cygwin D我将允许在它的libc版本中进行调试,但是关于如何找出相关的调试符号,有什么建议吗?我应该深入了解源代码,还是有一些gdb实用工具可以用来找出它?