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
Related
I have some code that calculates the price of a stock option using Monte Carlo and returns a discounted price. The final few lines of the relevant method look like this:
if(payoffType == pt.LongCall or payoffType == pt.LongPut):
discountedPrice=discountedValue
elif(payoffType == pt.ShortCall or payoffType == pt.ShortPut):
discountedPrice=(-1.0)*discountedValue
else:
raise Exception
#endif
print "dv:", discountedValue, " px:", discountedPrice
return discountedPrice
At a higher level of the program, I create four pricers, which are passed to instances of a portfolio class that calls the price() method on the pricer it has received.
When I set the breakpoint on the if statement or the print statement, the breakpoints work as expected. When I set the breakpoint on the return statement, the breakpoint is interpreted correctly on the first pass through the pricing code, but then skipped on subsequent passes.
On occasion, if I have set a breakpoint somewhere in the flow of execution between the first pass through the pricing code and the second pass, the breakpoint will be picked up.
I obviously have a workaround, but I'm curious if anyone else has observed this behavior in the PyDev debugger, and if so, does anyone know the root cause?
The issues I know of are:
If you have a StackOverflowError anywhere in the code, Python will disable the tracing that the debugger uses.
I know there are some issues with asynchronous code which could make the debugger break.
A workaround is using a programmatic breakpoint (i.e.: pydevd.settrace -- the remote debugger session: http://www.pydev.org/manual_adv_remote_debugger.html has more details on it) -- it resets the tracing even if Python broke it in a stack overflow error and will always be hit to (the issue on asynchronous code is that the debugger tries to run with untraced threads, but sometimes it's not able to restore it on some conditions when dealing with asynchronous code).
I have a nondeterministic memory corruption problem. Because it's not always the same address, and it occurs only rarely, I can't simply watchpoint it with gdb.
The problem is a value changes between point A and point B in my program. The only thing that is supposed to change it is point C, which does not run in that time (at least not for the specific instance that experiences the unexpected modification).
What I'd like to do is something like mprotect the value at point A so the machine will trap if it is modified and unprotected it again around the intentional modification at point C. Of course, mprotect is not meant to be taken literally as I need it to work with word granularity.
Simply watchpointing at point A manually with gdb is far too much toil, the frequency of the problem is only about one per thousand.
Ideally, I would like a stack trace at the point that modifies it.
Any ideas?
Update: I just found out about rr http://rr-project.org/, a tool that can allegedly "determinize" non-determinism problems. I'm going to give it a go.
Update2: Well that was a short trip:
[FATAL /build/rr-jR8ti5/rr-4.1.0/src/PerfCounters.cc:167:init_attributes() errno: 0 'Success']
-> Microarchitecture `Intel Merom' currently unsupported.
You are experiencing undefined behavior and it's being caused somewhere else, debugging this is really hard.
Since you are apparently on Linux, use valgrind and it will help you a lot. If you are not on Linux or (OS X which is also supported by valgrind), search for equivalent memory error detection software for your system.
I found that it isn't that difficult to script gdb in a scripting language that you know (in my case, Ruby). This cuts down on the need to learn how to make proper gdb scripts!
The API between the target program and the script is that the target program has a blank function called my_breakpoint that accepts a single machine word as an argument. Calling my_breakpoint(1); my_breakpoint(addr); adds an address to the watch list while the same thing with the constant 2 removes an address from the watch list.
To use this, you need to start gdbserver 127.0.0.1:7117 myapp myargs, and then launch the following script. When the script detects a problem, it disconnects cleanly from gdbserver so that you can reconnect another instance of gdb with gdb -ex 'target remote 127.0.0.1:7117' and off you go.
Note that it's extremely slow to use software watchpoints like this; maybe someday something like this can implemented as valgrind tool.
#!/usr/bin/env ruby
system("rm -f /tmp/gdb_i /tmp/gdb_o");
system("mkfifo /tmp/gdb_i /tmp/gdb_o");
system("killall -w gdb");
system("gdb -ex 'target remote 127.0.0.1:7117' </tmp/gdb_i >/tmp/gdb_o &");
$fo = File.open("/tmp/gdb_i", "wb");
$fi = File.open("/tmp/gdb_o", "rb");
def gdb_put(l)
$stderr.puts("gdb_out: #{l}");
$fo.write((l + "\n"));
$fo.flush;
end
gdb_put("b my_breakpoint");
gdb_put("set can-use-hw-watchpoints 0");
gdb_put("c");
$state = 0;
$watchpoint_ctr = 1; # start at 1 so the 1st watchpoint gets 2, etc. this is because the breakpoint gets 1.
$watchpoint_nr = {};
def gdb_got_my_breakpoint(x)
$stderr.puts("my_breakpoint #{x}");
if ((x == 1) || (x == 2))
raise if ($state != 0);
$state = x;
gdb_put("c");
else
if ($state == 1)
raise if ($watchpoint_nr[x].nil?.!);
$watchpoint_nr[x] = ($watchpoint_ctr += 1);
gdb_put("watch *#{x}");
elsif ($state == 2)
nr = $watchpoint_nr[x];
if (nr.nil?)
$stderr.puts("WARNING: ignoring delete request for watchpoint #{x} not previously established");
else
gdb_put("delete #{nr}");
$watchpoint_nr.delete(x);
end
end
$state = 0;
gdb_put("info breakpoints");
$stderr.puts("INFO: my current notion: #{$watchpoint_nr}");
gdb_put("c");
end
end
def gdb_got(l)
t = l.split;
if ((t[0] == "Breakpoint") && (t[2] == "my_breakpoint"))
gdb_got_my_breakpoint(t[3][3..-2].to_i);
end
if (l.start_with?("Program received signal ") || l.start_with?("Watchpoint "))
gdb_put("disconnect");
gdb_put("q");
sleep;
end
end
while (l = $fi.gets)
l = l.strip;
$stderr.puts("gdb_inp: #{l}");
gdb_got(l);
end
At the moment I'm using an eclipse-like IDE and the corresponding debug perspective, that most of you are probably familiar with. While debugging code I quite often find myself stepping through many lines of code and observing variables and double checking if everything is as it is supposed to be.
But suppose there is something like this:
1. important line, e.g. generating a new object;
2. another important line, e.g. some tricky class method;
3. for (int i = 0; i < some_limit; ++i)
4. some_array[i]++;
5. more important stuff;
Obviously I'm interested in what happens in lines 1,2 and 5 (I know this is a poor example, but please bear with me for a little while longer) but I don't want to step through all hundreds (or even thousands) of iterations of lines 3/4.
So, finally, my question: Is there some way to step directly over the for-cycle? What I do right now is set a new breakpoint at line 5 and let the program run as soon as I hit line 3 and I believe this is not an optimal solution.
edit: The eclipse implementation of what ks1322 proposed is called "Run to line" and is mapped to ctrl-r
Use until command instead of next.
From gdb documentation:
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.
If you will use until instead of next, gdb will step over loops only once, which almost exactly what you want.
If I set a watchpoint for a variable local to the current scope, it will be auto deleted when going out of the scope. Is there any way to set it once and keep it auto alive whenever entering the same scope?
Is there anyway to set conditional watchpoint, like watch var1 if var1==0? In my case, the condition does't work. gdb stops whenever var1's value is changed, instead of untill var1 == 0 is true. My gdb is GNU gdb 6.8-debian.
I agree with Dave that a conditional breakpoint is the way to go.
However, to do what you asked, you can use GDB's commands command to set a list of GDB commands to execute whenever a breakpoint is hit. I find this incredibly useful.
I suggest writing your GDB commands into a file so that they are easy to edit and easy to reload with the source command. Or you can specify command files to load on the GDB command line or use .gdbinit to make them load automatically.
An example of a good use of commands:
Suppose that I have a function format that is called by a lot of other functions. I want to break on it, but only after function do_step_3 has been called.
break do_step_3
commands
break format
continue
end
You could use this for your problem with something like:
break func
commands
watch var
continue
end
You can set conditions on watchpoints in the same way that you do with breakpoints. This is in the documentation but admittedly it hardly calls attention to itself.
So watch my_var if my_var > 3 works just fine, as does the condition command.
To recreate the watchpoint if the variable it is watching goes out of scope, have gdb do this automatically using a breakpoint at the start of the function as Zan has described.
You can set a watchpoint that does not go out of scope by setting it to the memory address.
(gdb) p &var1
$1 = (int *) 0x41523c0
(gdb) watch *(int *)0x41523c0
Hardware watchpoint 1: *(int *)0x41523c0
This also works for other data types and pointers.
I'm not sure which language us are using, so the exact answer will vary, but could you change the variable to either be static, global, or dynamically allocated (and don't free it when the function returns?). This way it's raw address won't change, and gdb will be able breakpoint on it.
Instead of watching the value whe it equals a specific value; you should set a conditional break point on the line where you want to check the value of var1. This should effectively have the same effect
e.g.
(gdb) break main.c:123 if (var1 == 0)
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.