如何将GDB输入文件用于多个输入

时间:2015-05-17 20:22:14

标签: c input gdb

编辑: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");
}

它从stdin读取两次字符串并打印出它的回声。

为了自动化这个阅读,我创建了以下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中使用输入文件时,我恐怕错误地使用了调试器。 通过教程和stackoverflow帖子,我知道gdb可以通过文件获取输入。

所以我试过了:

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

我预计gdb将用于第一次读取文件的第一行,而第二次读取第二行的输入。

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

aaaa
bbbb

但gdb打印:

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

在读取后观察变量buf(fileno(stdin),buf,0x100)告诉我:

(gdb) print buf
$1 = 0x0

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

感谢阅读:)

1 个答案:

答案 0 :(得分:2)

  

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

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

首先,如果您以相同的方式在GDB之外运行程序,即:

./a.out < in

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

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

那有什么错误?

第一个:来自&#34; man getline&#34;

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的返回值。如果您这样做,则会发现它返回0,因此您的printf("%s",buf);会打印未初始化的值(在我的终端中显示为��)。

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

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

第四个错误:read没有NUL - 终止字符串,您必须自己执行此操作,然后才能在其上调用printf("%s", ...)

纠正错误后,我得到了预期:

first:
aaaa
second:
bbbb
finished