Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

OS X lacks linux's strace, but it has dtrace which is supposed to be so much better.

However, I miss the ability to do simple tracing on individual commands. For example, on linux I can write strace -f gcc hello.c to caputre all system calls, which gives me the list of all the filenames needed by the compiler to compile my program (the excellent memoize script is built upon this trick)

I want to port memoize on the mac, so I need some kind of strace. What I actually need is the list of files gcc reads and writes into, so what I need is more of a truss. Sure enough can I say dtruss -f gcc hello.c and get somewhat the same functionality, but then the compiler is run with root priviledges, which is obviously undesirable (apart from the massive security risk, one issue is that the a.out file is now owned by root :-)

I then tried dtruss -f sudo -u myusername gcc hello.c, but this feels a bit wrong, and does not work anyway (I get no a.out file at all this time, not sure why)

All that long story tries to motivate my original question: how do I get dtrace to run my command with normal user privileges, just like strace does in linux ?

Edit: is seems that I'm not the only one wondering how to do this: question #1204256 is pretty much the same as mine (and has the same suboptimal sudo answer :-)

like image 676
Gyom Avatar asked Jun 09 '10 16:06

Gyom


People also ask

Does strace require root?

To run and trace a program as another user, we can use the flag -u followed by the username. One prerequisite for this option is that we'll need to run strace as a root user.

How do I activate strace?

To display only a specific system call, use the strace -e option as shown below. The above output displays only the open system call of the ls command. At the end of the strace output, it also displays the output of the ls command. If you want to trace multiple system calls use the “-e trace=” option.

How do you control strace?

If your strace doesn't respond to Ctrl + C, than as mentioned, use Ctrl + Z and bg to push it to the background then attach to the running strace process with another strace. This should tell you why the first strace is blocked.


2 Answers

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)

like image 149
kenorb Avatar answered Sep 19 '22 18:09

kenorb


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.

like image 20
wfaulk Avatar answered Sep 18 '22 18:09

wfaulk