我可以用 gdb 转储标准输入吗?

Posted

技术标签:

【中文标题】我可以用 gdb 转储标准输入吗?【英文标题】:Can I dump stdin with gdb? 【发布时间】:2015-06-26 13:26:49 【问题描述】:

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

例如,假设我没有弄清楚这个错误的来源,并试图弄清楚为什么当我进入“hello world!”时我的应用程序会吐出一堆“垃圾”。在用户提示而不是“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
$1 = 104 'h'
(gdb) print stdin
No symbol "stdin" in current context.
(gdb) ???

顺便说一下,这个应用示例取自“Learn C the Hard Way”的练习 19。

【问题讨论】:

为什么不使用fgets(s,10,stdin),然后使用第一个字符ch= *s; 很有可能,但我的问题不是如何修复代码。相反,我用它作为一个例子来说明为什么我可能想用 gdb 转储标准输入。 【参考方案1】:

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

是的,但要这样做,您需要知道您正在使用的 libc 的内部结构,并且您需要 libc 将调试信息编译到其中。

在 Linux 上,您将安装 libc6-debuginfo 或类似的软件包,然后打印 _IO_stdin 符号,其中包含指向包含缓冲数据的内部缓冲区的指针。

但是你使用的是cygwin libc,我对它的内部并不熟悉。

更新:

我相信我了解如何编译 cygwin DLL 以允许在它的 libc 版本中进行调试,但是对于如何找出相关调试符号有什么建议吗?

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

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

并查看预处理源代码的最后一行。如果stdin#defined 到_IO_stdin 之类的东西,if 将清晰可见。

【讨论】:

我认为这是我正在寻找的信息,谢谢!我会深入研究一下。 我相信我了解如何编译 cygwin DLL 以允许在 it's 版本的 libc 中进行调试,但是关于如何找出相关调试符号的任何建议?我应该深入研究源代码还是可以使用一些 gdb 实用程序来找出答案?

以上是关于我可以用 gdb 转储标准输入吗?的主要内容,如果未能解决你的问题,请参考以下文章

GDB:将参数转储到特定函数的所有调用

Python子进程错误:使用标准输入将输入传递到终端

我可以同时从 Node 的标准输入中读取行和字符吗?

请问ABAP中,如何从标准屏幕上获取到选择屏幕中一个字段的输入值。可以举个例子吗?这里感谢大家了。

如何将 A 的标准输出重定向到 B 的标准输入,将 B 的标准输出重定向到 A 的标准输入?

slimerjs - 打开通过标准输入的网页?