aboutsummaryrefslogtreecommitdiff
path: root/source/Interpreter/ScriptInterpreterPython.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Interpreter/ScriptInterpreterPython.cpp')
-rw-r--r--source/Interpreter/ScriptInterpreterPython.cpp378
1 files changed, 211 insertions, 167 deletions
diff --git a/source/Interpreter/ScriptInterpreterPython.cpp b/source/Interpreter/ScriptInterpreterPython.cpp
index c1d28e88afc1..1b24fea7c218 100644
--- a/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/source/Interpreter/ScriptInterpreterPython.cpp
@@ -31,7 +31,8 @@
#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Timer.h"
-#include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/Pipe.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/PythonDataObjects.h"
@@ -41,33 +42,26 @@ using namespace lldb;
using namespace lldb_private;
-static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = NULL;
-static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = NULL;
-static ScriptInterpreter::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = NULL;
-static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = NULL;
-static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = NULL;
-static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = NULL;
-static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = NULL;
-static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = NULL;
-static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = NULL;
-static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = NULL;
-static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = NULL;
-static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = NULL;
-static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = NULL;
-static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = NULL;
-static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = NULL;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = NULL;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = NULL;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = NULL;
-static ScriptInterpreter::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = NULL;
-static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = NULL;
-
-static int
-_check_and_flush (FILE *stream)
-{
- int prev_fail = ferror (stream);
- return fflush (stream) || prev_fail ? EOF : 0;
-}
+static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = nullptr;
+static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = nullptr;
+static ScriptInterpreter::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = nullptr;
+static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = nullptr;
+static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = nullptr;
+static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = nullptr;
+static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = nullptr;
+static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = nullptr;
+static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue = nullptr;
+static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
+static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
+static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
+static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = nullptr;
+static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
+static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
+static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr;
+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::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;
static std::string
ReadPythonBacktrace (PyObject* py_backtrace);
@@ -100,6 +94,13 @@ ScriptInterpreterPython::Locker::DoAcquireLock()
m_GILState = PyGILState_Ensure();
if (log)
log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
+
+ // we need to save the thread state when we first start the command
+ // because we might decide to interrupt it while some action is taking
+ // place outside of Python (e.g. printing to screen, waiting for the network, ...)
+ // in that case, _PyThreadState_Current will be NULL - and we would be unable
+ // to set the asynchronous exception - not a desirable situation
+ m_python_interpreter->SetThreadState (_PyThreadState_Current);
return true;
}
@@ -156,7 +157,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete
m_session_is_active (false),
m_pty_slave_is_open (false),
m_valid_session (true),
- m_command_thread_state (NULL)
+ m_command_thread_state (nullptr)
{
ScriptInterpreterPython::InitializePrivate ();
@@ -213,7 +214,7 @@ ScriptInterpreterPython::~ScriptInterpreterPython ()
void
ScriptInterpreterPython::IOHandlerActivated (IOHandler &io_handler)
{
- const char *instructions = NULL;
+ const char *instructions = nullptr;
switch (m_active_io_handler)
{
@@ -255,24 +256,30 @@ ScriptInterpreterPython::IOHandlerInputComplete (IOHandler &io_handler, std::str
break;
case eIOHandlerBreakpoint:
{
- BreakpointOptions *bp_options = (BreakpointOptions *)io_handler.GetUserData();
- std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
- if (data_ap.get())
+ std::vector<BreakpointOptions *> *bp_options_vec = (std::vector<BreakpointOptions *> *)io_handler.GetUserData();
+ for (auto bp_options : *bp_options_vec)
{
- data_ap->user_source.SplitIntoLines(data);
-
- if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
+ if (!bp_options)
+ continue;
+
+ std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
+ if (data_ap.get())
{
- BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
- bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
- }
- else if (!batch_mode)
- {
- StreamFileSP error_sp = io_handler.GetErrorStreamFile();
- if (error_sp)
+ data_ap->user_source.SplitIntoLines(data);
+
+ if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source).Success())
{
- error_sp->Printf ("Warning: No command attached to breakpoint.\n");
- error_sp->Flush();
+ BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
+ bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
+ }
+ else if (!batch_mode)
+ {
+ StreamFileSP error_sp = io_handler.GetErrorStreamFile();
+ if (error_sp)
+ {
+ error_sp->Printf ("Warning: No command attached to breakpoint.\n");
+ error_sp->Flush();
+ }
}
}
}
@@ -306,8 +313,6 @@ ScriptInterpreterPython::IOHandlerInputComplete (IOHandler &io_handler, std::str
}
break;
}
-
-
}
@@ -427,42 +432,42 @@ ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
lldb::StreamFileSP in_sp;
lldb::StreamFileSP out_sp;
lldb::StreamFileSP err_sp;
- if (in == NULL || out == NULL || err == NULL)
+ if (in == nullptr || out == nullptr || err == nullptr)
m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid (in_sp, out_sp, err_sp);
- if (in == NULL && in_sp && (on_entry_flags & Locker::NoSTDIN) == 0)
+ if (in == nullptr && in_sp && (on_entry_flags & Locker::NoSTDIN) == 0)
in = in_sp->GetFile().GetStream();
if (in)
{
m_saved_stdin.Reset(sys_module_dict.GetItemForKey("stdin"));
- PyObject *new_file = PyFile_FromFile (in, (char *) "", (char *) "r", 0);
+ PyObject *new_file = PyFile_FromFile (in, (char *) "", (char *) "r", nullptr);
sys_module_dict.SetItemForKey ("stdin", new_file);
Py_DECREF (new_file);
}
else
m_saved_stdin.Reset();
- if (out == NULL && out_sp)
+ if (out == nullptr && out_sp)
out = out_sp->GetFile().GetStream();
if (out)
{
m_saved_stdout.Reset(sys_module_dict.GetItemForKey("stdout"));
- PyObject *new_file = PyFile_FromFile (out, (char *) "", (char *) "w", 0);
+ PyObject *new_file = PyFile_FromFile (out, (char *) "", (char *) "w", nullptr);
sys_module_dict.SetItemForKey ("stdout", new_file);
Py_DECREF (new_file);
}
else
m_saved_stdout.Reset();
- if (err == NULL && err_sp)
+ if (err == nullptr && err_sp)
err = err_sp->GetFile().GetStream();
if (err)
{
m_saved_stderr.Reset(sys_module_dict.GetItemForKey("stderr"));
- PyObject *new_file = PyFile_FromFile (err, (char *) "", (char *) "w", 0);
+ PyObject *new_file = PyFile_FromFile (err, (char *) "", (char *) "w", nullptr);
sys_module_dict.SetItemForKey ("stderr", new_file);
Py_DECREF (new_file);
}
@@ -517,7 +522,7 @@ ScriptInterpreterPython::GetSysModuleDictionary ()
static std::string
GenerateUniqueName (const char* base_name_wanted,
uint32_t& functions_counter,
- void* name_token = NULL)
+ void* name_token = nullptr)
{
StreamString sstr;
@@ -538,7 +543,7 @@ ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects ()
if (!m_run_one_line_function)
{
PyObject *module = PyImport_AddModule ("lldb.embedded_interpreter");
- if (module != NULL)
+ if (module != nullptr)
{
PythonDictionary module_dict (PyModule_GetDict (module));
if (module_dict)
@@ -580,8 +585,7 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec
StreamFileSP output_file_sp;
StreamFileSP error_file_sp;
Communication output_comm ("lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
- int pipe_fds[2] = { -1, -1 };
-
+ bool join_read_thread = false;
if (options.GetEnableIO())
{
if (result)
@@ -589,20 +593,21 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec
input_file_sp = debugger.GetInputFile();
// Set output to a temporary file so we can forward the results on to the result object
- int err = pipe(pipe_fds);
- if (err == 0)
+ Pipe pipe;
+ if (pipe.Open())
{
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe_fds[0], true));
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe.ReleaseReadFileDescriptor(), true));
if (conn_ap->IsConnected())
{
output_comm.SetConnection(conn_ap.release());
output_comm.SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived, &result->GetOutputStream());
output_comm.StartReadThread();
- FILE *outfile_handle = fdopen (pipe_fds[1], "w");
+ join_read_thread = true;
+ FILE *outfile_handle = fdopen (pipe.ReleaseWriteFileDescriptor(), "w");
output_file_sp.reset(new StreamFile(outfile_handle, true));
error_file_sp = output_file_sp;
if (outfile_handle)
- ::setbuf (outfile_handle, NULL);
+ ::setbuf (outfile_handle, nullptr);
result->SetImmediateOutputFile(debugger.GetOutputFile()->GetFile().GetStream());
result->SetImmediateErrorFile(debugger.GetErrorFile()->GetFile().GetStream());
@@ -667,7 +672,7 @@ ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObjec
if (out_file != err_file)
::fflush (err_file);
- if (pipe_fds[0] != -1)
+ if (join_read_thread)
{
// Close the write end of the pipe since we are done with our
// one line script. This should cause the read thread that
@@ -788,10 +793,27 @@ public:
}
- virtual void
+ virtual bool
Interrupt ()
{
-
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+
+ PyThreadState* state = _PyThreadState_Current;
+ if (!state)
+ state = m_python->GetThreadState();
+ if (state)
+ {
+ long tid = state->thread_id;
+ _PyThreadState_Current = state;
+ int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
+ if (log)
+ log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p",
+ tid, num_threads, static_cast<void *>(state));
+ }
+ else if (log)
+ log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");
+
+ return false;
}
virtual void
@@ -834,13 +856,13 @@ ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
{
Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) | Locker::NoSTDIN,
ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
- PyObject *py_return = NULL;
+ PyObject *py_return = nullptr;
PythonObject &main_module = GetMainModule ();
PythonDictionary globals (PyModule_GetDict(main_module.get()));
- PyObject *py_error = NULL;
+ PyObject *py_error = nullptr;
bool ret_success = false;
int success;
@@ -855,25 +877,25 @@ ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
locals = globals;
py_error = PyErr_Occurred();
- if (py_error != NULL)
+ if (py_error != nullptr)
PyErr_Clear();
- if (in_string != NULL)
+ if (in_string != nullptr)
{
{ // scope for PythonInputReaderManager
//PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
py_return = PyRun_String (in_string, Py_eval_input, globals.get(), locals.get());
- if (py_return == NULL)
+ if (py_return == nullptr)
{
py_error = PyErr_Occurred ();
- if (py_error != NULL)
+ if (py_error != nullptr)
PyErr_Clear ();
py_return = PyRun_String (in_string, Py_single_input, globals.get(), locals.get());
}
}
- if (py_return != NULL)
+ if (py_return != nullptr)
{
switch (return_type)
{
@@ -978,7 +1000,7 @@ ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
}
py_error = PyErr_Occurred();
- if (py_error != NULL)
+ if (py_error != nullptr)
{
ret_success = false;
if (options.GetMaskoutErrors())
@@ -998,14 +1020,13 @@ ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const Exec
Error error;
Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0) | Locker::NoSTDIN,
ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
- bool success = false;
PythonObject return_value;
PythonObject &main_module = GetMainModule ();
PythonDictionary globals (PyModule_GetDict(main_module.get()));
- PyObject *py_error = NULL;
+ PyObject *py_error = nullptr;
PythonDictionary locals = GetSessionDictionary ();
@@ -1020,10 +1041,10 @@ ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const Exec
}
py_error = PyErr_Occurred();
- if (py_error != NULL)
+ if (py_error != nullptr)
PyErr_Clear();
- if (in_string != NULL)
+ if (in_string != nullptr)
{
struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
if (compiled_node)
@@ -1031,27 +1052,22 @@ ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const Exec
PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
if (compiled_code)
{
- { // scope for PythonInputReaderManager
- //PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
- return_value.Reset(PyEval_EvalCode (compiled_code, globals.get(), locals.get()));
- }
- if (return_value)
- success = true;
+ return_value.Reset(PyEval_EvalCode (compiled_code, globals.get(), locals.get()));
}
}
}
py_error = PyErr_Occurred ();
- if (py_error != NULL)
+ if (py_error != nullptr)
{
// puts(in_string);
// _PyObject_Dump (py_error);
// PyErr_Print();
// success = false;
- PyObject *type = NULL;
- PyObject *value = NULL;
- PyObject *traceback = NULL;
+ PyObject *type = nullptr;
+ PyObject *value = nullptr;
+ PyObject *traceback = nullptr;
PyErr_Fetch (&type,&value,&traceback);
// get the backtrace
@@ -1075,11 +1091,11 @@ ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const Exec
void
-ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
+ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec,
CommandReturnObject &result)
{
m_active_io_handler = eIOHandlerBreakpoint;
- m_interpreter.GetPythonCommandsFromIOHandler (" ", *this, true, bp_options);
+ m_interpreter.GetPythonCommandsFromIOHandler (" ", *this, true, &bp_options_vec);
}
void
@@ -1090,27 +1106,39 @@ ScriptInterpreterPython::CollectDataForWatchpointCommandCallback (WatchpointOpti
m_interpreter.GetPythonCommandsFromIOHandler (" ", *this, true, wp_options);
}
-// Set a Python one-liner as the callback for the breakpoint.
void
+ScriptInterpreterPython::SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options,
+ const char *function_name)
+{
+ // For now just cons up a oneliner that calls the provided function.
+ std::string oneliner("return ");
+ oneliner += function_name;
+ oneliner += "(frame, bp_loc, internal_dict)";
+ m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
+ oneliner.c_str());
+}
+
+// Set a Python one-liner as the callback for the breakpoint.
+Error
ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
- const char *oneliner)
+ const char *command_body_text)
{
std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
- // It's necessary to set both user_source and script_source to the oneliner.
- // The former is used to generate callback description (as in breakpoint command list)
- // while the latter is used for Python to interpret during the actual callback.
-
- data_ap->user_source.AppendString (oneliner);
- data_ap->script_source.assign (oneliner);
-
- if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
+ // Split the command_body_text into lines, and pass that to GenerateBreakpointCommandCallbackData. That will
+ // wrap the body in an auto-generated function, and return the function name in script_source. That is what
+ // the callback will actually invoke.
+
+ data_ap->user_source.SplitIntoLines(command_body_text);
+ Error error = GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source);
+ if (error.Success())
{
BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
+ return error;
}
-
- return;
+ else
+ return error;
}
// Set a Python one-liner as the callback for the watchpoint.
@@ -1136,24 +1164,32 @@ ScriptInterpreterPython::SetWatchpointCommandCallback (WatchpointOptions *wp_opt
return;
}
-bool
+Error
ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
{
// Convert StringList to one long, newline delimited, const char *.
std::string function_def_string(function_def.CopyList());
- return ExecuteMultipleLines (function_def_string.c_str(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)).Success();
+ Error error = ExecuteMultipleLines (function_def_string.c_str(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
+ return error;
}
-bool
+Error
ScriptInterpreterPython::GenerateFunction(const char *signature, const StringList &input)
{
+ Error error;
int num_lines = input.GetSize ();
if (num_lines == 0)
- return false;
+ {
+ error.SetErrorString ("No input data.");
+ return error;
+ }
if (!signature || *signature == 0)
- return false;
+ {
+ error.SetErrorString("No output function name.");
+ return error;
+ }
StreamString sstr;
StringList auto_generated_function;
@@ -1180,11 +1216,9 @@ ScriptInterpreterPython::GenerateFunction(const char *signature, const StringLis
// Verify that the results are valid Python.
- if (!ExportFunctionDefinitionToInterpreter (auto_generated_function))
- return false;
+ error = ExportFunctionDefinitionToInterpreter (auto_generated_function);
- return true;
-
+ return error;
}
bool
@@ -1204,7 +1238,7 @@ ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std
std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_type_print_func", num_created_functions, name_token));
sstr.Printf ("def %s (valobj, internal_dict):", auto_generated_function_name.c_str());
- if (!GenerateFunction(sstr.GetData(), user_input))
+ if (!GenerateFunction(sstr.GetData(), user_input).Success())
return false;
// Store the name of the auto-generated function to be called.
@@ -1227,7 +1261,7 @@ ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, st
sstr.Printf ("def %s (debugger, args, result, internal_dict):", auto_generated_function_name.c_str());
- if (!GenerateFunction(sstr.GetData(),user_input))
+ if (!GenerateFunction(sstr.GetData(),user_input).Success())
return false;
// Store the name of the auto-generated function to be called.
@@ -1273,7 +1307,7 @@ ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::st
// Verify that the results are valid Python.
// (even though the method is ExportFunctionDefinitionToInterpreter, a class will actually be exported)
// (TODO: rename that method to ExportDefinitionToInterpreter)
- if (!ExportFunctionDefinitionToInterpreter (auto_generated_class))
+ if (!ExportFunctionDefinitionToInterpreter (auto_generated_class).Success())
return false;
// Store the name of the auto-generated class
@@ -1285,7 +1319,7 @@ ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::st
lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp)
{
- if (class_name == NULL || class_name[0] == '\0')
+ if (class_name == nullptr || class_name[0] == '\0')
return lldb::ScriptInterpreterObjectSP();
if (!process_sp)
@@ -1319,7 +1353,7 @@ ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP
PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
- if (implementor == NULL || implementor == Py_None)
+ if (implementor == nullptr || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
@@ -1329,7 +1363,7 @@ ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP
PyErr_Clear();
}
- if (pmeth == NULL || pmeth == Py_None)
+ if (pmeth == nullptr || pmeth == Py_None)
{
Py_XDECREF(pmeth);
return lldb::ScriptInterpreterObjectSP();
@@ -1354,7 +1388,7 @@ ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP
Py_XDECREF(pmeth);
// right now we know this function exists and is callable..
- PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL);
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
// if it fails, print the error but otherwise go on
if (PyErr_Occurred())
@@ -1380,7 +1414,7 @@ ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP o
PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
- if (implementor == NULL || implementor == Py_None)
+ if (implementor == nullptr || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
@@ -1390,7 +1424,7 @@ ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP o
PyErr_Clear();
}
- if (pmeth == NULL || pmeth == Py_None)
+ if (pmeth == nullptr || pmeth == Py_None)
{
Py_XDECREF(pmeth);
return lldb::ScriptInterpreterObjectSP();
@@ -1415,7 +1449,7 @@ ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP o
Py_XDECREF(pmeth);
// right now we know this function exists and is callable..
- PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL);
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
// if it fails, print the error but otherwise go on
if (PyErr_Occurred())
@@ -1437,7 +1471,7 @@ template <typename T>
const char *GetPythonValueFormatString(T t)
{
assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type.");
- return NULL;
+ return nullptr;
}
template <> const char *GetPythonValueFormatString (char *) { return "s"; }
template <> const char *GetPythonValueFormatString (char) { return "b"; }
@@ -1469,7 +1503,7 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterOb
PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
- if (implementor == NULL || implementor == Py_None)
+ if (implementor == nullptr || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
@@ -1479,7 +1513,7 @@ ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterOb
PyErr_Clear();
}
- if (pmeth == NULL || pmeth == Py_None)
+ if (pmeth == nullptr || pmeth == Py_None)
{
Py_XDECREF(pmeth);
return lldb::ScriptInterpreterObjectSP();
@@ -1535,7 +1569,7 @@ ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP
PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
- if (implementor == NULL || implementor == Py_None)
+ if (implementor == nullptr || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
@@ -1545,7 +1579,7 @@ ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP
PyErr_Clear();
}
- if (pmeth == NULL || pmeth == Py_None)
+ if (pmeth == nullptr || pmeth == Py_None)
{
Py_XDECREF(pmeth);
return lldb::ScriptInterpreterObjectSP();
@@ -1627,7 +1661,7 @@ lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name,
lldb::ValueObjectSP valobj)
{
- if (class_name == NULL || class_name[0] == '\0')
+ if (class_name == nullptr || class_name[0] == '\0')
return lldb::ScriptInterpreterObjectSP();
if (!valobj.get())
@@ -1675,25 +1709,29 @@ ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::stri
}
-bool
+Error
ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, std::string& output)
{
static uint32_t num_created_functions = 0;
user_input.RemoveBlankLines ();
StreamString sstr;
-
+ Error error;
if (user_input.GetSize() == 0)
- return false;
+ {
+ error.SetErrorString("No input data.");
+ return error;
+ }
std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_bp_callback_func_",num_created_functions));
sstr.Printf ("def %s (frame, bp_loc, internal_dict):", auto_generated_function_name.c_str());
- if (!GenerateFunction(sstr.GetData(), user_input))
- return false;
+ error = GenerateFunction(sstr.GetData(), user_input);
+ if (!error.Success())
+ return error;
// Store the name of the auto-generated function to be called.
output.assign(auto_generated_function_name);
- return true;
+ return error;
}
bool
@@ -1709,7 +1747,7 @@ ScriptInterpreterPython::GenerateWatchpointCommandCallbackData (StringList &user
std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_wp_callback_func_",num_created_functions));
sstr.Printf ("def %s (frame, wp, internal_dict):", auto_generated_function_name.c_str());
- if (!GenerateFunction(sstr.GetData(), user_input))
+ if (!GenerateFunction(sstr.GetData(), user_input).Success())
return false;
// Store the name of the auto-generated function to be called.
@@ -1732,7 +1770,7 @@ ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
return false;
}
- void* old_callee = (callee_wrapper_sp ? callee_wrapper_sp->GetObject() : NULL);
+ void* old_callee = (callee_wrapper_sp ? callee_wrapper_sp->GetObject() : nullptr);
void* new_callee = old_callee;
bool ret_val;
@@ -1764,6 +1802,21 @@ ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
}
+void
+ScriptInterpreterPython::Clear ()
+{
+ // Release any global variables that might have strong references to
+ // LLDB objects when clearing the python script interpreter.
+ Locker locker(this,
+ ScriptInterpreterPython::Locker::AcquireLock,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock);
+
+ // This may be called as part of Py_Finalize. In that case the modules are destroyed in random
+ // order and we can't guarantee that we can access these.
+ if (Py_IsInitialized())
+ PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process = None; lldb.thread = None; lldb.frame = None");
+}
+
bool
ScriptInterpreterPython::BreakpointCallbackFunction
(
@@ -1914,10 +1967,10 @@ ScriptInterpreterPython::GetChildAtIndex (const lldb::ScriptInterpreterObjectSP&
{
Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
void* child_ptr = g_swig_get_child_index (implementor,idx);
- if (child_ptr != NULL && child_ptr != Py_None)
+ if (child_ptr != nullptr && child_ptr != Py_None)
{
lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
- if (sb_value_ptr == NULL)
+ if (sb_value_ptr == nullptr)
Py_XDECREF(child_ptr);
else
ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
@@ -2006,15 +2059,15 @@ ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::Scr
static std::string
ReadPythonBacktrace (PyObject* py_backtrace)
{
- PyObject* traceback_module = NULL,
- *stringIO_module = NULL,
- *stringIO_builder = NULL,
- *stringIO_buffer = NULL,
- *printTB = NULL,
- *printTB_args = NULL,
- *printTB_result = NULL,
- *stringIO_getvalue = NULL,
- *printTB_string = NULL;
+ PyObject* traceback_module = nullptr,
+ *stringIO_module = nullptr,
+ *stringIO_builder = nullptr,
+ *stringIO_buffer = nullptr,
+ *printTB = nullptr,
+ *printTB_args = nullptr,
+ *printTB_result = nullptr,
+ *stringIO_getvalue = nullptr,
+ *printTB_string = nullptr;
std::string retval("backtrace unavailable");
@@ -2028,7 +2081,7 @@ ReadPythonBacktrace (PyObject* py_backtrace)
stringIO_builder = PyObject_GetAttrString(stringIO_module, "StringIO");
if (stringIO_builder && stringIO_builder != Py_None)
{
- stringIO_buffer = PyObject_CallObject(stringIO_builder, NULL);
+ stringIO_buffer = PyObject_CallObject(stringIO_builder, nullptr);
if (stringIO_buffer && stringIO_buffer != Py_None)
{
printTB = PyObject_GetAttrString(traceback_module, "print_tb");
@@ -2039,7 +2092,7 @@ ReadPythonBacktrace (PyObject* py_backtrace)
stringIO_getvalue = PyObject_GetAttrString(stringIO_buffer, "getvalue");
if (stringIO_getvalue && stringIO_getvalue != Py_None)
{
- printTB_string = PyObject_CallObject (stringIO_getvalue,NULL);
+ printTB_string = PyObject_CallObject (stringIO_getvalue,nullptr);
if (printTB_string && printTB_string != Py_None && PyString_Check(printTB_string))
retval.assign(PyString_AsString(printTB_string));
}
@@ -2393,29 +2446,20 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
{
error.SetErrorString("invalid Debugger pointer");
return false;
- }
+ }
bool ret_val = false;
std::string err_msg;
-
+
{
Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession,
+ Locker::AcquireLock | Locker::InitSession | (cmd_retobj.GetInteractive() ? 0 : Locker::NoSTDIN),
Locker::FreeLock | Locker::TearDownSession);
SynchronicityHandler synch_handler(debugger_sp,
synchronicity);
- // we need to save the thread state when we first start the command
- // because we might decide to interrupt it while some action is taking
- // place outside of Python (e.g. printing to screen, waiting for the network, ...)
- // in that case, _PyThreadState_Current will be NULL - and we would be unable
- // to set the asynchronous exception - not a desirable situation
- m_command_thread_state = _PyThreadState_Current;
-
- //PythonInputReaderManager py_input(this);
-
ret_val = g_swig_call_command (impl_function,
m_dictionary_name.c_str(),
debugger_sp,
@@ -2443,7 +2487,7 @@ ScriptInterpreterPython::GetDocumentationForItem(const char* item, std::string&
std::string command(item);
command += ".__doc__";
- char* result_ptr = NULL; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
+ char* result_ptr = nullptr; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
if (ExecuteOneLineWithReturn (command.c_str(),
ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
@@ -2561,7 +2605,7 @@ ScriptInterpreterPython::InitializePrivate ()
FileSpec file_spec;
char python_dir_path[PATH_MAX];
- if (Host::GetLLDBPath (ePathTypePythonDir, file_spec))
+ if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec))
{
std::string python_path("sys.path.insert(0,\"");
size_t orig_len = python_path.length();
@@ -2572,8 +2616,8 @@ ScriptInterpreterPython::InitializePrivate ()
PyRun_SimpleString (python_path.c_str());
python_path.resize (orig_len);
}
-
- if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, file_spec))
+
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec))
{
if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
{
@@ -2585,7 +2629,7 @@ ScriptInterpreterPython::InitializePrivate ()
}
}
- PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line; from termios import *");
+ PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line");
if (threads_already_initialized) {
if (log)