如何使用 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
编辑: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