I am attempting to print the contents of a file opened with fopen in C within GDB.
For example, take the following C code:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file;
file = fopen("/etc/passwd", "r");
fclose(file);
return 0;
}
I would like to be able to view the contents of this file when running the compiled executable in GDB. Thankyou!
CodePudding user response:
I am attempting to print the contents of a file opened with fopen in C within GDB.
You need to have libc
which is compiled with debug info. For example, on Linux, using GLIBC and with libc6-dbg
installed, using your example program, modified to actually read the file (merely fopen
ing and immediately fclose
ing the file doesn't read anything):
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file;
file = fopen("/etc/passwd", "r");
int ch = fgetc(file); /* force a read */
fclose(file);
return 0;
}
(gdb) start
Temporary breakpoint 1 at 0x115d: file t.c, line 6.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at t.c:6
6 file = fopen("/etc/passwd", "r");
(gdb) n
7 int ch = fgetc(file);
(gdb) n
8 fclose(file);
(gdb) p *file
$1 = {_flags = -72539000, _IO_read_ptr = 0x555555559481 "oot:x:0:0:root:/root:/bin/bash\n"..., _IO_read_end = 0x55555555a1c6 "", ..., _IO_read_base = 0x555555559480 "root:x:0:0:root:/root:/bin/bash\n"...
Here you can see that the data which will be returned by subsequent reads is pointed to by file->_IO_read_ptr
, and the entire buffer is pointed by file->_IO_read_base
.
The members will depend on which libc
you use, and the amount of buffered data (if any) will depend on buffering that the stream was opened with.
CodePudding user response:
You can use call function. You write a function that prints the contents of a file as you wish and you call it from gdb.
(gdb) help call
Call a function in the program.
Usage: call EXP
The argument is the function name and arguments, in the notation of the current working language. The result is printed and saved in the value history, if it is not void.
Of course, in that function you should preserve the file position -- ftell at the beginning, fseek at the end, etc.
#include <stdio.h>
#include <stdlib.h>
void
debug_file(FILE*f)
{
printf("keep ftell, read, print, restore position\n");
}
int main() {
....
}
% gcc -O0 -g3 gbd.c
% gdb ./a.out
Reading symbols from ./a.out...
(gdb) break main
Breakpoint 1 at 0x118f: file gbd.c, line 12.
(gdb) r
Starting program: /work/stub/a.out
Breakpoint 1, main () at gbd.c:12
12 file = fopen("/etc/passwd", "r");
(gdb) n
13 int ch = fgetc(file); /* force a read */
(gdb)
14 fclose(file);
(gdb) call debug_file(file)
keep ftell, read, print, restore position
(gdb) c
Continuing.
[Inferior 1 (process 6432) exited normally]
(gdb)