This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: user mode backtrace


On Thursday, October 19, 2006 1:47 PM, David Boreham wrote:
> I'd like to get a stack trace for the process that made the
> system call I'm probing (I'm looking at filesystem access
> typically, so reads/writes/syncs etc). The systemtap backtrace
> function appears to only get the kernel mode stack which
> is not much use to me. I was wondering if anyone had
> discovered a good solution to this problem already ?
> I was thinking perhaps I could invoke pstack (gdb)
> on the current pid/tid. But I'm worried that doing so
> might deadlock since the process is inside a system
> call.
> 
> I'm looking at a very large application that beats up on
> the filesystem, in case you're wondering why I want to do
> this. It's so large that nobody is quite sure what code
> access which files, when and why.
> 
> Thanks.

Deadlock issues aside, there's not really a way for you to invoke a
process (like pstack) from within a SystemTap script.  You could run a
separate user program or script to do this for you though, and then you
just need to coordinate with SystemTap.  Such a method might look like
this:

-----------------------------------------------
/* Main test driver */
-----------------------------------------------
pid = fork_ptraceme_exec("myapp"); // start the app paused
stappid = fork_exec("stap myscript.stp -x " + pid); // start systemtap
ptrace(DETACH, pid, ...); // let the app run
while(pid == waitpid(pid, stat, 0)) {
  if (WIFSTOPPED(stat)) { // app is stopped
    system("pstack " + pid); // dump the stack
    kill(pid, SIGCONT); // continue the app
  }
  else if (WIFEXITED(stat)) {
    break;
  }
}
kill(stappid, SIGINT); // tell systemtap to stop
waitpid(stappid, ...);
-----------------------------------------------

-----------------------------------------------
/* SystemTap script: myscript.stp */
-----------------------------------------------
probe syscall.read {
  if (target() != tid()) next;
  /* log some stuff: filename, etc. */
}
probe syscall.read.return {
  if (target() != tid()) next;
  send_stop() // do this on return to avoid EINTR
}
function send_stop %{
  send_sig(SIGSTOP, current, 1);
%}
-----------------------------------------------

This is all pretty rough, and I haven't actually tried it, so who knows
if it will actually work.

Of course at the end of the day, this is just a convoluted strace with a
stack printout.  You could probably do the same thing by hacking gdb's
backtrace function into strace.  But this SystemTap method would also
let you do probe other things besides just system calls...

If anyone gets this working I would LOVE to hear about it... :)


Josh


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]