From: Jan Kratochvil Date: Sat, 25 Dec 2010 00:21:59 +0000 (+0100) Subject: fixes X-Git-Url: https://git.jankratochvil.net/?p=staptrace.git;a=commitdiff_plain;h=4a1ab902d8c1e3a20db8a736e159e393f8a375b7;ds=sidebyside fixes --- diff --git a/src/staptrace.c b/src/staptrace.c index 2f6f328..5dd7485 100644 --- a/src/staptrace.c +++ b/src/staptrace.c @@ -5,6 +5,7 @@ #include #include #include +#include #ifndef STAP_SCRIPT_FILENAME #error "STAP_SCRIPT_FILENAME is required" @@ -51,8 +52,8 @@ dump_args (char **args) for (argp = args; *argp; argp++) { if (argp > args) - fputs (", ", stderr); - fprintf (stderr, "'%s'", *argp); + fputc (' ', stderr); + fputs (*argp, stderr); } fputc ('\n', stderr); } @@ -62,9 +63,9 @@ main (int argc, char **argv) { char **args, **argp; - args = xmalloc (sizeof (*args) * argc * 2); + args = xmalloc (sizeof (*args) * argc * 2 + 32); argp = args; - *argp++ = argv[0]; + *argp++ = "stap"; for (;;) { @@ -114,39 +115,40 @@ main (int argc, char **argv) if (optind < argc) { - size_t len; + pid_t child; int i; - char *d; - const char *s; + static char kill_s[64]; + static char opt_s[64]; - *argp++ = "-c"; - - len = 32; - for (i = optind; i < argc; i++) - len += 3 + strlen (argv[i]) * 4; - - d = *argp++ = xmalloc (len); - d = stpcpy (d, "(exec"); - for (i = optind; i < argc; i++) + child = fork (); + switch (child) { - *d++ = ' '; - *d++ = '\''; - for (s = argv[optind]; *s; s++) - switch (*s) - { - case '\'': - d = stpcpy (d, "'\\''"); - break; - case '\\': - *d++ = '\\'; - /* FALLTHRU */ - default: - *d++ = *s; - } - *d++ = '\''; + case -1: + error (EXIT_FAILURE, errno, _("Error calling fork")); + case 0: + i = raise (SIGSTOP); + if (i != 0) + error (EXIT_FAILURE, errno, _("Error calling raise (SIGSTOP)")); + + execvp (argv[optind], &argv[optind]); + error (EXIT_FAILURE, errno, "Error executing child command"); + default: + break; } - *d++ = ')'; - *d++ = 0; + + /* FIXME: Call `kill -CONT' from the systamtap script. How? */ + i = sprintf (kill_s, "kill -CONT %lu; " + "while [ -e /proc/%lu/root ]; do sleep 0.1; done", + (unsigned long) child, (unsigned long) child); + if (i <= 0) + error (EXIT_FAILURE, errno, _("Error calling sprintf")); + *argp++ = "-c"; + *argp++ = kill_s; + i = sprintf (opt_s, "opt_child=%lu", (unsigned long) child); + if (i <= 0) + error (EXIT_FAILURE, errno, _("Error calling sprintf")); + *argp++ = "-G"; + *argp++ = opt_s; } *argp++ = opt_Z; *argp = NULL; diff --git a/src/staptrace.stp b/src/staptrace.stp index 4b61712..24e7775 100755 --- a/src/staptrace.stp +++ b/src/staptrace.stp @@ -18,6 +18,8 @@ # ` = 0' is there to prevent: WARNING: never-assigned global variable global opt_f = 0 global opt_q = 0 +# Override target(). +global opt_child = 0 /* systemtap bug? /usr/share/doc/systemtap-1.3/SystemTap_Beginners_Guide.pdf Example 3.19 reads or writes? */ @@ -26,11 +28,12 @@ global trace global last_tid probe begin { - trace[target ()] = 1 - last_tid = target () + tid = opt_child > 0 ? opt_child : target () + trace[tid] = 1 + last_tid = tid } -function heading:string () +function heading:string (tid:long) { foreach (tidi in trace limit 2) tid_count++ @@ -38,27 +41,23 @@ function heading:string () if (tid_count > 1) { /* strace really calls TID a "pid". */ - return sprintf ("[pid %5d] ", tid ()) + return sprintf ("[pid %5d] ", tid) } else return "" } -global namea +global funcname +global nest -function destroy (tid:long) -{ - delete namea[tid] -} - -function lhs:string (tid:long) -{ - return namea[tid] -} probe end { - foreach (tid in namea) - printf ("%s = ? \n", lhs (tid)) + if (nest[last_tid]) + printf (") = ? \n") + foreach (tid in nest) + if (tid != last_tid) + printf ("%s<... %s resumed> ) = ? \n", heading (tid), + funcname[tid] != "" ? funcname[tid] : "?"); } /* BUG: sleeping function called from invalid context at kernel/mutex.c:94 @@ -72,9 +71,15 @@ function unlock () mutex_unlock (&tracer_mutex); %} */ -global dummy -function lock () { dummy = 1; } -function unlock () { dummy = 1; } +global lockvar +function lock () +{ + lockvar++ +} +function unlock () +{ + lockvar++ +} #probe kprocess.start #{ @@ -104,22 +109,13 @@ probe kprocess.release tid = task_tid (task) if (trace[tid] != 0) { - if (namea[tid] != "") - { - printf ("%s = ?\n", lhs (tid)) - destroy (tid) - } -# FIXME - else if (0) + if (nest[tid]) { - /* systemtap bug? exit_group(2) systemtap calls "exit" and _exit(2) - is not caught at all. */ - lock () - if (last_tid != tid () && namea[last_tid] != "") - printf (" \n") - last_tid = tid - printf ("%s_exit(?) = ?\n", heading ()) - unlock () + /* FIXME: Do not assume "exit" for the nested calls. */ + printf ("%s<... %s resumed> = ?\n", heading (tid), + funcname[tid] != "" ? funcname[tid] : "exit") + delete nest[tid] + delete funcname[tid] } delete trace[tid] if (!opt_q) @@ -132,11 +128,12 @@ probe syscall.* { lock () /* Why is mmap() called recursively twice? */ - if (namea[last_tid] != "") + if (nest[last_tid]) printf (" \n") last_tid = tid (); - namea[tid ()] = name - printf ("%s%s(%s", heading (), name, argstr) + funcname[tid ()] = name + nest[tid ()]++ + printf ("%s%s(%s", heading (tid ()), name, argstr) unlock () } } @@ -145,14 +142,15 @@ probe syscall.*.return if (trace[tid ()] != 0) { lock () - if (last_tid != tid () && namea[last_tid] != "") + if (last_tid != tid () && nest[last_tid]) printf (" \n") - if ((last_tid != tid () && namea[last_tid] != "") - || (last_tid == tid () && namea[last_tid] == "")) - printf ("%s<... %s resumed> ", heading (), name); + if (last_tid != tid () || (last_tid == tid () && !nest[last_tid])) + printf ("%s<... %s resumed> ", heading (tid ()), name); last_tid = tid (); printf (") = %s\n", retstr) - destroy (tid ()) + if (!--nest[tid ()]) + delete nest[tid ()] + delete funcname[tid ()] unlock () } }