Gdb Break When Program Opens Specific File

gdb break when program opens specific file

GDB is a pretty powerful tool, but has a bit of a learning curve.

Basically, you want to set up a conditional breakpoint.

First use the -i flag to strace or objdump -d to find the address of the open function or more realistically something in the chain of getting there, such as in the plt.

set a breakpoint at that address (if you have debug symbols, you can use those instead, omitting the *, but I'm assuming you don't - though you may well have them for library functions if nothing else.

break * 0x080482c8 

Next you need to make it conditional

(Ideally you could compare a string argument to a desired string. I wasn't getting this to work within the first few minutes of trying)

Let's hope we can assume the string is a constant somewhere in the program or one of the libraries it loads. You could look in /proc/pid/maps to get an idea of what is loaded and where, then use grep to verify the string is actually in a file, objdump -s to find it's address, and gdb to verify that you've actually found it in memory by combining the high part of the address from maps with the low part from the file. (EDIT: it's probably easier to use ldd on the executable than look in /proc/pid/maps)

Next you will need to know something about the abi of the platform you are working on, specifically how arguments are passed. I've been working on arm's lately, and that's very nice as the first few arguments just go in registers r0, r1, r2... etc. x86 is a bit less convenient - it seems they go on the stack, ie, *($esp+4), *($esp+8), *($esp+12).

So let's assume we are on an x86, and we want to check that the first argument in esp+4 equals the address we found for the constant we are trying to catch it passing. Only, esp+4 is a pointer to a char pointer. So we need to dereference it for comparison.

cond 1 *(char **)($esp+4)==0x8048514

Then you can type run and hope for the best

If you catch your breakpoint condition, and looking around with info registers and the x command to examine memory seems right, then you can use the return command to percolate back up the call stack until you find something you recognize.

gdb : setting breakpoint when new file is opened or stream instance is created


This works except it also catches the output to the screen

You can exclude output to stdout with conditional breakpoint. On x86_64 this can be done with comparing rdi register to 1:

(gdb) catch syscall write
Catchpoint 1 (syscall 'write' [1])
(gdb) condition 1 $rdi!=1
(gdb) i b
Num Type Disp Enb Address What
1 catchpoint keep y syscall "write"
stop only if $rdi!=1
(gdb)

You can also set conditional breakpoint on exact file descriptor you want. See https://stackoverflow.com/a/8052681/72178 how to map file name to file descriptor on Linux.

How to stop program in gdb at writing to a particular file known by its name

You can get GDB to stop on every write system call with catch syscall write.

Since write operates on file descriptors, and not on named files, you can't make this breakpoint conditional on the name; you'll have to find out the file descriptor that corresponds to your "interesting" file first.

On Linux, you can look at ls -l /proc/<pid>/fd/* to associate file descriptors with names.

Other systems may have lsof, or other system-specific mechanisms for doing the same.

Once you have the file descriptor, you can make the catch conditional (so GDB stops only when that particular file is written). The exact details of how to do that differ between operating systems and processors, and you didn't supply either.

How to set break point on one file of a project which has many files with same name?

Specify the full path:

gdb> break /Full/path/to/service.cpp:45

GDB how to set break point in linked files?

What you want is the following (see GDB doc):

break main.c:232

And don't forget to compile with -g, otherwise line number information will not be present in the generated program.

Using gdb stop the program when it is using any function from file X

Step 1: construct a list of all functions defined in foo.cpp

The simplest way I can think of (assuming you have binutils and GNU grep):

nm a.out | grep ' T ' | addr2line  -fe a.out |
grep -B1 'foo\.cpp' | grep -v 'foo\.cpp' > funclist

Step 2: construct a GDB script which will set a break point on each of the above functions:

sed 's/^/break /' funclist > stop-in-foo.gdb

[Obviously, steps 1 and 2 could be combined ;-]

Step 3: actually set the breakpoints:

gdb a.out
(gdb) source stop-in-foo.gdb

Looking at this answer, an even simpler (if you are on Fedora Linux) way to find out which foo.cpp functions are called:

ftrace -sym='foo.cpp#*' ./a.out

Too bad ftrace man page says this isn't implemented yet.



Related Topics



Leave a reply



Submit