http://www.nabble.com/break-when-opening-certain-file-td21428195.html
You want a "conditional breakpoint".
Assuming you're on i386-linux or similar (adjustments are
straightforward for most other platforms),
#include <fcntl.h>
int
main (int argc, char *argv[])
{
int i;
for (i = 1; i < argc; ++i)
open (argv[i], O_RDONLY);
return 0;
}
bash$ gcc -g foo.c
bash$ gdb --args a.out foo bar baz
(gdb) start
(gdb) break open
(gdb) condition 2 strcmp (((char**)$esp)[1], "bar") == 0
(gdb) c
Continuing.
Breakpoint 2, 0x42ce0e80 in open () from /lib/tls/i686/cmov/libc.so.6
(gdb) x/s ((char**)$esp)[1]
0xffffdafe: "bar"
(gdb) c
Continuing.
Program exited normally.
(gdb)
You kinda have to know the i386 calling convention to know that on
entry to open the file name is at ((char**)$esp)[1].
The use of "start" above simplifies a few things, it runs the program
to the start of main(). At this point libc is loaded and any open
calls made while trying to get to main() are skipped.
One caveat is that specifying the condition this way will call
malloc() to allocate space for "bar" so that the call to strcmp will
work. If you don't want to call malloc when testing the breakpoint
condition then one alternative is to manually compare the characters.
A real pain, but if you're debugging a problem and you just need to
have gdb stop at the right file you often don't need to compare every
character in the file name, just enough to get you close. You can
keep hitting continue until the breakpoint hits the right one.
Starting over,
bash$ gdb --args a.out foo bar baz
(gdb) start
(gdb) break open
(gdb) condition 2 ((char**)$esp)[1][0] == 'b'
(gdb) commands 2
x/s ((char**)$esp)[1]
end
(gdb) c
Continuing.
Breakpoint 2, 0x42ce0e80 in open () from /lib/tls/i686/cmov/libc.so.6
0xffffdafe: "bar"
(gdb) c
Continuing.
Breakpoint 2, 0x42ce0e80 in open () from /lib/tls/i686/cmov/libc.so.6
0xffffdb02: "baz"
(gdb) c
Continuing.
Program exited normally.
(gdb)
You want a "conditional breakpoint".
Assuming you're on i386-linux or similar (adjustments are
straightforward for most other platforms),
#include <fcntl.h>
int
main (int argc, char *argv[])
{
int i;
for (i = 1; i < argc; ++i)
open (argv[i], O_RDONLY);
return 0;
}
bash$ gcc -g foo.c
bash$ gdb --args a.out foo bar baz
(gdb) start
(gdb) break open
(gdb) condition 2 strcmp (((char**)$esp)[1], "bar") == 0
(gdb) c
Continuing.
Breakpoint 2, 0x42ce0e80 in open () from /lib/tls/i686/cmov/libc.so.6
(gdb) x/s ((char**)$esp)[1]
0xffffdafe: "bar"
(gdb) c
Continuing.
Program exited normally.
(gdb)
You kinda have to know the i386 calling convention to know that on
entry to open the file name is at ((char**)$esp)[1].
The use of "start" above simplifies a few things, it runs the program
to the start of main(). At this point libc is loaded and any open
calls made while trying to get to main() are skipped.
One caveat is that specifying the condition this way will call
malloc() to allocate space for "bar" so that the call to strcmp will
work. If you don't want to call malloc when testing the breakpoint
condition then one alternative is to manually compare the characters.
A real pain, but if you're debugging a problem and you just need to
have gdb stop at the right file you often don't need to compare every
character in the file name, just enough to get you close. You can
keep hitting continue until the breakpoint hits the right one.
Starting over,
bash$ gdb --args a.out foo bar baz
(gdb) start
(gdb) break open
(gdb) condition 2 ((char**)$esp)[1][0] == 'b'
(gdb) commands 2
x/s ((char**)$esp)[1]
end
(gdb) c
Continuing.
Breakpoint 2, 0x42ce0e80 in open () from /lib/tls/i686/cmov/libc.so.6
0xffffdafe: "bar"
(gdb) c
Continuing.
Breakpoint 2, 0x42ce0e80 in open () from /lib/tls/i686/cmov/libc.so.6
0xffffdb02: "baz"
(gdb) c
Continuing.
Program exited normally.
(gdb)
条件断点调试技巧
本文介绍了一种在特定文件打开时设置条件断点的方法。通过使用GDB调试器,在i386-linux平台上实现了对指定文件名(如bar)进行精确匹配的断点设置。此外还提供了一个简化方案,只需比较文件名的第一个字符即可触发断点。
1268

被折叠的 条评论
为什么被折叠?



