Debugging attached process with gdb - how to escape from a loop - c++

I am debugging code that looks like this:
while (true){
// do something ...
size_t i = foo(); // <- bp set here
if (flag_set) break;
}
// More code follows here ...
I want to break at the foo() function call, invoke it a few times and then jump out of the while loop completely (lets assume that we are guaranteed that the flag will be set - so we can break out of the loop.
How do I break out of the loop completely?. finish simply runs to the next iteration. What I want to do is to exit the current "code chunk" (in this case, the while loop)

You want the advance command, which takes the same arguments as the break command. Using your code as an example (but with line numbers added):
10 while (true){
11 // do something ...
12 size_t i = foo(); // <- bp set here
13 if (flag_set) break;
14 }
15
16 // More code follows here ...
17 someFunction();
Say your original breakpoint on line 12 was breakpoint 1, and after breaking a few times you wanted to skip to line 17, you would type something like:
disable 1
advance 17
which would disable breakpoint 1 (so it doesn't get hit for the rest of the loop) and then keep executing the program until it hit line 17.

Set a breakpoint before the loop. Then cursor to the foo() call, and use Debug|Run to Line. This is so useful that I have dedicated a function key to it.

Set a second breakpoint after the loop. disable the breakpoint inside the loop. cont. enable the breakpoint again.
I don't know of any easier way.

Try using the jump command. Per gdb help, on this system at least:
jump -- Continue program being debugged at specified line or address

What you need is until command. This is the easiest way to avoid stepping through the loop. From gdb manual:
Continue running until a source line past the current line, in the current stack frame, is reached. This command is used to avoid single stepping through a loop more than once. It is like the next command, except that when until encounters a jump, it automatically continues execution until the program counter is greater than the address of the jump.

Related

Ignore but count breakpoint hits in lldb/gdb

I have two breakpoints A and B. And I'd like to count how many instances of A occur before B is hit. The thing is A occurs quite a bit (>1000) so i can't manually continue and iterate. A can also occur after B so I can't run a program to completion to find out the hit counts. Is there an automatic way to do this?
You can do this pretty easily with an auto-continue breakpoint at A and commands on breakpoint B. In the simplest approach, the breakpoint on A would look like:
break set <HoweverYouSpecifyA> --auto-continue 1 -N BreakpointA
Then the breakpoint on B would be:
break set <HoweverYouSpecifyB> -C "break list BreakpointA" -C "break disable BreakpointA" --one-shot
The break list BreakpointA output will show the hit count of A when you hit B, which is what you wanted to know. By disabling A when you hit B, the hit count for A will stay what it was when you hit B, so you should be able to check it at any point after that (till you rerun).
I like to use named breakpoints when I'm doing a little breakpoint two-step like this, otherwise you have to use the ID of the first breakpoint, and that can change from run to run depending on the order in which you set breakpoints.
I also made breakpoint B a one-shot since you're just using it to freeze the hit-count of A so it only needs to get hit the once. If it's more convenient you could also make B auto continue and then just read out the hit count of A when the program exits.
If you wanted to get fancier, you could use a Python callback for B instead, and get the hit count from A and report that however you want. It's more work but it is easier to control output formatting from Python...
Is there an automatic way to do this?
In GDB, I usually do this:
(gdb) ign 1 10000
(gdb) cont
When the second (B) breakpoint is hit, info break will say something like:
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000555555555129 in a at t.c:1
breakpoint already hit 1234 times <<<===
ignore next 8766 hits
2 breakpoint keep y 0x0000555555555130 in b at t.c:2
breakpoint already hit 1 time
If 10000 turns out to not be enough, you could always increase it to 10000000 instead.

Repeating Command in LLDB

How can I repeatedly run a command in LLDB for debugging C++ code?
For example, when I set a breakpoint inside a loop and want to continue for 10 iterations before stopping, I am currently typing continue ten times manually to do this. Is there a better way?
As an example, let's say I have this code block:
int i = 0;
while (true) {
// Increment i
i++;
}
If I set a breakpoint on the line with the comment, I could keep using the command continue to go through one iteration of the loop and go back to that line. However, if I wanted to skip over 10 iterations (i.e. use the command continue 10 times), how would I do that?
lldb tends to use options where gdb would use a command argument. That makes it easier to have a bunch of different ways to condition a particular command without having to come up with ad hoc mini-syntaxes for each command.
Anyway, so in lldb you would do:
(lldb) c -i 10
You can see this in help:
(lldb) help continue
Continue execution of all threads in the current process.
Syntax: continue <cmd-options>
Command Options Usage:
continue [-i <unsigned-integer>]
-i <unsigned-integer> ( --ignore-count <unsigned-integer> )
Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread.
'continue' is an abbreviation for 'process continue'
Note also that you can do the same thing just by setting the ignore count in the breakpoint you just hit: break modify -i 10 <BKPTNO>.
Just add a conditional breakpoint. In gdb it's like this
break ... if cond
Set a breakpoint with condition cond; evaluate the expression cond each time the breakpoint is reached, and stop only if the value is nonzero--that is, if cond evaluates as true. `...' stands for one of the possible arguments described above (or no argument) specifying where to break. See section Break conditions, for more information on breakpoint conditions.
https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_28.html
For example if i is currently 0 and you want to break on line 10 then use
break 10 if i >= 10
Just increase the condition value based no the current value of i
I don't know lldb but according the the mapping list break foo if strcmp(y,"hello") == 0 in gdb can be done as the following in lldb
(lldb) breakpoint set --name foo --condition '(int)strcmp(y,"hello") == 0'
(lldb) br s -n foo -c '(int)strcmp(y,"hello") == 0'
If there's no loop counter you can just declare a debug variable yourself
expr unsigned int $foo = 1
breakpoint set --name foo --condition '++$foo >= 10'

Step into using GDB

I am performing some analysis of code using gdb. Just suppose the program is like
#include<stdio.h>
getinput()
{
char buffer[8];
gets(buffer);
puts(buffer);
}
int main()
{
getinput();
return 0;
}
I have complied it using gcc withsome other switches as mentioned below:
gcc -ggdb -mpreferred-stack-boundary -fno-stack-protection -o demo demo.c
On analysis with gdb, when I insert break point on getinput() and gets(buffer) function..
Then using "s" step through function.. on gets(buffer) function..
it does not ask for the user input, rather it asks for userinput. GDB directly steps into function gets...but i don't want it to move into gets functions..
(gdb) break 6
Breakpoint 2 at 0x8048441: file demo.c, line 6.
(gdb) s
The program is not being run.
(gdb) run
Starting program: /root/BufferOverflow/demo
Breakpoint 1, main () at demo.c:11
11 getinput();
(gdb) s
Breakpoint 2, getinput () at demo.c:6
6 gets(buffer);
(gdb) s
_IO_gets (buf=0xbfffeda8 "y\204\004\b") at iogets.c:32
32 iogets.c: No such file or directory.
(gdb)
I am getting the error shown above. Can anyone please help me regarding this ???
Then using "s" step through function.. on gets(buffer) function..
Using step command on line 6 will step into gets() function. If you don't want this, use next command. It will move to the next line of code in getinput() function (to puts() call).
gdb has a variety of ways to advance through a program. An excellent overview can be found here.
The most common sequence will be something like:
break [line or function/method]
run args
next
print [interesting variables]
The next will skip any function calls on the line and move to the next source line in the current function. The step will step into a function.
If you accidentally step into a non-interesting function the finish command will run until the end of the current function.
A common case is stepping into a function that is evaluating an argument.
my_method(gets(buffer));
A step on this line will lead you into the assembler of the gets() function. Usually this is not what you want. For such cases, I will usually just set a breakpoint on my_method and then cont.
gdb tries to avoid this situation with the step-mode setting. It doesn't always work however as you see in your example.
gdb is a great tool that will save you time and misery. If you are working as a developer then certainly take time to master it.

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.

Continue an iteration in C++ until a specific iteration number in gdb

I am using gdb-7.0.1 and I think I have detected a bug in a certain section of my code, which
has a for loop. The for loop looks like
for (int i=0 ; i< end ; ++i )
{
//Code here.
}
Here end is a very large integer. The code does not crash at the first iteration, and seems to crash somewhere at iteration number end/2.
Since I want to understand the behaviour of the code at iteration number end/2 , just stepping and nexting from i=0 till I reach this iteration point, is unfeasible.
Is there a way to tell gdb to continue through a for loop till i gets the value end/2 and then wait for the user to manually step through iteration number end/2?
I am using gcc-4.5.2 on Ubuntu Linux
Here's a tutorial on conditional breakpoints with gdb.
I'm guessing you didn't know the term for this, otherwise it would have been easy to google.
When you set the breakpoint it'll give you a breakpoint number (for the moment, let's assume it's 1). You'll then make that breakpoint conditional, something like:
condition 1 i==end/2
You have to use conditional breakpoint. Here is more about it: http://www.cs.cmu.edu/~gilpin/tutorial/#3.4
And on SO: How do I set a conditional breakpoint in gdb, when char* x points to a string whose value equals "hello"?
In your case (not tested):
break <line_number> if i==end/2
You should be able to place an if (i == (end/2 -1)) { Foo; } in there then set a breakpoint at Foo, which would allow you to continue stepping from there.
If end is big (in the tens of thousands), then the conditional breakpoint solution can be very slow - gdb has to evaluate the condition each time round the loop. If this is a problem for you, then you can use this trick:
for (int i=0 ; i< end ; ++i )
{
if (i == end/2)
i %= end ; // This has no effect, but lets you set a breakpoint here
//Code here.
}
I do this all the time :-)
Another solution is to set a skip-count on the breakpoint. I use gdb in a Qt environment, so I can't give you the gdb syntax. But it's faster than setting a condition.