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.
Related
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'
I 'm wondering if it 's possible to create a script that will continue the program 's execution (after a break) step by step based on the memory address value.
So, if I 'm tracing a function and it goes into a high memory value, I 'd call the gdb script until the memory value is below a set value - then it would break again.
I 'm very new to gdb and still reading the manual/tutorials, but I 'd like to know if my goal is possible :) - and if you could bump me to the proper direction, even better ;)
Thanks!
Edit, updated with pseudocode:
while (1) {
cma = getMemoryAddressForCurrentInstruction();
if (cma > 0xdeadbeef) {
stepi;
} else {
break;
}
}
You're talking about the Program Counter (sometimes called the instruction pointer). It's available in gdb as $pc. Your pseudocode can be translated into this actual gdb command:
while $pc <= 0xdeadbeef
stepi
It'll be slow, since it's starting and stopping the program for every instruction, but as far as I know there's no fast way to do it if you don't know exactly what address you're looking for. If you do, then you can just set a breakpoint there:
break *0xf0abcdef
cont
will run until the program counter hits 0xf0abcdef
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.
I am trying to find an error in my code. The problem is the error occurs in a loop. But the loop iterates about 500 times. Instead of clicking through the loop. Is it possible to skip over a certain amount of the loop ??
VS allows you to set a condition on a breakpoint in terms of variables that are in scope. So, in your case, you can test against the loop counter.
Here is a crude answer:
if ((iter % 10) == 0) {
int stop = 1;
}
Then place a break-point at "int stop = 1;". Perhaps, there is a better way in VS but this is what I do from time-to-time.
You can assign new values to variables during debug session. Step through the loop statements as many times as you like, then set your loop counter (or whatever other vars maintain loop condition) to terminate the loop.
Just put the breakpoint in the loop like indicated below >>. Use F5 to get to the condition that causes failure so you can loop through the individual pass. How to know where to break is up to you.
for (int i = 0; i < LOOPMAX; i++) {
>>some_proc(i);
some_other_proc(i);
some_third_proc(i);
}
By pressing F5 it'll continue running till it gets to the next breakpoint (the next pass through the code). Sure you'll have to hit it 500 times, but that beats some thousands of times. Combine this with #Troubador code above.
PS: This answer IS really simple, but some people don't know they can do this.
I'm trying to debug a method which among other things, adds items to a list which is local to the method.
However, every so often the list size gets set to zero "midstream". I would like to set the debugger to break when the list size becomes zero, but I don't know how to, and would appreciate any pointers on how to do this.
Thanks.
Why not use conditional breakpoints?
http://blogs.msdn.com/saraford/archive/2008/06/17/did-you-know-you-can-set-conditional-breakpoints-239.aspx
in C#
if(theList.Count == 0){
//do something meaningless here .e.g.
int i = 1; // << set your breakpoint here
}
in VB.NET
If theList.Count = 0 Then
'do something meaningless here .e.g.
Dim i = 1; ' << set your breakpoint here
End If
For completeness sake, here's the C++ version:
if(theList->Count == 0){
//do something meaningless here .e.g.
int i = 1; // << set your breakpoint here
}
I can give a partial answer for Visual Studio 2005. If you open the "Breakpoints" window (Alt + F9) you get a list of breakpoints. Right-click on the breakpoint you want, and choose "Condition." Then put in the condition you want.
You have already got both major options suggested:
1. Conditional breakpoints
2. Code to check for the wrong value, and with a breakpoint if so happens
The first option is the easiest and best, but on large loops it is unfortunately really slow! If you loop 100's of thousands iterations the only real option is #2. In option #1 the cpu break into the debugger on each iteration, then it evaluates the condition and if the condition for breaking is false it just continiues execution of the program. This is slow when it happens thousands of times, it is actually slow if you loop just 1000 times (depending on hardware of course)
As I suspect you really want an "global" breakpoint condition that should break the program if a certain condition is met (array size == 0), unfortunately that does not exist to my knowledge. I have made a debugging function that checks the condition, and if it is true it does something meaningless that I have a breakpoint set to (i.e. option 2), then I call that function frequently where I suspect the original fails. When the system breaks you can use the call stack to identify the faulty location.