gdb rbreak and commands (or dprintf behavior)? - gdb

Taking the example from http://shanekirk.com/2017/08/gdb-tips-and-tricks-2-setting-breakpoints-with-regular-expressions/ - when I use rbreak, I get something like:
(gdb) rb TestFixture.h:.
Breakpoint 1 at 0x4008b6: file TestFixture.h, line 5.
void TestFixture::setUp();
Breakpoint 2 at 0x4008d4: file TestFixture.h, line 6.
void TestFixture::tearDown();
Breakpoint 3 at 0x4008f2: file TestFixture.h, line 7.
void TestFixture::testA();
Breakpoint 4 at 0x400910: file TestFixture.h, line 8.
void TestFixture::testB();
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004008b6 in TestFixture::setUp() at TestFixture.h:5
2 breakpoint keep y 0x00000000004008d4 in TestFixture::tearDown() at TestFixture.h:6
3 breakpoint keep y 0x00000000004008f2 in TestFixture::testA() at TestFixture.h:7
4 breakpoint keep y 0x0000000000400910 in TestFixture::testB() at TestFixture.h:8
Now, what I want is basically a dprintf-like behavior: once one of this breakpoints is hit, I just want the function name printed out, and then continue (basically, a function call trace)
However, the way I understand gdb - in order to do that, I would issue a rbreak [regex] first, then I get a bunch of breakpoints, then for each and every one of those I'd had to type manually:
commands [number-of-breakpoint]
print "[name of function]"
continue
end
... which quickly becomes a chore, especially if you end up with a lot more breakpoints than the 4 in the above example (say hundreds).
Now, it would be rather cool, if I could use something like "regex dprintf", or rdprintf, as in:
rdprintf TestFixture.h:., "%s\n", $__breakname__
... but as far as I know, there is no such command...
Or, if after issuing a rbreak TestFixture.h:., I could target the commands for those breakpoints as:
commands 1-4
print $__breakname__
continue
end
... but again, I think this does not exist either...
So is there a way to use gdb to provide this kind of a function call trace printout - without me manually typing the names of breakpoints and their commands, similar to how rbreak allows you to set multiple breakpoints with one command?
EDIT: just found List of all function calls made in an application - record function-call-history /ilc might be interesting, but there doesn't seem to be a way to limit the scope of what functions to trace, say with a regex...

Ok, via the link above, found https://stackoverflow.com/a/39124320/277826 - turns out, you can issue command for multiple breakpoints, as found by rbreak; and to print the name of the function, just use backtrace 1:
(gdb) command 1-36
Type commands for breakpoint(s) 1-36, one per line.
End with a line saying just "end".
>silent
>bt 1
>continue
>end
(gdb) r
... or with python, printing the frame at bt 0 and its parent's frame name:
command 1-36
silent
python print("{} <- {}".format( gdb.execute("bt 0", False, True).strip(), gdb.newest_frame().older().name() ))
continue
end
... or even better, python printing bt 0 function name and args, and parent name:
command 1-36
silent
python nf = gdb.newest_frame(); nfb = nf.block()
python nfargs = [ "{}={}".format(sym, nf.read_var(sym, nfb)) for sym in nfb if sym.is_argument ]
python print("#0 {}({}) <- {}".format(nf.name(), ",".join(nfargs), nf.older().name() ))
continue
end
... which would print something like:
#0 Searcher::FlagFromCmd(this=0x7fffffffaed8,cmd=808) <- FindLiveStrip::GrabToggles
#0 Searcher::FlagFromCmd(this=0x7fffffffaed8,cmd=807) <- FindLiveStrip::ToggleChanged
... and this seems to work fine; though if there are other options, I'd love to know about them.

Related

GDB define command: print $arg1 doesn't print the correct value when in define

I want to define a new command which basically sets a breakpoint on a line, print a value of a certain variable and then continues execution. Unfortunately I am having issues. Here is the code I am using
(gdb) define print_and_continue
Type commands for definition of "print_and_continue".
End with a line saying just "end".
>break $arg0
>command $bpnum
>print $arg1
>continue
>end
>end
So I want to print the value of variable len which is defined in linked_list.h:109. And I execute the following code:
(gdb) print_and_continue linked_list.h:111 len
Breakpoint 1 at 0x388a: linked_list.h:111. (12 locations)
(gdb) r
...
Breakpoint 1, linked_list<test_struct<1>, 1>::remove_if<run_test<1, 1, 1>(std::vector<int, std::allocator<int> >&)::{lambda(test_struct<1> const&)#1}>(run_test<1, 1, 1>(std::vector<int, std::allocator<int> >&)::{lambda(test_struct<1> const&)#1}&&) (this=0x7fffffffdca0, condition=...) at linked_list.h:112
112 linked_list_node* prev = nullptr;
$1 = void
It seems like $arg1 in print function didn't get replaces by the actual argument. What am I doing wrong?
It seems like $arg1 in print function didn't get replaces by the actual argument.
I don't believe that's what is actually happening. Rather, everything following command $bpnum is attached to the newly-created breakpoint literally (without any expansion at all). You can see that happening with info break, which will show something like:
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000001136 at ...
print $arg1
continue
This is generally what you would want (deferring evaluating the argument until the time breakpoint is hit). Otherwise you would print current value of len if you use print len, when what you want is to print the value of len when the breakpoint is hit.
Of course, when the breakpoint is hit, there is no $arg1 (or $arg0) anywhere around, so you get the same output you'd get trying to print any other non-existent GDB variable.
What am I doing wrong?
You are using "quick hack of a language" (which is what the "native" GDB scripting language is), instead of using a proper programming language.
I am 99.99% certain that defining print_and_continue is possible (and probably quite easy) using embedded Python.
That said, I don't believe that print_and_continue is all that useful (in my 20+ years of using GDB, I never needed anything like that).

Is there a "watch window" like GDB function?

In gdb, when it hits a breakpoint, I need to manually investigate the variable values, one by one, with print or print/x functions.
Is there any easier way to list all selected variable's values whenever it hits a breakpoint, commonly known as a "watch window" of a GUI debugger?
Commands can be executed on breakpoints.
From docs:
break foo
commands
printf "x is %d\n",x
end
Or add commands to some existing breakpoint (breakpoint number 3 in this case):
commands 3
print x
print y
end
Or make a command that adds prints to a breakpoint:
define addwatch
commands $arg0
print x
print y
end
end
Then use:
addwatch 3
Or make a command that sets a breakpoint and adds prints to it.
Scripts can be stored in .gdbinit, so they'll load automatically. The language is either this GDB syntax or Python.
P.S. Some people do tracing with this by adding continue at the end of the command list: that way the variables are printed, but the application doesn't stop on the breakpoint.

gdb print file name line number when program is running

I need to debug a flow using gdb - I do not know the call stack hence cannot set break points and going thru first entry points will be really very tedious in project code that runs thru thousands of line.
In same regards is there a way that when I start the program execution via gdb we enable some commands (after some initial breakpoint) - hence when the program starts processing further on it print file name line number without user interaction - something like code flow itself?
Well I want to list lines of code when executing via GDB - like we do
when breakpoint is set and we run 'step'.
You can run step in infinite loop like this:
(gdb) start
Temporary breakpoint 2, main () at ttt123.cpp:23
23 vector<A> v1;
(gdb) while 1
>step
>end

Is there a way to reset breakpoint stats in GDB?

Assume the following .gdbinit:
break foobar
ignore 1 1
run
The program is started using gdb --args ./myprogram --argument1 --argument2 etc.
Now, when I start this the first time around all is fine and dandy. However, if I issue a run on the (gdb) prompt in order to restart the program with the last-known command line, the ignore line will simply not take effect.
The reason is of course clear. The first time around I end up with
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000061ea6a in foobar at ../foobar.c:1173
breakpoint already hit 1 time
And any subsequent run starts with whatever value is shown for X in breakpoint already hit X time. Naturally that value will already exceed the limit set by ignore.
How can I reset the stats on the breakpoints or better yet how can I cause run to do that automatically for me?
How can I reset the stats on the breakpoints or better yet how can I cause run to do that automatically for me?
One way to do that is:
# ~/.gdbinit
break foobar
break main
commands 2
silent
ignore 1 1
continue
end
Now, every time you run, you hit silent breakpoint on main, which resets the ignore count on foobar breakpoint and continues.

Prevent PLT (procedure linkage table) breakpoints in GDB

In recent versions of GDB, setting a breakpoint on a library function call results in multiple actual breakpoints:
Call into the procedure linkage table (PLT)
The actual function call
This means that when the library function is called, we end up going through two breaks each time. In previous GDB versions, only #2 would be created and hence you only get one break.
So the question is: can one can create a library function call breakpoint without the corresponding PLT breakpoint? I am aware that you can create a regular breakpoint and then explicitly disable the PLT one, but this is really tedious.
I think I found a solution for this problem. You can use the
break *address
syntax of break, but instead of specifying a hex address, you give the name of the function (which evaluates to the function's address). Something like
break *myfunction
That sets a breakpoint only on the main function, and not any of the PLT versions.
add these lines to your ~/.gdbinit file and call disaplts to disable all #plt breakpoints:
define disaplts
python
import gdb
from StringIO import StringIO
lines=gdb.execute("info break", True, True)
for l in StringIO(lines).readlines():
if "#plt" in l:
bp=l.split()[0]
gdb.execute("disa {0}".format(bp))
print("disabling {0}".format(bp))
end
end
# disable on library load
catch load mylibrarywithplt disaplt
Note: mind the spacing in python code. I recommend you use cat to paste the content.
EDIT: added "execute on library load" per #WallStProg
Yup, it can be done.
To simply place breakpoints on all functions, use command:
rbreak .*
So, this will place breakpoints on all the functions including PLT.
Now type:
save breakpoints filename
This will save a list of all breakpoints in a file called as filename.
Now open the file in normal text editor like gedit, and remove all the PLT lines given at the end of the file. And then save the file with only the required functions on which you want to place breakpoints.
or
Remove all the #plt from the function names using the command:
sed 's/#plt//g' filename > newfilename
After this, exit gdb (to unlink gdb from useless PLT breakpoints, added before) and execute gdb again.
Now type command:
source filename
or
source newfilename (in case you used sed command)
At this point, gdb will put breakpoints only on the functions mentioned in the file called as "filename" or "newfilename" (if used sed).
Note: To filter functions more in the file "filename", one can use grep also according to the requirements. :)
Here's a command, rdelete, that is like delete in the same way that rbreak is like break - it deletes breakpoints based on a regexp argument.
$ cat rdelete.py
import gdb
import re
class RDelete(gdb.Command):
"""Delete breakpoints for all locations matching REGEXP."""
def __init__(self):
super (RDelete, self).__init__ ("rdelete", gdb.COMMAND_BREAKPOINTS, gdb.COMPLETE_LOCATION)
def invoke(self, argstr, from_tty):
bppat = re.compile(argstr)
for bp in gdb.breakpoints():
if bppat.search(bp.location):
print("Deleting breakpoint {} at {}".format(bp.number, bp.location))
bp.delete()
RDelete()
$ gdb -q hoist
(gdb) rbreak .*
...
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000000580 in main at hoist.c:6
2 breakpoint keep y 0x00000000000007a0 in x at hoist.c:4
3 breakpoint keep y 0x0000000000000530 <_init>
4 breakpoint keep y 0x0000000000000560 <printf#plt>
5 breakpoint keep y 0x00000000000007b0 <__libc_csu_init>
6 breakpoint keep y 0x0000000000000820 <__libc_csu_fini>
7 breakpoint keep y 0x0000000000000824 <_fini>
(gdb) source rdelete.py
(gdb) rdelete #plt
Deleting breakpoint 4 at printf#plt