我想知道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中使用多个输入?
感谢阅读:)
答案 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