DTrace C++ Mysteries Solved
I’ve been using DTrace on Leopard in my recent work, and while it’s a great tool, the C++ support is confusing and I couldn’t find proper documentation. But eventually I found sketchy documentation that gave me the answers, so in the interest of saving others from pain:
Basic Call Profiling. One of the most basic profiling tasks is recording function call entries and returns. And DTrace is very good at this, using the pid provider. For example, if you have a simple C program ‘prog’ that contains a function ‘foo’, you can get DTrace to trace calls to ‘foo’ like this:
sudo dtrace -c './prog' -n 'pid$target:prog:foo:entry'
Unpacking this, the -c option starts a program and the process id in a special DTrace variable-type-thing called $target. The -n option specifies a probe to trace using DTrace’s standard 4-part syntax. In this case, the 4 parts are: (1) the provider, pid$target, which means user function call tracing in process $target, (2) prog, the module to trace functions in, (3) the function to trace, foo, and (4) entry, meaning we want function entries (as opposed to returns or other instructions). (Thanks to Vlad for giving me the verbal tutorial on this part.)
This time, with C++. So far, so good, but when you try to do this for C++ programs, some weirdness sets in. Let’s say our C++ program has a class C that contains a method bar that takes an int argument. This means the C-style symbol that the linker operates on is the mangled name, some junk like __ZN1C1barEi. According to Sun’s article on DTrace with C++, which is all I could find by Googling “dtrace c++” you use the mangled name in the provider specification, as in
sudo dtrace -c './prog' -n 'pid$target:prog:__ZN1C1barEi:entry'
But that didn’t work at all for me on Leopard. DTrace said “invalid probe specifier, blah, blah, blah”. I figured out part of the answer by trial and error, but I didn’t get the full answer until I remembered that Vlad suggested the support for demangled names might have been added as part of Objective C support, Googled “dtrace objective c”, found a blog post, followed a link from there to the Apple dtrace man page, saw the “-xmangled” option, Googled “xmangled”, and found an Apple mailing list thread. Ugh. Is there no better way to find documentation? (I guess I should be comparing with the effort of searching a wall full of manuals, and instead of complaining, I should be grateful that once again, Teh Mighty Interwebs have proven infinitely wise.)
Anyway, the answer is that on Leopard you can specify probes for C++ functions using either mangled names or unmangled names, with appropriate obscure incantations either way.
sudo dtrace -c './prog' -n 'pid$target:prog:C??f(int):entry'
The key is that you have to give the whole signature for the method, but you can’t have colons in there because the probe specification parser gets confused, so you use the ? wildcard instead. You can also abbreviate using other wildcards, as in C??f*.
sudo dtrace -c './prog' -n 'pid$target:prog:__ZN1C1barEi:entry' -xmangled
-xmangled tells DTrace to use the mangled names. If you do it this way, you’ll also see the mangled names in the output.