Is there any way to set a breakpoint in gdb that is conditional on the call stack?
Update: There is now a better answer to this question: use GDB _is_caller
convenience function.
The need you describe comes up quite often, usually in the context of some_utility_fn
being called a lot, but you only are interested in the call which comes from some_other_fn
.
You could probably script this entire interaction using the new embedded Python support in GDB from CVS trunk.
Without Python, you are limited in what you can do, but the usual technique is to have a disabled breakpoint on a()
, and enable it from a command, attached to a breakpoint on b()
.
Here is an example:
int a(int x)
{
return x + 1;
}
int b()
{
return a(1);
}
int call_a_lots()
{
int i, sum = 0;
for (i = 0; i < 100; i++)
sum += a(i);
}
int main()
{
call_a_lots();
return b();
}
gcc -g t.c
gdb -q ./a.out
Reading symbols from /tmp/a.out...done.
(gdb) break a
Breakpoint 1 at 0x4004cb: file t.c, line 3.
(gdb) disable 1
(gdb) break b
Breakpoint 2 at 0x4004d7: file t.c, line 8.
(gdb) command 2
>silent
>enable 1
>continue
>end
(gdb) run
Breakpoint 1, a (x=1) at t.c:3
3 return x + 1;
(gdb) bt
#0 a (x=1) at t.c:3
#1 0x00000000004004e1 in b () at t.c:8
#2 0x000000000040052c in main () at t.c:21
(gdb) q
Voila: we've stopped on a()
called from b()
, ignoring previous 100 calls to a()
.
Can GDB set a breakpoint on a sequence of function calls?
You can use a conditional breakpoint with the the $_caller_is
convenience function. Something like this:
(gdb) break connect
Breakpoint 1 at 0x7ffff7ee6820
(gdb) cond 1 $_caller_is("curl_connect") && $_caller_is("get_file", 2) && $_caller_is("init_assets", 3)
Create a conditional breakpoint base on the call stack
You can query the stack trace programatically, using System.Diagnostics Namespace. Yoy may do something like this:
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();
var f = st.GetFrames();
var names = f.Select(f => f.GetMethod().Name).ToList();
if (names.Contains("DoSomething4"))
{
var a = 0; // Set breakpoint in this line or use Debugger.Launch()
}
You can use #if DEBUG and #endif so this code doesn't go into release
Also, you can create a condition for a breakpoint using this class
gdb: conditionally break on function only if the caller function is not equal certain value
I like to set up the conditional breakpoint in gdb such that gdb will break into "gdb>" only when the caller function of malloc() is not equal to my_mallc().
In other words, you want to break on malloc
when it is not called by my_malloc
.
One way to do that is to set three breakpoints: one on malloc
, one on my_malloc
entry, and one on my_malloc
return. Then (assuming the breakpoints are 1, 2 and 3 respectively).
(gdb) commands 2
silent # don't announce hitting breakpoint #2
disable 1 # don't stop when malloc is called within my_malloc
continue # continue execution when BP#2 is hit
end
(gdb) commands 3
silent
enable 1 # re-enable malloc breakpoint
continue
end
This technique only works for single-threaded applications.
In Gdb how to set conditional breakpoint to a function's 3rd line
How about defining your own command file for gdb and then just sourcing it during debug? That would help reduce a fair bit of typing. Try this:
Create a file, let's call it mydef and here's its contents:
define cmd
b function-where-you-want-to-break
r
b +2
c
end
Once you load the executable in gdb, type in source mydef
in gdb prompt followed by cmd
Now you are into the 2nd line from where function began. :)
Hope this helps!
How do I set a breakpoint in GDB, but not have the breakpoint halt execution? I just want to be notified in the console if the line is hit
I want the option to be notified of the breakpoint traversal, but not halt execution.
(gdb) break foo.c:123
(gdb) commands $bpnum
continue
end
This attaches a command to the breakpoint. GDB will print that a breakpoint is hit, then run the attached command, which will continue execution.
You could also print some variables before continuing, or even continue only if some condition is true, and stop otherwise. E.g. "continue if x > 100
, but stop if it's not".
Is it possible to break on a breakpoint only when a certain method is present in the call stack?
Recent versions of gdb ship with some convenience functions written in Python for just this case. Take a look at $_caller_is
and friends. (FWIW this exact use case was what motivated me to work on adding Python to gdb...)
A simple use would be:
(gdb) break foo if $_any_caller_matches("bar")
If the call stack contains more functions in between foo
and bar
calls resulting in a stack that looks like the following,
foo()
...
...
...
bar()
...
...
...
main()
you could pass an extra argument to _any_caller_matches
which indicates the number of frames to check for the occurrence of bar
(gdb) break foo if $_any_caller_matches("bar", 10)
Reference: https://sourceware.org/gdb/current/onlinedocs/gdb/Convenience-Funs.html
$_any_caller_matches(regexp[, number_of_frames])
Returns one if any
calling function’s name matches the regular expression regexp.
Otherwise it returns zero.If the optional argument number_of_frames is provided, it is the
number of frames up in the stack to look. The default is 1.This function differs from $_caller_matches in that this function
checks all stack frames from the immediate caller to the frame
specified by number_of_frames, whereas $_caller_matches only checks
the frame specified by number_of_frames.
How do I set a conditional breakpoint in gdb, when char* x points to a string whose value equals hello?
You can use strcmp
:
break x:20 if strcmp(y, "hello") == 0
20
is line number, x
can be any filename and y
can be any variable.
Related Topics
How to Update a Printed Message in Terminal Without Reprinting
How to Export a C++ Class from a Dll
How Can Std::Make_Heap Be Implemented While Making at Most 3N Comparisons
Details of Std::Make_Index_Sequence and Std::Index_Sequence
How Does Malloc Understand Alignment
Returning to Beginning of File After Getline
C++ Multiple Inheritance Function Call Ambiguity
How to Cancel/Detach a Future in C++11
Is Volatile Bool for Thread Control Considered Wrong
Convert C++ Function Pointer to C Function Pointer
Custom Manipulator for C++ iOStream
Setting Vector Elements in Range-Based for Loop
C++ Equivalent of Stringbuffer/Stringbuilder
C++ - Decimal to Binary Converting