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
Related
I am trying to debug a very sporadic issue in my application. If ran ~1000 times my application surely hits a certain line it shouldn't and I would like to view the stack.
I tried using a gdb script cmd.gdb for this:
set logging overwrite on
set pagination off
set $n = 1000
break file.c:496
while $n-- > 0
ignore 1 9
condition 1 global_var == 10
run
end
How should I modify this script in order to print the stack when the breakpoint is reached?
I tried adding this after "run":
if $_siginfo
bt
loop_break
end
but it doesn't seem to work.
Actually, I have a Github repo with a Python-GDB extension, which does exactly the same thing as You have described, but with some more functionality.
You can just clone the repo:
git clone https://github.com/Viaceslavus/gdb-debug-until.git
and feed the python script to GDB with the following command inside GDB:
source <python script path>
Then, according to your example, you should run the next command:
debug-until file.c:496 --args="" --var-eq="global_var:10" -r=1000
*some remarks:
file.c:496 here is a starting breakpoint
"--args" parameter contains the arguments for your program
"--var-eq" is a debugging event, where 'global_var' is a variable name and '10' is a value
and finally the "-r" option specifies the number of times the program will be ran.
So all together this command will run your program 1000 times and will immediately notify You when the 'global_var' will be equal to 10.
Any additional information about the project could be found here:
https://github.com/Viaceslavus/gdb-debug-until.git in the README file.
GDB allows registering a set of commands to a specific breakpoint via commands NUM syntax. I need to register the set of commands for a specific breakpoint via an external file, by using a syntax something like the following:
commands ./main.c:18
silent
print buffer[0]
cont
end
commands ./io.c:29
silent
printf "Hello world %i\n", myvar1
cont
end
The commands path/to/file:XX syntax is made up by me. Because the NUM in commands NUM syntax requires exactly the breakpoint's runtime ID number (assigned by GDB), I can not use a deterministic syntax for that purpose.
I'm currently registering breakpoints via a text file with such a content:
break ./main.c:18
break ./io.c:29
and then issuing source breakpoints.txt command inside GDB. It seems that there is no way to register commands at the same time while registering a breakpoint:
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point. Accepted values are -probe' (for a generic, automatically guessed probe type), -probe-stap' (for a SystemTap probe) or
`-probe-dtrace' (for a DTrace probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame. This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if their
conditions are different.
Question
Is there any easy way to set some predetermined commands for a predetermined breakpoint from within a file?
If not, is there any equivalent way to pass the (gdb) info breakpoints output to a file or a program while pipe is not available in GDB (version 5.3)? Currently I'm trying a workaround by using logging feature for that purpose:
set logging file /tmp/breakpoints
set logging on
info breakpoints
set logging off
Is there any easy way to set some predetermined commands for a predetermined breakpoint from within a file?
Yes: if you use commands without NUM, the commands will apply to the last breakpoint set. So you want something like:
break main.c:18
commands
silent
print buffer[0]
cont
end
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.
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.
If I set up a break point and if GDB hits the break points, then it shows the line of the code. If I enter n or next, then GDB prints out the next line of the code.
I was wondering if there is a way I can trace the actual line of code being executed through GDB.
For example, if I enter n or next 100 times then I will get traces of 100 lines of code. I want to do this automatically not by entering n or next.
Note that collecting next trace like you appear to desire is exceedingly unlikely to help you debug actual problem in any realistically sized program: most of the time programs spend in loops, and executing next repeatedly will just give you a never-ending stream of loop repetitions.
That said, you can achieve what you want like this:
(gdb) shell perl -e 'print "n\n" x 100' > gdb.cmd
(gdb) source gdb.cmd
put a breakpoint 100 lines from your current position and continue the execution