So my solution is to load a shared resource containing my debugging routines at runtime using dlopen. Turns out this is even easier than I thought when you get all the flag compilations.
In OS X, this means that you compile the application and debug it as follows:
all : application.x debug_helper.so application.x : application.cpp g++ -g application.cpp -o application.x -fPIC debug_helper.so : debug_helper.o g++ -dynamiclib -o debug_helper.so debug_helper.o debug_helper.o : debug_helper.cpp g++ -Wall -g -fPIC -c debug_helper.cpp
The -fPIC value for the application is critical, as is the -dynamiclib (instead of trying the linux -shared flag)
An example debug_helper.cpp might look like this:
#include <map> #include <stdio.h> extern "C" void printMap( const std::map<int,int> &m ) { printf("Map of size %d\n", int(m.size()) ); for( std::map<int,int>::const_iterator it = m.begin(); it!=m.end(); ++it ) { printf("%d : %d \n", it->first, it->second ); } fflush(stdout); }
I don’t know why I decided to use stdio and not iostream. I think you can use it too. (just remember to clear the threads ...)
Now my application file looks like this:
#include <map> int main() { std::map<int,int> m; m[1]=2; m[2]=5; m[3]=10; m[4]=17; }
And heres an example of debugging a session (some output removed)
Launch the app and break at an interesting point
(gdb) break main (gdb) run Reading symbols for shared libraries +++. done Breakpoint 1, main () at test.cpp:5 5 std::map<int,int> m;
Download to the debug helper library
(gdb) print (void*) dlopen("debug_helper.so",2) Reading symbols for shared libraries . done $1 = (void *) 0x100270 (gdb) n 6 m[1]=2;
GDB is smart and catches all new characters for us, so we don’t need to use dlsym etc. We can just call functions directly.
(gdb) call printMap(m) Map of size 0 (gdb) n (gdb) n (gdb) n 9 m[4]=17; (gdb) call printMap(m) Map of size 3 1 : 2 2 : 5 3 : 10
Allows you to add additional information to printMap. First unload the library.
(gdb) print (int) dlclose($1) $2 = 0
Edit the source you want to add to the sum of the records. Recompile and load the new library back into gdb (without restarting the executable or gdb)
(gdb) print (void*) dlopen("debug_helper.so",2) Reading symbols for shared libraries . done
Use the modified function
$3 = (void *) 0x100270 (gdb) call printMap(m) Map of size 3 1 : 2 2 : 5 3 : 10 SUM = 17
I think this does everything I need.