GDB breakpoints won't work after the function address changed. Is it possible to tell gdb to relocate the function address when running the program?
GDB breakpoints won't work after the function address changed
That depends on how you set a breakpoint.
If you did break *0x12345, then you must update the breakpoint if on re-build and re-run the address you care about is different.
On the other hand, if you did break foo, and the &foo changes due to a re-build, GDB will automatically reset the breakpoint on the new address on re-run. (If GDB doesn't do it for you, that's a bug in GDB.)
Related
When ive attached the visual studio debugger to a process, then add a new function breakpoint, and choose e.g. "system" as the function name. Visual studio will then detect whenever the system() function is called from the target process.
Is there any efficient way to detect function calls from a process using c++?
A debugger detects that a breakpoint has been hit in several ways.
The basic strategy is the software breakpoint. This means that the debugger replaces an instruction at the breakpoint target with a breakpoint trap instruction.
When the execution hits the breakpoint instruction, a CPU exception is caused which is then handled via the debugger. The debugger sees that execution has stopped at a certain address, and for a certain reason, and that confirms to it that the breakpoint has been hit.
Lastly, implementing breakpoint debugging is possible even without the help from a breakpoint instruction. A software breakpoint could be inserted into the target code as ordinary branch instruction that jumps into a routine inside debugger, rather than raising CPU exception which is handled through the debugger.
In addition to this, processors can (and do) support hardware breakpoints. Usually a very limited number of hardware breakpoints can be configured in the processor which tell it to stop at a certain address. This is less intrusive than a software breakpoint, and will work even if the code is in read-only memory.
Of course if you have a software breakpoint, the missing instruction which has been replaced has to be executed when the execution is restarted. The debugger must put the original instruction in place before resuming. But if that is all that is done, the breakpoint will effectively disappear. The breakpoint must be re-armed so that execution will stop if it is hit again. To achieve that, the debugger can put the processor into single step mode. It can replace the original instruction, then step the code in single step mode, then put in the software breakpoint again and resume.
If the processor doesn't have a single step mode, but only a break instruction, then the processor can simulate single stepping using a temporary software breakpoint (one that doesn't have to be re-armed once executed).
I have a C++ application where somehow, gdb (I'm using the mingw-w64 version) always seems to be confused about what address the main executable is loaded at. If I try to insert a breakpoint on some function or file+line number, gdb tries to do it at the wrong address and the breakpoint doesn't work. It also can't produce backtraces. I can see that the address it uses is wrong by adding a printf showing the address of some function, and comparing it with the one gdb uses with break someFunction (or print &someFunction). On the other hand, for functions located in DLLs, gdb can successfully insert a breakpoint or produce a backtrace (at least until a function in the executable is reached).
I don't know why this happens, but it would be nice to be able to use the debugger anyway. Assuming the hypothesis of a wrong address for the executable's code segment, is there some way I can adjust it to be at the right place? The gdb versions I've tried are 7.9 and 8.0.1.
A basic question & I am very new to C/C++ and GDB.
We use GDB to debug a process. We attach GDB to a process and then specify filename.c along with line number to put break point.
My question is "How would GDB or OS OR possibly anything else know that it has to break at specified line number (in filename.c) after we connect GDB to running process?"
What is coming into picture that, say, the current process is run in debug mode and a breakpoint is applied and the process execution has to break (wait for user input) at that point?
The same way that if your program stops or crashes at a particular point, the debugger can tell you where in the program that point is.
For both of these to work the program binary must contain additional debugging information that associates addresses in the program image with locations in the source code (source file and line number.)
To add a breakpoint at a particular line the debugger finds the program address closest to that line, modifies the copy of the executable in memory to insert a special "break" instruction at that location which will cause the program's execution to be interrupted, then "traces" the program's execution and waits for it to reach the breakpoint and stop.
For more details see http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1/ and http://www.howzatt.demon.co.uk/articles/SimplePTrace.html
I can't comment for the latest version of gdb - but many debuggers actually swap the assembly instruction at the desired breakpoint location (in memory) with an interrupt instruction. This "wakes up" the debugger which takes control at this point.
Using a substituted interrupt instruction means that the CPU can execute your program at full speed and "trip up" at the desired location.
Modern processors are very complex, however, and probably have far superior debugging features.
GDB is aware of your code : it knows all about it. When you set a breakpoint at a line, GDB gets the equivalant machine instruction address : all your code (as machine instructions) is loaded in memory, so the instructions of your code have an address.
So now GDB knows the adress of the instruction you want to break. When you run your programm, GDB will use ptrace, which allow GDB to "see" each instructions before their execution. Then GDB have just to look if the current instruction (which will be executed) is the same as your instruction (that you want to break).
I have been using gdb for most of a decade now and have never seen this particular problem. I upgraded to gdb 7.4 and the problem persists.
I am debugging a Cilk-multithreaded C++ application on RHEL5. Execution ceases at a seg fault. When I ask gdb to print the value of certain variables (which are boost::intrusive_ptr references to templated object instances) gdb will print the proper value, but will also resume execution on all threads for a very short time. I suspect it resumes execution because more of my debug print statements scroll to the terminal (it's not just clearing a buffer---I can keep printing it and it keeps resuming execution). This short spurt of continued execution causes the values of the variables I am tracking to change. This hinders debugging, to say the least.
I suspect that I have a memory leak and the stack is getting corrupted, but I've run valgrind on the code (with different initial conditions) and it shows no memory leaks in the major subsystem that I am debugging, except for a nominal Cilk-internal leak.
When I ask gdb to print the value of certain variables (which are boost::intrusive_ptr references to templated object instances) gdb will print the proper value, but will also resume execution on all threads for a very short time.
The only way that I know of for this to happen is if you have
A python pretty-printer for the type (boost::intrusive_ptr) and
That pretty-printer calls back into the inferior (being debugged) process.
You can disable all pretty-printers by e.g. disable pretty-printer. If that helps, you should probably figure out which exact pretty-printer is doing this, and contact its author.
Is there a way for my code to be instrumented to insert a break point or watch on a memory location that will be honored by gdb? (And presumably have no effect when gdb is not attached.)
I know how to do such things as gdb commands within the gdb session, but for certain types of debugging it would be really handy to do it "programmatically", if you know what I mean -- for example, the bug only happens with a particular circumstance, not any of the first 11,024 times the crashing routine is called, or the first 43,028,503 times that memory location is modified, so setting a simple break point on the routine or watch point on the variable is not helpful -- it's all false positives.
I'm concerned mostly about Linux, but curious about if similar solutions exist for OS X (or Windows, though obviously not with gdb).
For breakpoints, on x86 you can break at any location with
asm("int3");
Unfortunately, I don't know how to detect if you're running inside gdb (doing that outside a debugger will kill your program with a SIGTRAP signal)
GDB supports a scripting language that can help in situations like this. For example, you can trigger a bit of custom script on a breakpoint that (for example) may decided to "continue" because some condition hasn't been met.
Not directly related to your question, but may be helpful. Have you looked at backtrace and backtrace_symbol calls in execinfo.h
http://linux.die.net/man/3/backtrace
This can help you log a backtrace whenever your condition is met. It isn't gdb, so you can't break and step through your program, but may be useful as a quick diagnostic.
The commonly used approach is to use a dummy function with non-obvious name. Then, you can augment your .gdbinit or use whatever other technique to always break on that symbol name.
Trivial dummy function:
void my_dummy_breakpoint_loc(void) {}
Code under test (can be an assert-like macro):
if (rare_condition)
my_dummy_breakpoint_loc();
gdb session (obvious, eh?):
b my_dummy_breakpoint_loc
It is important to make sure that "my_dummy_breakpoint_loc" is not optimized away by compiler for this technique to work.
In the fanciest of cases, the actual assembler instruction that calls my_dummy_breakpoint_loc can be replaced by "nops" and enabled on site by site basis by a bit of code self-modification in run-time. This technique is used by Linux kernel development instrumentation, to name a one example.