[Lldb-commits] [lldb] r114849 - in /lldb/trunk: include/lldb/API/SBBreakpointLocation.h include/lldb/API/SBFrame.h scripts/lldb.swig source/Interpreter/ScriptInterpreterPython.cpp
Johnny Chen
johnny.chen at apple.com
Mon Sep 27 12:17:42 PDT 2010
Hi Caroline,
This checkin seems to break the test suite: test/breakpoint_command, and maybe others....
On Sep 27, 2010, at 11:00 AM, Caroline Tice wrote:
> Author: ctice
> Date: Mon Sep 27 13:00:20 2010
> New Revision: 114849
>
> URL: http://llvm.org/viewvc/llvm-project?rev=114849&view=rev
> Log:
> Automatically wrap *all* Python code entered for a breakpoint command inside
> an auto-generated Python function, and pass the stoppoint context frame and
> breakpoint location as parameters to the function (named 'frame' and 'bp_loc'),
> to be used inside the breakpoint command Python code, if desired.
>
>
> Modified:
> lldb/trunk/include/lldb/API/SBBreakpointLocation.h
> lldb/trunk/include/lldb/API/SBFrame.h
> lldb/trunk/scripts/lldb.swig
> lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
>
> Modified: lldb/trunk/include/lldb/API/SBBreakpointLocation.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpointLocation.h?rev=114849&r1=114848&r2=114849&view=diff
> ==============================================================================
> --- lldb/trunk/include/lldb/API/SBBreakpointLocation.h (original)
> +++ lldb/trunk/include/lldb/API/SBBreakpointLocation.h Mon Sep 27 13:00:20 2010
> @@ -76,6 +76,7 @@
>
> private:
> friend class SBBreakpoint;
> + friend class lldb_private::ScriptInterpreterPython;
>
> SBBreakpointLocation (const lldb::BreakpointLocationSP &break_loc_sp);
>
>
> Modified: lldb/trunk/include/lldb/API/SBFrame.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFrame.h?rev=114849&r1=114848&r2=114849&view=diff
> ==============================================================================
> --- lldb/trunk/include/lldb/API/SBFrame.h (original)
> +++ lldb/trunk/include/lldb/API/SBFrame.h Mon Sep 27 13:00:20 2010
> @@ -123,6 +123,7 @@
>
> private:
> friend class SBThread;
> + friend class lldb_private::ScriptInterpreterPython;
>
> #ifndef SWIG
>
>
> Modified: lldb/trunk/scripts/lldb.swig
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=114849&r1=114848&r2=114849&view=diff
> ==============================================================================
> --- lldb/trunk/scripts/lldb.swig (original)
> +++ lldb/trunk/scripts/lldb.swig Mon Sep 27 13:00:20 2010
> @@ -99,6 +99,15 @@
> #include "lldb/API/SBType.h"
> #include "lldb/API/SBValue.h"
> #include "lldb/API/SBValueList.h"
> +#include "lldb/Interpreter/ScriptInterpreterPython.h"
> +#include "lldb/Breakpoint/Breakpoint.h"
> +#include "lldb/Breakpoint/BreakpointLocation.h"
> +#include "lldb/Breakpoint/StoppointCallbackContext.h"
> +#include "lldb/Target/ExecutionContext.h"
> +#include "lldb/Target/StackFrame.h"
> +#include "lldb/Target/Target.h"
> +#include "lldb/Target/Thread.h"
> +#include "lldb/lldb-forward-rtti.h"
> using namespace lldb_private;
> %}
>
> @@ -157,3 +166,97 @@
> %include "lldb/lldb-types.h"
>
> %include "./Python/python-extensions.swig"
> +
> +
> +%wrapper %{
> +
> +
> +bool
> +ScriptInterpreterPython::BreakpointCallbackFunction (void *baton,
> + StoppointCallbackContext *context,
> + lldb::user_id_t break_id,
> + lldb::user_id_t break_loc_id)
> +{
> + bool ret_value = true;
> +
> + BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
> + const char *python_function_name = bp_option_data->script_source.GetStringAtIndex (0);
> +
> + if (python_function_name != NULL
> + && python_function_name[0] != '\0')
> + {
> + Thread *thread = context->exe_ctx.thread;
> + Target *target = context->exe_ctx.target;
> + const lldb::StackFrameSP stop_frame_sp = thread->GetStackFrameSPForStackFramePtr (context->exe_ctx.frame);
> + lldb::BreakpointSP breakpoint_sp = target->GetBreakpointByID (break_id);
> + const lldb::BreakpointLocationSP bp_loc_sp = breakpoint_sp->FindLocationByID (break_loc_id);
> +
> + lldb::SBFrame sb_frame (stop_frame_sp);
> + lldb::SBBreakpointLocation sb_bp_loc (bp_loc_sp);
> +
> + if (!sb_bp_loc.IsValid() || !sb_frame.IsValid())
> + return ret_value;
> +
> +
> + PyObject *Frame_PyObj = SWIG_NewPointerObj((void *) &sb_frame, SWIGTYPE_p_lldb__SBFrame, 0);
> + PyObject *Bp_Loc_PyObj = SWIG_NewPointerObj ((void *) &sb_bp_loc, SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
> +
> + if (Frame_PyObj == NULL
> + || Bp_Loc_PyObj == NULL)
> + return ret_value;
> +
> + PyObject *pmodule, *pdict, *pfunc;
> + PyObject *pargs, *pvalue;
> +
> + pmodule = PyImport_AddModule ("__main__");
> + if (pmodule != NULL)
> + {
> + pdict = PyModule_GetDict (pmodule);
> + if (pdict != NULL)
> + {
> + pfunc = PyObject_GetAttrString (pmodule, python_function_name);
> + if (pfunc && PyCallable_Check (pfunc))
> + {
> + pargs = PyTuple_New (2);
> + if (pargs == NULL)
> + {
> + if (PyErr_Occurred())
> + PyErr_Clear();
> + return ret_value;
> + }
> +
> + PyTuple_SetItem (pargs, 0, Frame_PyObj); // This "steals" a reference to Frame_PyObj
> + PyTuple_SetItem (pargs, 1, Bp_Loc_PyObj); // This "steals" a reference to Bp_Loc_PyObj
> + pvalue = PyObject_CallObject (pfunc, pargs);
> + Py_DECREF (pargs);
> +
> + if (pvalue != NULL)
> + {
> + Py_DECREF (pvalue);
> + }
> + else if (PyErr_Occurred ())
> + {
> + PyErr_Clear();
> + }
> + Py_DECREF (pfunc);
> + }
> + else if (PyErr_Occurred())
> + {
> + PyErr_Clear();
> + }
> + }
> + else if (PyErr_Occurred())
> + {
> + PyErr_Clear();
> + }
> + }
> + else if (PyErr_Occurred ())
> + {
> + PyErr_Clear ();
> + }
> + }
> +
> + return ret_value;
> +}
> +
> +%}
>
> Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=114849&r1=114848&r2=114849&view=diff
> ==============================================================================
> --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
> +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon Sep 27 13:00:20 2010
> @@ -717,220 +717,44 @@
> {
> static int num_created_functions = 0;
> user_input.RemoveBlankLines ();
> - int num_lines = user_input.GetSize();
> + int num_lines = user_input.GetSize ();
> + StreamString sstr;
>
> - if (num_lines == 1)
> - {
> - callback_data.AppendString (user_input.GetStringAtIndex (0));
> - return true;
> - }
> + // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
> + // frame and breakpoint location as parameters to the function.
>
> - // Traverse user_input exactly once. At each line, either copy line into new, auto-generated function,
> - // increasing indentation by 5 spaces or copy it exactly as is into the user-written
> - // currently-to-be-pushed-to-Python function def. At the end of each Python function def, push the function
> - // to Python, and clear the function string, to start again. At the end of it all, if there is anything in
> - // the auto-generated function, push it to Python and add the function call to it to the callback data.
>
> - bool inside_user_python_function_def = false;
> - std::string whitespace = " \t";
> + sstr.Printf ("lldb_autogen_python_bp_callback_func_%d", num_created_functions);
> + ++num_created_functions;
> + std::string auto_generated_function_name = sstr.GetData();
>
> + sstr.Clear();
> StringList auto_generated_function;
> - StringList user_defined_function;
>
> - StringList *current_function_def = &auto_generated_function;
> - std::string auto_generated_function_name ("lldb_autogen_python_bp_callback_func_");
> + // Create the function name & definition string.
>
> - for (int i = 0; i < num_lines; ++i)
> - {
> - std::string current_line (user_input.GetStringAtIndex(i));
> - size_t idx = current_line.find_first_of (whitespace);
> - if (idx != std::string::npos)
> - {
> - if (idx == 0) // line starts with indentation...
> - {
> - if (inside_user_python_function_def)
> - {
> - // Add this line to the user's python function definition.
> - current_function_def->AppendString (current_line.c_str());
> - }
> - else
> - {
> - // Add this line to our auto-generated function; increase original indentation by 5.
> - StreamString tmp_str;
> - tmp_str.Printf (" %s", current_line.c_str());
> - current_function_def->AppendString (tmp_str.GetData());
> - }
> - }
> - else // line does not start with indentation...
> - {
> - // First, check to see if we just finished a user-written function definition; if so,
> - // wrap it up and send it to Python.
> -
> - if (inside_user_python_function_def && (user_defined_function.GetSize() > 0))
> - {
> - if (! ExportFunctionDefinitionToInterpreter (user_defined_function))
> - {
> - // User entered incorrect Python syntax. We should not attempt to continue.
> - // Clear the callback data, and return immediately.
> - callback_data.Clear();
> - return false;
> - }
> -
> - // User defined function was successfully sent to Python. Clean up after it.
> - user_defined_function.Clear();
> - inside_user_python_function_def = false;
> - current_function_def = &auto_generated_function;
> - }
> -
> - // Next, check to see if we are at the start of a user-defined Python function.
> - std::string first_word = current_line.substr (0, idx);
> - if (first_word.compare ("def") == 0)
> - {
> - // Start the user defined function properly:
> - inside_user_python_function_def = true;
> - current_function_def = &user_defined_function;
> - current_function_def->AppendString (current_line.c_str());
> - }
> - else
> - {
> - // We are in "loose" Python code that we need to collect and put into the auto-generated
> - // function.
> - StreamString tmp_str;
> - current_function_def = &auto_generated_function;
> - if (current_function_def->GetSize() == 0)
> - {
> - // Create the function name, and add insert the function def line.
> - tmp_str.Printf ("%d", num_created_functions);
> - ++num_created_functions;
> - auto_generated_function_name.append (tmp_str.GetData());
> -
> - tmp_str.Clear();
> - tmp_str.Printf ("def %s ():", auto_generated_function_name.c_str());
> - current_function_def->AppendString (tmp_str.GetData());
> - }
> - tmp_str.Clear();
> -
> - // Indent the line an extra 5 spaces and add it to our auto-generated function.
> - tmp_str.Printf (" %s", current_line.c_str());
> - current_function_def->AppendString (tmp_str.GetData());
> - } // else we are in loose Python code
> - } // else current line does not start with indentatin
> - }
> - else
> - {
> - // There was no white space on the line (and therefore no indentation either).
> -
> - // First, check to see if we just finished a user-written function definition; if so,
> - // wrap it up and send it to Python.
> -
> - if (inside_user_python_function_def && (user_defined_function.GetSize() > 0))
> - {
> - if (! ExportFunctionDefinitionToInterpreter (user_defined_function))
> - {
> - // User entered incorrect Python syntax. We should not attempt to continue.
> - // Clear the callback data, and return immediately.
> - callback_data.Clear();
> - return false;
> - }
> -
> - // User defined function was successfully sent to Python. Clean up after it.
> - user_defined_function.Clear();
> - inside_user_python_function_def = false;
> - current_function_def = &auto_generated_function;
> - }
> -
> - // We cannot be at the start of a function definition (they contain white space) so we
> - // must have "loose" python code.
> -
> - StreamString tmp_str;
> - current_function_def = &auto_generated_function;
> - if (current_function_def->GetSize() == 0)
> - {
> - // Create the function name, and add insert the function def line.
> - tmp_str.Printf ("%d", num_created_functions);
> - ++num_created_functions;
> - auto_generated_function_name.append (tmp_str.GetData());
> -
> - tmp_str.Clear();
> - tmp_str.Printf ("def %s ():", auto_generated_function_name.c_str());
> - current_function_def->AppendString (tmp_str.GetData());
> - }
> - tmp_str.Clear();
> -
> - // Indent the line an extra 5 spaces and add it to our auto-generated function.
> - tmp_str.Printf (" %s", current_line.c_str());
> - current_function_def->AppendString (tmp_str.GetData());
> -
> - } // else there was no white space on the line.
> - }
> + sstr.Printf ("def %s (frame, bp_loc):", auto_generated_function_name.c_str());
> + auto_generated_function.AppendString (sstr.GetData());
>
> - // Perhaps the last line of input was also the last line of a user-defined function; if so,
> - // attempt to push the function down to Python.
> + // Wrap everything up inside the function, increasing the indentation.
>
> - if (inside_user_python_function_def && (user_defined_function.GetSize() > 0))
> + for (int i = 0; i < num_lines; ++i)
> {
> - if (! ExportFunctionDefinitionToInterpreter (user_defined_function))
> - {
> - callback_data.Clear();
> - return false;
> - }
> + sstr.Clear ();
> + sstr.Printf (" %s", user_input.GetStringAtIndex (i));
> + auto_generated_function.AppendString (sstr.GetData());
> }
>
> + // Verify that the results are valid Python.
>
> - if (auto_generated_function.GetSize() > 0)
> - {
> - // Export the auto-generated function to Python.
> - if (ExportFunctionDefinitionToInterpreter (auto_generated_function))
> - {
> - // The export succeeded; the syntax must be ok. Generate the function call and put
> - // it in the callback data.
> - StreamString tmp_str;
> - tmp_str.Printf ("%s ()", auto_generated_function_name.c_str());
> - callback_data.AppendString (tmp_str.GetData());
> - return true;
> - }
> - else
> - {
> - // Syntax error!
> - callback_data.Clear();
> - return false;
> - }
> - }
> - else
> + if (!ExportFunctionDefinitionToInterpreter (auto_generated_function))
> {
> - // If there was any code, it consisted entirely of function defs, without any calls to the functions.
> - // No actual exectuable code was therefore generated. (Function calls would have looked like "loose" python,
> - // and would have been collected into the auto-generated function.)
> return false;
> }
> -}
>
> -bool
> -ScriptInterpreterPython::BreakpointCallbackFunction
> -(
> - void *baton,
> - StoppointCallbackContext *context,
> - lldb::user_id_t break_id,
> - lldb::user_id_t break_loc_id
> -)
> -{
> - bool ret_value = true;
> - bool temp_bool;
> -
> - BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
> + // Store the name of the auto-generated function to be called.
>
> - const char *python_string = bp_option_data->script_source.GetStringAtIndex(0);
> -
> - if (python_string != NULL)
> - {
> - bool success = context->exe_ctx.target->GetDebugger().
> - GetCommandInterpreter().
> - GetScriptInterpreter()->ExecuteOneLineWithReturn (python_string,
> - ScriptInterpreter::eBool,
> - (void *) &temp_bool);
> - if (success)
> - ret_value = temp_bool;
> - }
> -
> - return ret_value;
> + callback_data.AppendString (auto_generated_function_name.c_str());
> + return true;
> }
> +
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
More information about the lldb-commits
mailing list