[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