Reputation: 981
Suppose I have the following C++:
template <int I> int bar(int i) {
++i;
label1:
return I * i;
}
int main(int argc, char **) { return bar<2>(argc); }
Is it possible to set a gdb breakpoint on label1
for all instantiations of bar? In the above, it is easy -- there is just one instantiation. In my actual use case there are a large number spread all over the code base.
Said another way, in my gdb commandfile, is there a way to avoid the need to know a priori about every template instantiation of bar? In my actual use case, my aim is to emit some information about program state at the point of the labels (worry not, no programs were harmed by goto
).
I know I can set a breakpoint on the label for a specific instantiation of bar
as follows:
break -function bar<2> -label label1
I also know about rbreak
which can be used to break on the entry of all template functions, but apparently does not have the -label
option. I don't want to break on the entry point -- just the the label(s). I also looked to see if I could combine rbreak
with until label1
but that didn't work.
Two other approaches I've considered are:
list
from within the gdb python package.Any suggestions?
Upvotes: 3
Views: 1103
Reputation: 981
Per the suggestion from Employed Russian, I came up with the following gdb python script:
import re
class Custombreakpoint(gdb.Breakpoint):
def __init__(self, function, label):
super().__init__(function=function, label=label, internal=True)
def stop(self):
I = gdb.parse_and_eval("I")
i = gdb.parse_and_eval("i")
print(f"I = {I}, i = {i}")
return False
pattern = re.compile('.*foo.*')
for sym in gdb.lookup_global_symbol('main').symtab.global_block():
if sym.is_function:
match = pattern.search(sym.name)
if match:
Custombreakpoint(function=match.string, label='label1')
gdb.execute('run')
gdb.execute('quit')
Which yields the following output:
$ g++ -g ./test.cc && gdb --command=test.py ./a.out
Reading symbols from ./a.out...
I = 2, i = 2
I = 3, i = 2
[Inferior 1 (process 17224) exited with code 012]
This will allow me to do exactly what I want to do in my actual use case. Thanks for the help!
Upvotes: 0
Reputation: 213935
This answer shows how to iterate over all global symbols in a program.
For your test program, it yields:
bar<2>(int) True
main(int, char**) True
From here, you can easily find all instantiations of bar<>()
, and set breakpoints on them using Python breakpoints API.
(gdb) py
>gdb.Breakpoint(function='bar<2>(int)', label='label1')
Breakpoint 1 at 0x1158: file t.cc, line 3.
Using function='bar<2>'
also works.
Upvotes: 3