fixes
[staptrace.git] / src / staptrace.stp
index 4b61712..24e7775 100755 (executable)
@@ -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 = ? <tracer terminated>\n", lhs (tid))
+  if (nest[last_tid])
+    printf (") = ? <tracer terminated>\n")
+  foreach (tid in nest)
+    if (tid != last_tid)
+      printf ("%s<... %s resumed> ) = ? <tracer terminated>\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 (" <unfinished ...>\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 (" <unfinished ...>\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 (" <unfinished ...>\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 ()
     }
 }