[Lldb-commits] [lldb] r162633 - in /lldb/trunk: include/lldb/API/SBDebugger.h scripts/Python/interface/SBDebugger.i scripts/Python/python-extensions.swig scripts/Python/python-typemaps.swig scripts/Python/python-wrapper.swig test/python_api/debugger/TestDebuggerAPI.py

Filipe Cabecinhas me at filcab.net
Fri Aug 24 17:29:08 PDT 2012


Author: filcab
Date: Fri Aug 24 19:29:07 2012
New Revision: 162633

URL: http://llvm.org/viewvc/llvm-project?rev=162633&view=rev
Log:
Added SBDebugger's log callbacks to Python-land

- Tweaked a parameter name in SBDebugger.h so my typemap will catch it;
- Added a SBDebugger.Create(bool, callback, baton) to the swig interface;
- Added SBDebugger.SetLoggingCallback to the swig interface;
- Added a callback utility function for log callbacks;
- Guard against Py_None on both callback utility functions;

- Added a FIXME to the SBDebugger API test;
- Added a __del__() stub for SBDebugger.

We need to be able to get both the log callback and baton from an
SBDebugger if we want to protect against memory leaks (or make the user
responsible for holding another reference to the callback).
Additionally, it's impossible to revert from a callback-backed log
mechanism to a file-backed log mechanism.


Modified:
    lldb/trunk/include/lldb/API/SBDebugger.h
    lldb/trunk/scripts/Python/interface/SBDebugger.i
    lldb/trunk/scripts/Python/python-extensions.swig
    lldb/trunk/scripts/Python/python-typemaps.swig
    lldb/trunk/scripts/Python/python-wrapper.swig
    lldb/trunk/test/python_api/debugger/TestDebuggerAPI.py

Modified: lldb/trunk/include/lldb/API/SBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBDebugger.h?rev=162633&r1=162632&r2=162633&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBDebugger.h (original)
+++ lldb/trunk/include/lldb/API/SBDebugger.h Fri Aug 24 19:29:07 2012
@@ -33,7 +33,7 @@
     Create(bool source_init_files);
 
     static lldb::SBDebugger
-    Create(bool source_init_files, lldb::LogOutputCallback callback, void *baton);
+    Create(bool source_init_files, lldb::LogOutputCallback log_callback, void *baton);
 
     static void
     Destroy (lldb::SBDebugger &debugger);

Modified: lldb/trunk/scripts/Python/interface/SBDebugger.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBDebugger.i?rev=162633&r1=162632&r2=162633&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBDebugger.i (original)
+++ lldb/trunk/scripts/Python/interface/SBDebugger.i Fri Aug 24 19:29:07 2012
@@ -122,6 +122,9 @@
     static lldb::SBDebugger
     Create(bool source_init_files);
 
+    static lldb::SBDebugger
+    Create(bool source_init_files, lldb::LogOutputCallback log_callback, void *baton);
+
     static void
     Destroy (lldb::SBDebugger &debugger);
 
@@ -272,6 +275,9 @@
     EnableLog (const char *channel, const char ** types);
 
     void
+    SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton);
+
+    void
     DispatchInput (const void *data, size_t data_len);
 
     void

Modified: lldb/trunk/scripts/Python/python-extensions.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-extensions.swig?rev=162633&r1=162632&r2=162633&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-extensions.swig (original)
+++ lldb/trunk/scripts/Python/python-extensions.swig Fri Aug 24 19:29:07 2012
@@ -484,6 +484,15 @@
         }
 }
 
+
+// %extend lldb::SBDebugger {
+//         // FIXME: We can't get the callback and baton
+//         PyObject *lldb::SBDebugger (){
+//             // Only call Py_XDECREF if we have a Python object (or NULL)
+//             if (LLDBSwigPythonCallPythonLogOutputCallback == $self->GetLogOutPutCallback())
+//                 Py_XDECREF($self->GetCallbackBaton());
+//         }
+// }
 // %extend lldb::SBInputReader {
 //         // FIXME: m_callback_function is private and we have no other
 //         // way to access it.
@@ -686,4 +695,3 @@
     def __neq__(self, other):
         return not self.__eq__(other)
 %}
-

Modified: lldb/trunk/scripts/Python/python-typemaps.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-typemaps.swig?rev=162633&r1=162632&r2=162633&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-typemaps.swig (original)
+++ lldb/trunk/scripts/Python/python-typemaps.swig Fri Aug 24 19:29:07 2012
@@ -352,11 +352,16 @@
 
 // For lldb::SBInputReader::Callback
 %typemap(in) (lldb::SBInputReader::Callback callback, void *callback_baton) {
-  if (!PyCallable_Check(reinterpret_cast<PyObject*>($input))) {
-    PyErr_SetString(PyExc_TypeError, "Need a callable object!");
+  if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) {
+    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
     return NULL;
   }
 
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
   // Don't lose the callback reference
   Py_INCREF($input);
   $1 = LLDBSwigPythonCallSBInputReaderCallback;
@@ -364,7 +369,33 @@
 }
 
 %typemap(typecheck) (lldb::SBInputReader::Callback callback, void *baton) {
-  if (!PyCallable_Check(reinterpret_cast<PyObject*>($input))) {
+  if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) {
+    $1 = 0;
+  } else {
+    $1 = 1;
+  }
+}
+
+// For Log::LogOutputCallback
+%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) {
+  if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) {
+    PyErr_SetString(PyExc_TypeError, "Need a callable object or None!");
+    return NULL;
+  }
+
+  // FIXME (filcab): We can't currently check if our callback is already
+  // LLDBSwigPythonCallPythonLogOutputCallback (to DECREF the previous
+  // baton) nor can we just remove all traces of a callback, if we want to
+  // revert to a file logging mechanism.
+
+  // Don't lose the callback reference
+  Py_INCREF($input);
+  $1 = LLDBSwigPythonCallPythonLogOutputCallback;
+  $2 = $input;
+}
+
+%typemap(typecheck) (lldb::LogOutputCallback log_callback, void *baton) {
+  if (!($input == Py_None || PyCallable_Check(reinterpret_cast<PyObject*>($input)))) {
     $1 = 0;
   } else {
     $1 = 1;

Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=162633&r1=162632&r2=162633&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Fri Aug 24 19:29:07 2012
@@ -929,6 +929,7 @@
 // This is needed to use LLDBSwigPythonCallSBInputReaderCallback in the
 // typemaps and in the extensions (SBInputReader.__del__()).
 #include "lldb/API/SBInputReader.h"
+#include "lldb/API/SBDebugger.h"
 
 size_t
 LLDBSwigPythonCallSBInputReaderCallback(void *baton,
@@ -936,6 +937,8 @@
                                         lldb::InputReaderAction notification,
                                         const char*bytes,
                                         size_t bytes_len);
+
+void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton);
 %}
 
 %wrapper %{
@@ -946,35 +949,46 @@
                                         lldb::InputReaderAction notification,
                                         const char*bytes,
                                         size_t bytes_len) {
-    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-
-    PyObject *py_InputReader = SWIG_NewPointerObj(reader, SWIGTYPE_p_lldb__SBInputReader, false);
-    PyObject *py_Notification = PyInt_FromLong(notification);
-    PyObject *py_Bytes = PyBytes_FromStringAndSize(bytes, bytes_len);
-
-    PyObject *tuple = PyTuple_Pack(3, py_InputReader, py_Notification, py_Bytes);
-    PyObject *res = PyObject_Call(reinterpret_cast<PyObject*>(baton), tuple, NULL);
-    Py_DECREF(tuple);
-    Py_DECREF(py_InputReader);
-    Py_DECREF(py_Notification);
-    Py_DECREF(py_Bytes);
-
-    if (res == NULL) {
-      PyObject *exc = PyErr_Occurred();
-      if (exc) {
-        ::puts("\nErroring out at LLDBSwigPythonCallSBInputReaderCallback");
-        PyErr_Print();
-      }
-      return 0;
+    if (baton != Py_None) {
+        SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+    
+        PyObject *py_InputReader = SWIG_NewPointerObj(reader, SWIGTYPE_p_lldb__SBInputReader, false);
+        PyObject *py_Notification = PyInt_FromLong(notification);
+        PyObject *py_Bytes = PyBytes_FromStringAndSize(bytes, bytes_len);
+    
+        PyObject *tuple = PyTuple_Pack(3, py_InputReader, py_Notification, py_Bytes);
+        PyObject *res = PyObject_Call(reinterpret_cast<PyObject*>(baton), tuple, NULL);
+        Py_DECREF(tuple);
+        Py_DECREF(py_InputReader);
+        Py_DECREF(py_Notification);
+        Py_DECREF(py_Bytes);
+    
+        if (res == NULL) {
+          PyObject *exc = PyErr_Occurred();
+          if (exc) {
+            ::puts("\nErroring out at LLDBSwigPythonCallSBInputReaderCallback");
+            PyErr_Print();
+          }
+          return 0;
+        }
+    
+        size_t result = 0;
+        // If the callback misbehaves and returns Py_None, assume it returned 0
+        if (res != Py_None)
+          result = static_cast<size_t>(PyInt_AsSsize_t(res));
+    
+        Py_DECREF(res);
+        SWIG_PYTHON_THREAD_END_BLOCK;
+        return result;
     }
+}
 
-    size_t result = 0;
-    // If the callback misbehaves and returns Py_None, assume it returned 0
-    if (res != Py_None)
-      result = static_cast<size_t>(PyInt_AsSsize_t(res));
-
-    Py_DECREF(res);
-    SWIG_PYTHON_THREAD_END_BLOCK;
-    return result;
+// For the LogOutputCallback functions
+void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton) {
+    if (baton != Py_None) {
+      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+      PyObject_CallFunction(reinterpret_cast<PyObject*>(baton), const_cast<char*>("s"), str);
+      SWIG_PYTHON_THREAD_END_BLOCK;
+    }
 }
 %}

Modified: lldb/trunk/test/python_api/debugger/TestDebuggerAPI.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/debugger/TestDebuggerAPI.py?rev=162633&r1=162632&r2=162633&view=diff
==============================================================================
--- lldb/trunk/test/python_api/debugger/TestDebuggerAPI.py (original)
+++ lldb/trunk/test/python_api/debugger/TestDebuggerAPI.py Fri Aug 24 19:29:07 2012
@@ -2,11 +2,10 @@
 Test Debugger APIs.
 """
 
-import os, time
-import re
-import unittest2
-import lldb, lldbutil
-from lldbtest import *
+import os
+import lldb
+from lldbtest import TestBase, python_api_test
+
 
 class DebuggerAPITestCase(TestBase):
 
@@ -25,6 +24,9 @@
         self.dbg.FindTargetWithFileAndArch(None, None)
         self.dbg.SetInternalVariable(None, None, None)
         self.dbg.GetInternalVariableValue(None, None)
+        # FIXME (filcab): We must first allow for the swig bindings to know if
+        # a Python callback is set. (Check python-typemaps.swig)
+        #self.dbg.SetLoggingCallback(None)
         self.dbg.SetPrompt(None)
         self.dbg.SetCurrentPlatform(None)
         self.dbg.SetCurrentPlatformSDKRoot(None)
@@ -35,4 +37,3 @@
         target = lldb.SBTarget()
         self.assertFalse(target.IsValid())
         self.dbg.DeleteTarget(target)
-        





More information about the lldb-commits mailing list