【问题标题】:how to use a GDB input file for multiple input如何使用 GDB 输入文件进行多个输入
【发布时间】:2015-05-18 16:38:39
【问题描述】:

编辑: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中使用输入文件时,恐怕我错误地使用了调试器。 通过教程和 stackoverflow 帖子,我知道 gdb 可以通过文件获取输入。

所以我尝试了:

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

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

in 看起来像(由于 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]

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

(gdb) print buf
$1 = 0x0

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

感谢阅读:)

【问题讨论】:

    标签: c input gdb


    【解决方案1】:

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

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

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

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

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

    纠正错误后,我期待:

    first:
    aaaa
    second:
    bbbb
    finished
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      • 2012-11-11
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 2020-03-09
      相关资源
      最近更新 更多