How can I get dtrace to run the traced command with non-root priviledges?

The easiest way is to use sudo:

sudo dtruss -f sudo -u $USER whoami

Other solution would be to run the debugger first and monitor for new specific processes. E.g.

sudo dtruss -fn whoami

Then in another Terminal simply run:

whoami

Simple as that.

More tricky arguments you can find in the manual: man dtruss


Alternatively you can attach dtruss to the running user process e.g. on Mac:

sudo dtruss -fp PID

or similar on Linux/Unix by using strace:

sudo strace -fp PID

Another hacky trick could be to execute the command and right after that attach to the process. Here are some examples:

sudo true; (./Pages &); sudo dtruss -fp `pgrep -n -x Pages`
sudo true; (sleep 1 &); sudo dtruss -fp `pgrep -n -x sleep`
sudo true; (tail -f /var/log/system.log &); sudo dtruss -fp `pgrep -n -x tail`

Note:

  • first sudo is just for caching the password at the first time of running,

  • this trick doesn't work for quick command lines like ls, date as it takes some time untill debugger will attach to the process,

  • you have to type your command in two places,

  • you can ignore & to run the process to the background, if it's already doing that,

  • after finishing debugging, you'll have to manually kill the background process (e.g. killall -v tail)


I don't know if you can get dtruss to be as noninvasive as strace.

A variant of the "sudo [to root] dtruss sudo [back to nonroot] cmd" that seems to work better in some quick testing for me is:

sudo dtruss -f su -l `whoami` cd `pwd` && cmd....

The outer sudo is of course so dtruss runs as root.

The inner su is back to me, and with -l it recreates the environment properly, at which point we need to cd back to where we started.

I think "su -l user" is better than "sudo -u user" if you want the environment to be what that user normally gets. That'll be their login environment though; I don't know if there's a good way to let the environment inherit through the two user changes instead.

In your question, one additional complaint that you had about the "sudo dtruss sudo" workaround, other than ugliness, was that "I get no a.out file at all this time, not sure why". I don't know why either, but in my little test script, a "sudo dtruss sudo" variant also failed to write to a test output file, and the "sudo dtruss su" variant above did create the output file.


Not an answer to your question but something to know. OpenSolaris solved this issue (partially) with "privileges" - see this page. Even in OpenSolaris, it wouldn't be possible to allow an user, without any extra privileges, to dtruss their own process. The reason is the way dtrace works - it enables probes in the kernel. So allowing a non-privileged user to probe kernel means the user can do lot of unwanted things e.g. sniffing other user's passwd by enabling probes in keyboard driver!


The -n argument to dtruss will cause dtruss to wait and examine processes that match the argument to -n. The -f option will still work to follow processes forked from the processes matched by -n.

All this means that if you want to dtruss a process (for the sake of argument, let's say it's whoami) running as your nonprivileged user, follow these steps:

  1. Open a root shell
  2. Run dtruss -fn whoami
    • this will sit and wait for a process named "whoami" to exist
  3. Open a nonprivileged shell
  4. Run whoami
    • this will execute and exit normally
  5. Observe system call trace in dtruss window
    • dtruss will not exit on its own — it will continue waiting for matching processes — so break out of it when you're done

This answer duplicates the latter part of @kenorb's response, but it deserves to be a first-class answer.