如何使用 GDB 输入文件进行多输入

how to use a GDB input file for multiple input

编辑:GDB 不是问题所在。我的代码中的错误造成了这种行为。

我想知道 GDB 的输入是如何工作的。

例如,我创建了以下小 c 程序:

#include <stdlib.h>
#include <stdio.h>

int main(){

    setbuf(stdout,NULL);

    printf("first:\n");

    char *inp;
    size_t k = 0;
    getline(&inp, &k, stdin);
    printf("%s",inp);
    free(inp);

    // read buffer overflow
    printf("second:\n");

    char buf[0x101];
    read(fileno(stdin),buf,0x100);
    printf("%s",buf);

    printf("finished\n");
}

它从标准输入中读取两次字符串并打印它的回显。

为了自动阅读,我创建了以下 python 代码:

python3 -c 'import sys,time; l1 = b"aaaa\n"; l2 = b"bbbb\n"; sys.stdout.buffer.write(l1); sys.stdout.buffer.flush(); time.sleep(1); sys.stdout.buffer.write(l2); sys.stdout.buffer.flush();'

运行 c 程序工作正常。 运行 输入 python 的 c 程序也运行良好:

python-snippet-above | ./c-program

运行 没有输入文件的 gdb,在请求时输入字符串,似乎也很好。

但是在gdb中使用输入文件时,恐怕我错误地使用了调试器。 通过教程和 Whosebug 帖子,我知道 gdb 可以通过文件获取输入。

所以我尝试了:

& python-snippet > in
& gdb ./c-program
run < in

我希望 gdb 第一次读取文件的第一行,第二次读取文件的第二行。

in 看起来像(由于 python 代码):

aaaa
bbbb

而是 gdb 打印:

(gdb) r < in
Starting program: /home/user/tmp/Whosebug/test < in
first:
aaaa
second:
finished
[Inferior 1 (process 24635) exited with code 011]

在 read(fileno(stdin),buf,0x100) 之后观察变量 buf 显示:

(gdb) print buf
 = 0x0

所以我假设我的第二个输入 (bbbb) 丢失了。我如何在 gdb 中使用多个输入?

感谢阅读:)

I am wondering how GDB's input works.

您的问题似乎与 GDB 无关,而与程序本身的错误有关。

首先,如果你运行 GDB之外的程序以同样的方式,即:

./a.out < in

您应该会看到与在 GDB 中看到的相同的行为。这是我看到的:

./a.out < in
first:
aaaa
second:
p ��finished

那么错误是什么?

第一个:来自"man getline"

getline() reads an entire line from stream, storing the address
of the buffer containing the text into *lineptr.

If *lineptr is NULL, then getline() will allocate a buffer
for storing the line, which should be freed by the user program.

没有inp设置为NULL,也没有设置到分配的缓冲区。如果 inp 没有 发生 成为 NULL,你就会得到堆损坏。

第二个错误:您没有检查 read 中的 return 值。如果这样做,您会发现它 returns 0,因此您的 printf("%s",buf); 打印未初始化的值(在我的终端中显示为 ��)。

第三个错误:您期望 read 到 return 第二行。但是你之前在 stdin 上使用了 getline,当从文件 中读取 时,stdin 将使用 full 缓冲。由于您的输入很小,第一个 getline 尝试读取 BUFSIZ 的数据,并读取(缓冲区) 所有数据 。随后的 read(自然地)returns 0 因为您已经到达文件末尾。

你有 setbuf(stdout,NULL);。您的意思是改为在 stdin 上禁用缓冲吗?

第四个错误:read 不会 NUL 终止字符串,您必须自己做,然后才能调用 printf("%s", ...)

修复错误后,我得到了预期:

first:
aaaa
second:
bbbb
finished