]> sourceware.org Git - systemtap.git/commitdiff
Export a value with every python breakpoint which gets returned.
authorDavid Smith <dsmith@redhat.com>
Thu, 27 Oct 2016 18:11:14 +0000 (13:11 -0500)
committerDavid Smith <dsmith@redhat.com>
Thu, 27 Oct 2016 18:11:14 +0000 (13:11 -0500)
* python/HelperSDT/__init__.py: Expect a 'key' value for every breakpoint and
  return that value when a breakpoint is hit.
* python/HelperSDT/_HelperSDT.c (trace_callback): Expect an index value
  and put that value in the marker.
* tapset-python.cxx (python_derived_probe_group::emit_module_decls):
  Output an index value with each breakpoint.

python/HelperSDT/_HelperSDT.c
python/HelperSDT/__init__.py
tapset-python.cxx

index af8c0ecca3aba93251ae80711215c2b23c1b30b8..915f56271a7aea677445f8b959958609e54111d7 100644 (file)
 static PyObject *
 trace_callback(PyObject *self, PyObject *args)
 {
-    int what;
+    unsigned int what;
     PyObject *frame_obj, *arg_obj;
+    unsigned int key;
 
     /* Parse the input tuple */
-    if (!PyArg_ParseTuple(args, "iOO", &what, &frame_obj, &arg_obj))
+    if (!PyArg_ParseTuple(args, "IOOI", &what, &frame_obj, &arg_obj, &key))
        return NULL;
 
     /* We want to name the probes with the same name as the
@@ -26,25 +27,25 @@ trace_callback(PyObject *self, PyObject *args)
     case PyTrace_CALL:
 #pragma push_macro("PyTrace_CALL")
 #undef PyTrace_CALL
-       STAP_PROBE2(HelperSDT, PyTrace_CALL, frame_obj, arg_obj);
+       STAP_PROBE3(HelperSDT, PyTrace_CALL, frame_obj, arg_obj, key);
 #pragma pop_macro("PyTrace_CALL")
        break;
     case PyTrace_EXCEPTION:
 #pragma push_macro("PyTrace_EXCEPTION")
 #undef PyTrace_EXCEPTION
-       STAP_PROBE2(HelperSDT, PyTrace_EXCEPTION, frame_obj, arg_obj);
+       STAP_PROBE3(HelperSDT, PyTrace_EXCEPTION, frame_obj, arg_obj, key);
 #pragma pop_macro("PyTrace_EXCEPTION")
        break;
     case PyTrace_LINE:
 #pragma push_macro("PyTrace_LINE")
 #undef PyTrace_LINE
-       STAP_PROBE2(HelperSDT, PyTrace_LINE, frame_obj, arg_obj);
+       STAP_PROBE3(HelperSDT, PyTrace_LINE, frame_obj, arg_obj, key);
 #pragma pop_macro("PyTrace_LINE")
        break;
     case PyTrace_RETURN:
 #pragma push_macro("PyTrace_RETURN")
 #undef PyTrace_RETURN
-       STAP_PROBE2(HelperSDT, PyTrace_RETURN, frame_obj, arg_obj);
+       STAP_PROBE3(HelperSDT, PyTrace_RETURN, frame_obj, arg_obj, key);
 #pragma pop_macro("PyTrace_RETURN")
        break;
     // FIXME: What about PyTrace_C_CALL, PyTrace_C_EXCEPTION,
index 552d48e1f8ac975188b47e24af4ce3a7260ca54e..3bb57470f4f9b0c06d62d08bda1d3f72c153c2ed 100644 (file)
@@ -24,19 +24,13 @@ import _HelperSDT
 
 
 class _Breakpoint:
-    def __init__(self, index, filename, funcname, lineno=None,
-                 returnp=False):
-        # We've got to have a filename and funcname with an optional
-        # lineno or returnp.
-        if not filename:
-            pass
-        if not funcname:
-            pass
+    def __init__(self, index, filename, funcname, lineno, returnp, key):
         self.index = index
         self.filename = filename
         self.funcname = funcname
         self.lineno = lineno
         self.returnp = returnp
+        self.key = key
 
     def dump(self, out=None):
         if out is None:
@@ -50,7 +44,8 @@ class _Breakpoint:
             disp = self.funcname
         else:
             disp = '%s.return' % self.funcname
-        return '%-4dbreakpoint at %s:%s' % (self.index, self.filename, disp)
+        return '%-4dbreakpoint at %s:%s %d' % (self.index, self.filename,
+                                               disp, self.key)
 
 
 class _BreakpointList:
@@ -65,8 +60,9 @@ class _BreakpointList:
         self._byfunc = {}      # indexed by (file, function) tuple
         self._byfuncret = {}    # indexed by (file, function) tuple
 
-    def add(self, filename, funcname, lineno=None, returnp=None):
-        bp = _Breakpoint(self._index, filename, funcname, lineno, returnp)
+    def add(self, filename, funcname, lineno, returnp, key):
+        bp = _Breakpoint(self._index, filename, funcname, lineno,
+                         returnp, key)
         self._index += 1
         self._bynumber.append(bp)
         if bp.lineno:
@@ -157,7 +153,7 @@ class Dispatcher(cmd.Cmd):
                                      % (frame.f_code.co_filename,
                                         frame.f_code.co_name))
                     _HelperSDT.trace_callback(_HelperSDT.PyTrace_CALL,
-                                              frame, arg)
+                                              frame, arg, bp.key)
             return self.pytrace_dispatch
         elif event == 'line':
             bplist = self._bplist.break_here(frame, event)
@@ -167,7 +163,7 @@ class Dispatcher(cmd.Cmd):
                                      % (frame.f_code.co_filename,
                                         frame.f_code.co_name, frame.f_lineno))
                     _HelperSDT.trace_callback(_HelperSDT.PyTrace_LINE,
-                                              frame, arg)
+                                              frame, arg, bp.key)
             return self.pytrace_dispatch
         elif event == 'return':
             bplist = self._bplist.break_here(frame, event)
@@ -177,7 +173,7 @@ class Dispatcher(cmd.Cmd):
                                      % (frame.f_code.co_filename,
                                         frame.f_code.co_name, frame.f_lineno))
                     _HelperSDT.trace_callback(_HelperSDT.PyTrace_RETURN,
-                                              frame, arg)
+                                              frame, arg, bp.key)
             return self.pytrace_dispatch
         return self.pytrace_dispatch
 
@@ -187,7 +183,7 @@ class Dispatcher(cmd.Cmd):
 
     def do_b(self, arg):
         # Breakpoint command:
-        #   b [ MODULE|FUNCTION@FILENAME:LINENO|FLAGS ]
+        #   b [ MODULE|FUNCTION@FILENAME:LINENO|FLAGS|KEY ]
         if not arg:
             self._bplist.dump()
             return
@@ -199,10 +195,11 @@ class Dispatcher(cmd.Cmd):
         filename = None
         lineno = None
         flags = None
+        key = None
         parts = arg.split('|')
-        if len(parts) != 3:
+        if len(parts) != 4:
             sys.stderr.write("Invalid breakpoint format: %s\n" % arg)
-            sys.stderr.write("Wrong number of major parts (%d vs. 3)\n" %
+            sys.stderr.write("Wrong number of major parts (%d vs. 4)\n" %
                              len(parts))
             return
         #  module = parts[0]
@@ -213,6 +210,12 @@ class Dispatcher(cmd.Cmd):
             sys.stderr.write("Invalid breakpoint format: %s\n" % arg)
             sys.stderr.write("Invalid flags value (%s)\n" % parts[2])
             return
+        try:
+            key = int(parts[3])
+        except:
+            sys.stderr.write("Invalid breakpoint format: %s\n" % arg)
+            sys.stderr.write("Invalid key value (%s)\n" % parts[3])
+            return
         parts = filename_arg.split('@')
         if len(parts) != 2:
             sys.stderr.write("Invalid breakpoint format: %s\n" % arg)
@@ -250,7 +253,7 @@ class Dispatcher(cmd.Cmd):
             returnp = True
 
         # Actually add the breakpoint.
-        self._bplist.add(filename, funcname, lineno, returnp)
+        self._bplist.add(filename, funcname, lineno, returnp, key)
 
 
 def run():
index 19c76a7780591d7ebefa0d8df692ae48548edc4e..22615c742eaca9a2bd8f5a16f0559133dc96680f 100644 (file)
@@ -183,24 +183,28 @@ python_derived_probe_group::emit_module_decls (systemtap_session& s)
   // Output the probe info buffer.
   if (python2_probes.size())
     {
+      unsigned index = 0;
       s.op->newline() << "static const char python2_probe_info[] =";
       s.op->indent(1);
       for (auto iter = python2_probes.begin(); iter != python2_probes.end();
           iter++)
         {
-         s.op->newline() << "\"b " << (*iter)->break_definition() << "\\n\"";
+         s.op->newline() << "\"b " << (*iter)->break_definition()
+                         << "|" << index++ << "\\n\"";
        }
       s.op->line() << ";";
       s.op->indent(-1);
     }
   if (python3_probes.size())
     {
+      unsigned index = 0;
       s.op->newline() << "static const char python3_probe_info[] =";
       s.op->indent(1);
       for (auto iter = python3_probes.begin(); iter != python3_probes.end();
           iter++)
         {
-         s.op->newline() << "\"b " << (*iter)->break_definition() << "\\n\"";
+         s.op->newline() << "\"b " << (*iter)->break_definition()
+                         << "|" << index++ << "\\n\"";
        }
       s.op->line() << ";";
       s.op->indent(-1);
This page took 0.032509 seconds and 5 git commands to generate.