I read Federico’s post about finding poll()
wakeups and got really excited about the idea of using frysk to do this.
Unfortunately I looked and frysk doesn’t yet have symbol table lookups, so there’s really no good way to set a breakpoint yet, or to fetch the local callback
variables.
What a bummer. frysk offers a couple nice things for this problem: it is very easy to trace many programs (including through forks and multi-threaded programs) at once; this is one of its biggest advantages over gdb for this problem. It is also very easy to write a little custom code to pick exactly what you’re interested in — e.g., any program that calls poll
more than 5 times per second — as if you have a scriptable strace.
I didn’t want to leave empty-handed though. So, I refactored ftrace a little and wrote my first actually-functioning frysk-using jython script:
import sys
import frysk
import java
class fdtracer(frysk.ftrace.SyscallHandler):
def handle(self, task, syscall, what):
frysk.ftrace.Util.printStackTrace(java.lang.System.out, task)
tracer = frysk.ftrace.Ftrace()
tracer.setExitHandler(fdtracer())
tracer.addTracePid(int(sys.argv[1]))
tracer.trace()
This will trace a process (identified by pid) and print a stack trace every time a system call in the process exits. (Bah, can’t figure out how to make this blog software not delete leading spaces. So much for posting python code, dammit.)
This is silly of course. Still, writing something like the bad close catcher is an obvious extension of this. And Federico’s case is not really all that far off… I want that to be a nice little script that will automatically find gnome-session
, trace all its descendants, notice over-eager polling, and finally print the callback functions that are triggered.