问题
I'm using qt-creator as an IDE and frontend for gdb. How can I set a breakpoint when operator<< is called on std::cerr variable? Is it possible from qt-creator or I will have to run gdb standalone?
回答1:
How can I set a breakpoint at std::cerr
Your question doesn't make sense: std::cerr
is a global variable. You can set breakpoints only on functions. You can also set watchpoints on variables, so GDB stops when the variable is modified, but it's likely not what you want either.
What you are probably asking is: "how can I stop when something is written to STDERR_FILENO
file descriptor?".
If that's the case, catch syscall write
might be the answer (but the real answer depends on your OS, which you didn't reveal).
Update:
catching syscall write is not an option I believe, because I'm frequently writing to files
You can make the syscall catchpoint conditional on writing to STDERR_FILENO
(which is 2 on Linux). Example (this will work on Linux/x86_64, but would need to be adjusted for Linux/ix86):
cat t.cc
#include <iostream>
using namespace std;
int main()
{
cout << "Hello,";
cerr << "error 1" << endl;
cout << " World!" << endl;
cerr << "error 2" << endl;
}
gcc -g t.cc
gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) catch syscall write
Catchpoint 2 (syscall 'write' [1])
# Make the catchpoint conditional on writing to stderr:
(gdb) cond 2 $rdi == 2
# By default, "catch syscall" will stop both before and after the actual syscall
# Ignoring the catchpoint once will skip past the "after" stop.
(gdb) command 2
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>ignore 2 1
>end
(gdb) r
Starting program: /tmp/a.out
Hello,
Catchpoint 2 (call to syscall write), 0x00007ffff7383ff0 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) x/s $rsi
0x400a83: "error 1" # Good: we caught our first write to std::cerr
(gdb) c
Continuing.
error 1
Catchpoint 2 (call to syscall write), 0x00007ffff7383ff0 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 in ../sysdeps/unix/syscall-template.S
(gdb) x/s $rsi
0x7ffff76298e3 <_IO_2_1_stderr_+131>: "\n" # I didn't know endl gets a separate write syscall.
(gdb) c
Continuing.
World!
Catchpoint 2 (call to syscall write), 0x00007ffff7383ff0 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 in ../sysdeps/unix/syscall-template.S
(gdb) x/s $rsi
0x400a93: "error 2"
(gdb) c
Continuing.
error 2
Catchpoint 2 (call to syscall write), 0x00007ffff7383ff0 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 in ../sysdeps/unix/syscall-template.S
(gdb) x/s $rsi
0x7ffff76298e3 <_IO_2_1_stderr_+131>: "\n"
(gdb) c
Continuing.
[Inferior 1 (process 17291) exited normally]
来源:https://stackoverflow.com/questions/14305461/set-gdb-breakpoint-when-something-is-printed-on-stdcerr