Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So my solution is to load a shared object containing my debugging routines at run time, using dlopen. Turns out it is even simpler than I thought when you get all the compile flags right.</p> <p>On OS X this means you compile your application and debugging object like this:</p> <pre><code>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 </code></pre> <p>The -fPIC on the application is critical, as is the -dynamiclib (rather than trying the linux -shared flag )</p> <p>An example debug_helper.cpp might look like this</p> <pre><code>#include &lt;map&gt; #include &lt;stdio.h&gt; extern "C" void printMap( const std::map&lt;int,int&gt; &amp;m ) { printf("Map of size %d\n", int(m.size()) ); for( std::map&lt;int,int&gt;::const_iterator it = m.begin(); it!=m.end(); ++it ) { printf("%d : %d \n", it-&gt;first, it-&gt;second ); } fflush(stdout); } </code></pre> <p>Don't know why I chose to use stdio rather than iostream stuff... I guess you can use either. (just don't forget to flush the streams...)</p> <p>Now my application file looks like this:</p> <pre><code>#include &lt;map&gt; int main() { std::map&lt;int,int&gt; m; m[1]=2; m[2]=5; m[3]=10; m[4]=17; } </code></pre> <p>And heres an example debugging session (some output removed)</p> <p>Start the application and break at an interesting point</p> <pre><code>(gdb) break main (gdb) run Reading symbols for shared libraries +++. done Breakpoint 1, main () at test.cpp:5 5 std::map&lt;int,int&gt; m; </code></pre> <p>Load in the debug helper library</p> <pre><code>(gdb) print (void*) dlopen("debug_helper.so",2) Reading symbols for shared libraries . done $1 = (void *) 0x100270 (gdb) n 6 m[1]=2; </code></pre> <p>GDB is smart and catches all the new symbols for us so we dont need to use dlsym etc. We can just call the functions directly.</p> <pre><code>(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 </code></pre> <p>Lets add some more info to printMap. First unload the library.</p> <pre><code>(gdb) print (int) dlclose($1) $2 = 0 </code></pre> <p>Edit the source to add in the sum of the entries. Recompile and then load the new library back into gdb (without restarting the executable or gdb )</p> <pre><code>(gdb) print (void*) dlopen("debug_helper.so",2) Reading symbols for shared libraries . done </code></pre> <p>Use the modified function</p> <pre><code>$3 = (void *) 0x100270 (gdb) call printMap(m) Map of size 3 1 : 2 2 : 5 3 : 10 SUM = 17 </code></pre> <p>I think this does everything that I need.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload