[Lldb-commits] [lldb] r220821 - Add a feature where a string data formatter can now be partially composed of Python summary functions

Enrico Granata egranata at apple.com
Tue Oct 28 14:07:01 PDT 2014


Author: enrico
Date: Tue Oct 28 16:07:00 2014
New Revision: 220821

URL: http://llvm.org/viewvc/llvm-project?rev=220821&view=rev
Log:
Add a feature where a string data formatter can now be partially composed of Python summary functions
This works similarly to the {thread/frame/process/target.script:...} feature - you write a summary string, part of which is

${var.script:someFuncName}
someFuncName is expected to be declared as
def someFuncName(SBValue,otherArgument) - essentially the same as a summary function

Since . -> [] are the only allowed separators, and % is used for custom formatting, .script: would not be a legitimate symbol anyway, which makes this non-ambiguous


Added:
    lldb/trunk/test/functionalities/data-formatter/varscript_formatting/
    lldb/trunk/test/functionalities/data-formatter/varscript_formatting/Makefile
    lldb/trunk/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py
    lldb/trunk/test/functionalities/data-formatter/varscript_formatting/helperfunc.py
    lldb/trunk/test/functionalities/data-formatter/varscript_formatting/main.cpp
Modified:
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/scripts/Python/python-wrapper.swig
    lldb/trunk/source/API/SBCommandInterpreter.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=220821&r1=220820&r2=220821&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Tue Oct 28 16:07:00 2014
@@ -152,6 +152,11 @@ public:
                                                                  const char* session_dictionary_name,
                                                                  lldb::StackFrameSP& frame,
                                                                  std::string& output);
+
+    typedef bool            (*SWIGPythonScriptKeyword_Value)    (const char* python_function_name,
+                                                                 const char* session_dictionary_name,
+                                                                 lldb::ValueObjectSP& value,
+                                                                 std::string& output);
     
     typedef void*           (*SWIGPython_GetDynamicSetting)     (void* module,
                                                                  const char* setting,
@@ -556,6 +561,16 @@ public:
     }
     
     virtual bool
+    RunScriptFormatKeyword (const char* impl_function,
+                            ValueObject* value,
+                            std::string& output,
+                            Error& error)
+    {
+        error.SetErrorString("unimplemented");
+        return false;
+    }
+    
+    virtual bool
     GetDocumentationForItem (const char* item, std::string& dest)
     {
 		dest.clear();
@@ -621,6 +636,7 @@ public:
                            SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                            SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                            SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
+                           SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
                            SWIGPython_GetDynamicSetting swig_plugin_get,
                            SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
                            SWIGPythonCallThreadPlan swig_call_thread_plan);

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=220821&r1=220820&r2=220821&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Tue Oct 28 16:07:00 2014
@@ -232,6 +232,12 @@ public:
                             Error& error);
     
     virtual bool
+    RunScriptFormatKeyword (const char* impl_function,
+                            ValueObject* value,
+                            std::string& output,
+                            Error& error);
+    
+    virtual bool
     LoadScriptingModule (const char* filename,
                          bool can_reload,
                          bool init_session,
@@ -296,6 +302,7 @@ public:
                            SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                            SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                            SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
+                           SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
                            SWIGPython_GetDynamicSetting swig_plugin_get,
                            SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
                            SWIGPythonCallThreadPlan swig_call_thread_plan);

Modified: lldb/trunk/scripts/Python/python-wrapper.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=220821&r1=220820&r2=220821&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-wrapper.swig (original)
+++ lldb/trunk/scripts/Python/python-wrapper.swig Tue Oct 28 16:07:00 2014
@@ -1060,6 +1060,44 @@ std::string& output)
 }
 
 SWIGEXPORT bool
+LLDBSWIGPythonRunScriptKeywordValue
+(const char* python_function_name,
+const char* session_dictionary_name,
+lldb::ValueObjectSP& value,
+std::string& output)
+
+{
+    bool retval = false;
+
+    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
+        return retval;
+
+    lldb::SBValue value_sb(value);
+    
+    {
+        PyErr_Cleaner py_err_cleaner(true);
+        
+        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
+        
+        if (!pfunc)
+            return retval;
+        
+        PyObject* session_dict = NULL;
+        PyObject* pvalue = NULL;
+        pvalue = pfunc(value_sb, session_dict = FindSessionDictionary(session_dictionary_name));
+        
+        Py_XINCREF (session_dict);
+        
+        if (PyObjectToString(pvalue,output))
+            retval = true;
+        
+        Py_XDECREF(pvalue);
+    }
+    
+    return retval;
+}
+
+SWIGEXPORT bool
 LLDBSwigPythonCallModuleInit 
 (
     const char *python_module_name,

Modified: lldb/trunk/source/API/SBCommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBCommandInterpreter.cpp?rev=220821&r1=220820&r2=220821&view=diff
==============================================================================
--- lldb/trunk/source/API/SBCommandInterpreter.cpp (original)
+++ lldb/trunk/source/API/SBCommandInterpreter.cpp Tue Oct 28 16:07:00 2014
@@ -679,6 +679,12 @@ LLDBSWIGPythonRunScriptKeywordFrame (con
                                      lldb::StackFrameSP& frame,
                                      std::string& output);
 
+extern "C" bool
+LLDBSWIGPythonRunScriptKeywordValue (const char* python_function_name,
+                                     const char* session_dictionary_name,
+                                     lldb::ValueObjectSP& value,
+                                     std::string& output);
+
 extern "C" void*
 LLDBSWIGPython_GetDynamicSetting (void* module,
                                   const char* setting,
@@ -715,6 +721,7 @@ SBCommandInterpreter::InitializeSWIG ()
                                                   LLDBSWIGPythonRunScriptKeywordThread,
                                                   LLDBSWIGPythonRunScriptKeywordTarget,
                                                   LLDBSWIGPythonRunScriptKeywordFrame,
+                                                  LLDBSWIGPythonRunScriptKeywordValue,
                                                   LLDBSWIGPython_GetDynamicSetting,
                                                   LLDBSwigPythonCreateScriptedThreadPlan,
                                                   LLDBSWIGPythonCallThreadPlan);

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=220821&r1=220820&r2=220821&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Tue Oct 28 16:07:00 2014
@@ -1735,6 +1735,15 @@ FormatPromptRecurse
                                     target = valobj;
                                     val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
                                 }
+                                else if (IsToken (var_name_begin, "var.script:"))
+                                {
+                                    var_name_begin += ::strlen("var.script:");
+                                    std::string script_name(var_name_begin,var_name_end);
+                                    ScriptInterpreter* script_interpreter = valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+                                    if (RunScriptFormatKeyword (s, script_interpreter, valobj, script_name))
+                                        var_success = true;
+                                    break;
+                                }
                                 else if (IsToken (var_name_begin,"var%"))
                                 {
                                     was_var_format = true;

Modified: lldb/trunk/source/Interpreter/ScriptInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreter.cpp?rev=220821&r1=220820&r2=220821&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreter.cpp Tue Oct 28 16:07:00 2014
@@ -132,6 +132,7 @@ ScriptInterpreter::InitializeInterpreter
                                           SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                                           SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                                           SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
+                                          SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
                                           SWIGPython_GetDynamicSetting swig_plugin_get,
                                           SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
                                           SWIGPythonCallThreadPlan swig_call_thread_plan)
@@ -157,6 +158,7 @@ ScriptInterpreter::InitializeInterpreter
                                                     swig_run_script_keyword_thread,
                                                     swig_run_script_keyword_target,
                                                     swig_run_script_keyword_frame,
+                                                    swig_run_script_keyword_value,
                                                     swig_plugin_get,
                                                     swig_thread_plan_script,
                                                     swig_call_thread_plan);

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=220821&r1=220820&r2=220821&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Tue Oct 28 16:07:00 2014
@@ -67,6 +67,7 @@ static ScriptInterpreter::SWIGPythonScri
 static ScriptInterpreter::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = nullptr;
 static ScriptInterpreter::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = nullptr;
 static ScriptInterpreter::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = nullptr;
+static ScriptInterpreter::SWIGPythonScriptKeyword_Value g_swig_run_script_keyword_value = nullptr;
 static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
 static ScriptInterpreter::SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr;
 static ScriptInterpreter::SWIGPythonCallThreadPlan g_swig_call_thread_plan = nullptr;
@@ -2376,6 +2377,38 @@ ScriptInterpreterPython::RunScriptFormat
     }
     return ret_val;
 }
+    
+bool
+ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
+                                                 ValueObject *value,
+                                                 std::string& output,
+                                                 Error& error)
+{
+    bool ret_val;
+    if (!value)
+    {
+        error.SetErrorString("no value");
+        return false;
+    }
+    if (!impl_function || !impl_function[0])
+    {
+        error.SetErrorString("no function to execute");
+        return false;
+    }
+    if (!g_swig_run_script_keyword_value)
+    {
+        error.SetErrorString("internal helper function missing");
+        return false;
+    }
+    {
+        ValueObjectSP value_sp(value->GetSP());
+        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+        ret_val = g_swig_run_script_keyword_value (impl_function, m_dictionary_name.c_str(), value_sp, output);
+        if (!ret_val)
+            error.SetErrorString("python script evaluation failed");
+    }
+    return ret_val;
+}
 
 uint64_t replace_all(std::string& str, const std::string& oldStr, const std::string& newStr)
 {
@@ -2676,6 +2709,7 @@ ScriptInterpreterPython::InitializeInter
                                                 SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                                                 SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                                                 SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
+                                                SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
                                                 SWIGPython_GetDynamicSetting swig_plugin_get,
                                                 SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
                                                 SWIGPythonCallThreadPlan swig_call_thread_plan)
@@ -2700,6 +2734,7 @@ ScriptInterpreterPython::InitializeInter
     g_swig_run_script_keyword_thread = swig_run_script_keyword_thread;
     g_swig_run_script_keyword_target = swig_run_script_keyword_target;
     g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
+    g_swig_run_script_keyword_value = swig_run_script_keyword_value;
     g_swig_plugin_get = swig_plugin_get;
     g_swig_thread_plan_script = swig_thread_plan_script;
     g_swig_call_thread_plan = swig_call_thread_plan;

Added: lldb/trunk/test/functionalities/data-formatter/varscript_formatting/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/varscript_formatting/Makefile?rev=220821&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/varscript_formatting/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/varscript_formatting/Makefile Tue Oct 28 16:07:00 2014
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py?rev=220821&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/varscript_formatting/TestDataFormatterVarScriptFormatting.py Tue Oct 28 16:07:00 2014
@@ -0,0 +1,71 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+import os.path
+
+class PythonSynthDataFormatterTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_with_dsym_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDsym()
+        self.data_formatter_commands()
+
+    @skipIfFreeBSD # llvm.org/pr20545 bogus output confuses buildbot parser
+    @dwarf_test
+    def test_with_dwarf_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDwarf()
+        self.data_formatter_commands()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break at.
+        self.line = line_number('main.cpp', ' // Set breakpoint here.')
+
+    def data_formatter_commands(self):
+        """Test using Python synthetic children provider."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        # This is the function to remove the custom formats in order to have a
+        # clean slate for the next test case.
+        def cleanup():
+            self.runCmd('type format clear', check=False)
+            self.runCmd('type summary clear', check=False)
+            self.runCmd('type filter clear', check=False)
+            self.runCmd('type synth clear', check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+        
+        self.runCmd("command script import helperfunc.py")
+        self.runCmd('type summary add -x "^something<.*>$" -s "T is a ${var.script:helperfunc.f}"')
+
+        self.expect("frame variable x", substrs = ['T is a non-pointer type']);
+            
+        self.expect("frame variable y", substrs = ['T is a pointer type']);
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/functionalities/data-formatter/varscript_formatting/helperfunc.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/varscript_formatting/helperfunc.py?rev=220821&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/varscript_formatting/helperfunc.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/varscript_formatting/helperfunc.py Tue Oct 28 16:07:00 2014
@@ -0,0 +1,5 @@
+import lldb
+
+def f(value,d):
+    return "pointer type" if value.GetType().GetTemplateArgumentType(0).IsPointerType() else "non-pointer type"
+

Added: lldb/trunk/test/functionalities/data-formatter/varscript_formatting/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/varscript_formatting/main.cpp?rev=220821&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/varscript_formatting/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/varscript_formatting/main.cpp Tue Oct 28 16:07:00 2014
@@ -0,0 +1,8 @@
+template <typename T>
+struct something {};
+
+int main() {
+    something<int> x;
+    something<void*> y;
+    return 0; // Set breakpoint here.
+}
\ No newline at end of file





More information about the lldb-commits mailing list