<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Chris Ball: Tracing internal function calls in a binary</title>
    <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Tracing internal function calls in a binary</title>
      <description>&lt;p&gt;Dear everyone who likes Unix,&lt;/p&gt;

&lt;p&gt;I have a binary (which uses glib and was compiled from C) and I'd like to get output with the function name each time any function in that binary is called.  So, I'd like the output of &lt;code&gt;ltrace(1)&lt;/code&gt;, but for function calls rather than dynamic library calls.  I am bored of adding   &lt;code&gt;g_debug("%s", G_STRFUNC);&lt;/code&gt; to the top of all my functions.&lt;/p&gt;

&lt;p&gt;You'd think this would be easy, given that incredibly similar tools have existed for twenty years, but so far the shortest answer I've heard starts "well, you could write a gcc profile function stub that..".  It would be nice not have to recompile, since gdb certainly doesn't have to, but I'd welcome the way to achieve this with a recompile as well.&lt;/p&gt;

&lt;p&gt;Any ideas?  Thanks!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: &lt;a href="http://superadditive.com"&gt;jmbr&lt;/a&gt; wins, with the only solution that doesn't require anything more than gdb, and no recompile.  Here's his script:  &lt;a href="http://superadditive.com/software/callgraph"&gt;http://superadditive.com/software/callgraph&lt;/a&gt;.  I'd like to work on it to add support for modules loaded with &lt;code&gt;dlopen()&lt;/code&gt;.&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 20:27:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:bb5862a9-05e1-48fc-bc29-b6e373cd548a</guid>
      <author>Chris Ball</author>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary</link>
      <category>linux</category>
      <category>c</category>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by TomTromey</title>
      <description>&lt;p&gt;Like Mark said, ftrace -- part of frysk -- can do this.  frysk has a lot of potential for fun stuff like this; last year I was playing around writing jython scripts to debug things.  Back then frysk wasn't mature enough to do much interesting, but this has changed.&lt;/p&gt;

&lt;p&gt;Also ltrace can do it for things loaded from shared libraries.  Unfortunately this doesn't work with the main executable.  You could hack around this, though, by having a small main and then putting the rest of your program into a .so.&lt;/p&gt;

&lt;p&gt;Pace Federico, but systemtap can't do userspace yet.  However, that is also coming.&lt;/p&gt;

&lt;p&gt;Finally, I wonder if a valgrind skin exists to do this.&lt;/p&gt;</description>
      <pubDate>Wed, 05 Dec 2007 01:10:37 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:4b51e119-aa5c-4f98-9db9-6d8b20ae22aa</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37230</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by John Levon</title>
      <description>&lt;p&gt;It's easy with DTrace:&lt;/p&gt;

&lt;p&gt;dtrace -n 'pid&lt;em&gt;:::entry, pid&lt;/em&gt;:::return {}' -c /bin/mycommand&lt;/p&gt;</description>
      <pubDate>Mon, 03 Dec 2007 01:51:03 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:ab15bd02-725f-4625-9745-f587837d14f7</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37220</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Rob</title>
      <description>&lt;p&gt;LTTng can apparently do this, but I have to admit I haven't got it working yet!&lt;/p&gt;</description>
      <pubDate>Sun, 02 Dec 2007 13:43:39 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a79b3bf5-1b11-45e6-a6ae-25b3070e18f8</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37217</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Ross</title>
      <description>&lt;p&gt;oprofile can't do this, because it's a statistical profiler.  If you have a function which is called frequently but very short, it may never notice it being called.&lt;/p&gt;</description>
      <pubDate>Sun, 02 Dec 2007 08:32:29 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a318e44c-8c15-44e8-a933-b99447c0a9de</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37215</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Stoffe</title>
      <description>&lt;blockquote&gt;
    &lt;p&gt;I thought that oprofile could do this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, are you surprised to learn that it can't, or are you trying to be helpful but in a smug oh-look-I-know-more-than-someone-else-on-the-internet way?&lt;/p&gt;

&lt;p&gt;If you are trying to be helpful, the grown up way to do that is saying "oprofile will do want you want".&lt;/p&gt;

&lt;p&gt;Thanks.&lt;/p&gt;</description>
      <pubDate>Sat, 01 Dec 2007 09:26:41 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:c6303aad-29c8-49f8-8d47-15c05bfe534a</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37214</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Davyd</title>
      <description>&lt;p&gt;I thought that oprofile could do this.&lt;/p&gt;</description>
      <pubDate>Sat, 01 Dec 2007 01:30:18 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:c0053a70-d8a4-41ac-bdd0-7fc4a9f8ea2e</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37213</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Chris</title>
      <description>&lt;p&gt;Hi Toby!&lt;/p&gt;

&lt;p&gt;Yes, your example is what one of my coworkers recommended (but he didn't have code handy, so thanks for that).&lt;/p&gt;

&lt;p&gt;It's clear that a gdb solution is preferable, though.  I wonder if a patch to accomplish jmbr's hack through a "trace *"-like syntax would be accepted upstream.&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 23:56:10 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:8607a6e5-9aa6-4204-adf6-f03ba0c8cfd6</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37212</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Chris</title>
      <description>&lt;p&gt;Ian, many thanks to you too -- I also like the look of etrace.&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 23:37:19 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:193966d6-4985-47bb-ad3d-298d8c39b484</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37211</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Chris</title>
      <description>&lt;p&gt;jmbr, thanks so much!  This looks perfect, and works.  &lt;/p&gt;

&lt;p&gt;My process opens some shared libraries with the glib module_open() call, though, and those obviously don't get breakpoints set ahead of time.  &lt;/p&gt;

&lt;p&gt;Those libraries have individual debuginfo files in /usr/lib/debug; I'm going to try doing &lt;code&gt;nm /usr/lib/debug/foo/*.debug&lt;/code&gt; and massaging the output so that it fits into the trace.gdb style, then I'll hope that gdb can resolve the functions once they're dynamically loaded.  Can anyone think of a reason this won't work, or a better way?  :)&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 23:31:41 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:4d931e09-29b6-42e2-bade-72805bbaa7a3</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37210</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Mark Wielaard</title>
      <description>&lt;p&gt;You might want to check out frysk
&lt;a href="http://www.sourceware.org/frysk/" rel="nofollow"&gt;http://www.sourceware.org/frysk/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It very recently (read today) got various function and syscall tracing options merged in by Petr Machata:
&lt;a href="http://sourceware.org/ml/frysk/2007-q4/msg00164.html" rel="nofollow"&gt;http://sourceware.org/ml/frysk/2007-q4/msg00164.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;man page explaining the different options of call tracing:
&lt;a href="http://sourceware.org/git/?p=frysk.git;a=blob;f=frysk-core" rel="nofollow"&gt;http://sourceware.org/git/?p=frysk.git;a=blob;f=frysk-core&lt;/a&gt;/frysk/bindir/ftrace.xml;hb=HEAD&lt;/p&gt;

&lt;p&gt;I am afraid you will have to build it from a current git checkout for now though:
&lt;a href="http://sourceware.org/frysk/build/" rel="nofollow"&gt;http://sourceware.org/frysk/build/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you might find some bugs, but we welcome reports!
&lt;a href="http://sourceware.org/bugzilla/" rel="nofollow"&gt;http://sourceware.org/bugzilla/&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 23:28:18 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:767079c5-98d2-4495-b90d-ada5f6348ef0</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37209</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Toby Jaffey</title>
      <description>&lt;p&gt;I'd do it with instrumentation as you can recompile, but etrace looks a bit heavyweight.&lt;/p&gt;

&lt;p&gt;Here's a contrived example showing how to add the hooks, compile the code and get a live trace.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://the.earth.li/~toby/hello.c" rel="nofollow"&gt;http://the.earth.li/~toby/hello.c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;:)&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 23:06:05 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:bee877fa-b9d7-4ec8-93a2-920940691045</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37208</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Ian McKellar</title>
      <description>&lt;p&gt;If you can recompile you can play with GCC's function instrumentation feature. Google found this: &lt;a href="http://ndevilla.free.fr/etrace/" rel="nofollow"&gt;http://ndevilla.free.fr/etrace/&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 22:44:30 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3cd759a7-ecbd-4faf-9e34-fbd4d622d961</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37207</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Federico Mena Quintero</title>
      <description>&lt;p&gt;Dtrace can do this.&lt;/p&gt;

&lt;p&gt;I'm not sure if Systemtap can dive into userspace these days, or if they have a related tool for that.&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 22:06:06 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:14579145-5e72-4fe6-89a8-d535d0c12f4c</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37205</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by jmbr</title>
      <description>&lt;p&gt;Hi Chris,&lt;/p&gt;

&lt;p&gt;My hack to achieve is to compile the program using gcc's -g option and take control of gdb.  The technique is illustrated in the following script:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://superadditive.com/software/callgraph" rel="nofollow"&gt;http://superadditive.com/software/callgraph&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope it helps&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 21:54:18 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:10a8ff41-24f1-4eee-a429-2d7408edc732</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37204</link>
    </item>
    <item>
      <title>"Tracing internal function calls in a binary" by Andrew Sutherland</title>
      <description>&lt;p&gt;Have you looked at chronicle recorder (&lt;a href="http://code.google.com/p/chronicle-recorder/" rel="nofollow"&gt;http://code.google.com/p/chronicle-recorder/&lt;/a&gt;)?  It's arguably a bit heavy-weight; you are running your program under valgrind, resulting in a complete execution trace.  But it can tell you all the functions that were called, what their arguments were, and other exciting debugging functionality from the year 2020.  (But the run will be slow...)&lt;/p&gt;</description>
      <pubDate>Fri, 30 Nov 2007 21:22:06 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:92b6e05e-6f3b-46eb-8812-0e1f4025a81b</guid>
      <link>http://blog.printf.net/articles/2007/11/30/tracing-internal-function-calls-in-a-binary#comment-37203</link>
    </item>
  </channel>
</rss>
