OSX “strace” equivalent: dtruss – seeing inside applications what they do and why they hang

I am running OSX desktops coming from Linux background. We cross-develop software both on OSX and Linux. I am familiar of debugging system issues on Linux using strace command and now I had to try something similar on OSX. strace prints out system calls a running application makes so you can see “inside” the application and see where it crashes, hangs, etc.

OSX doesn’t have strace, but has its equivalent dtrace which originates from Solaris and I believe it has replaced OSX ktrace, truss etc. commands since OSX 10.5 Leopard.

Here are brief instructions how I tracked down a non-working Subversion svn up command. svn was correctly updating some repositories, but not others and just hung which means it probably hung on some system call.

Turns out dtrace itself is a very low level framework which its own programming language. I just want to dump the system calls. So there exist an utility called dtruss for this purpose.

But the first attempt failed:

dtruss svn up
dtrace: failed to initialize dtrace: DTrace requires additional privileges

You could solve this by running dtruss as root, but we really don’t want to do that. You can enable normal user execution for dtruss / dtrace with the following command:

sudo chmod u+s /usr/sbin/dtrace

Now we dtruss get output:

dtruss svn up
...
write(0x5, "( set-path ( 0: 94 false ( ) infinity ) ) ( link-path ( 10:thirdparty 31:svn+ssh://repo-svn/thirdparty 107 false ( ) infinity ) ) ( finish-report ( ) ) \0", 0x9A)         = 154 0
read(0x6, "( success ( ( ) 0: ) ) ( failure ( ( 170000 82:'svn+ssh://repo-svn/thirdparty' is not the same repository as 'svn+ssh://indweb' 63:/build/buildd/subversion-1.6.12dfsg/subversion/svnserve/serve.c 310 ) ) ) \0", 0x1000)         = 207 0
fcntl(0x5, 0x3, 0x0)         = 1 0
fcntl(0x5, 0x4, 0x5)         = 0 0
write(0x5, "( failure ( ( 210001 25:Unknown command 'failure' 34:subversion/libsvn_ra_svn/editorp.c 887 ) ) ) \0", 0x62)         = 98 0
fcntl(0x5, 0x3, 0x0)         = 5 0
fcntl(0x5, 0x4, 0x1)         = 0 0
read(0x6, "( failure ( ( 210001 25:Unknown command 'failure' 70:/build/buildd/subversion-1.6.12dfsg/subversion/libsvn_ra_svn/marshal.c 931 ) ) ) \0", 0x1000)         = 134 0
__disable_threadsignal(0x1, 0x0, 0x0)         = 0 0

… and there it hangs. Unknown command “failure”. In the end this all was not very helpful and I decided just selfupdate Macports and take clean checkout.

1. More info

 

 Subscribe to RSS feed Follow me on Twitter Follow me on Facebook Follow me Google+

8 thoughts on “OSX “strace” equivalent: dtruss – seeing inside applications what they do and why they hang

  1. sudo chmod u+s /usr/sbin/dtrace

    You have just opened big security hole on your mac. Congratulations.

  2. Maybe some constructive criticism for the alternative way to do this?

    You know, it’s my local Mac. I use it for development. I need to run dtrace as root.

  3. I think the point is that you say “You could solve this by running dtruss as root, but we really don’t want to do that. You can enable normal user execution for dtruss / dtrace with … chmod u+s /usr/sbin/dtrace”.

    But your solution does *not* make dtrace/dtruss run as a normal user. Instead, now truss and trace will always run as root, for every user on the system, and not just if invoked as “sudo dtruss”.

    So it’s better to run truss as an admin user via “sudo truss …”.

    Note that dtruss and dtrace are particularly bad to run setuid root (chmod u+s) because any user or malware with access to the system can now invoke “dtruss some_command” and run any command whatsoever they like as root. This is probably not what you want, and certainly not something to recommend generally on the net.

  4. sudo dtruss [dtruss_options] -f sudo -u $USER myprogram [program_options]

    is the safe way to run it

  5. To amplify on an old thread: After you make dtruss setuid, it runs as root; that means the programs you have dtruss kick off also run as root. So if you have a guest user on the system (or a piece of malicious code running by what ought to be a compartmentalized, limited system account) it can simply say “dtruss bash” and voila, it is running a shell as root and can basically do *anything* on your system.

  6. Thanks @Chip and @flummoxer. But in El Capitan I get thissudo dtruss -f sudo -u UnpriviledgedUser MyCommand
    Password:
    dtrace: failed to execute sudo: dtrace cannot control executables signed with restricted entitlements

    How can I trace the execution of MyCommand, a #!/usr/bin/python script? Thanks!

  7. @Mikko, I’m not certain how to be “constructive” about this.

    When you `chmod u+s` a file, you are creating a new setuid executable containing code which was never meant to run with elevated privs which now runs with elevated privs. As someone who used to actively break security (on systems under my control) you’ve just created another avenue of attack for me. The executable was not designed to invoke itself setuid so it won’t drop privs itself, and any bugs that it has which would normally harmlessly cause a segfault are now potentially usable to run arbitrary code as the root user.

    Please use `sudo` and not `chmod u+s` and don’t offer the latter as a suggestion on how to work around this kind of problem. Its actually better just to drop in to a root shell than to set a binary to setuid, you’re creating more problems than you’re solving.

Leave a Reply

Your email address will not be published. Required fields are marked *