diff options
Diffstat (limited to 'lldb/source')
22 files changed, 1297 insertions, 141 deletions
diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index 121d742da91..2fc834d9d50 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -72,6 +72,13 @@ add_lldb_library(liblldb SHARED ${LLDB_VERS_GENERATED_FILE} ) +# This should not be part of LLDBDependencies.cmake, because we don't +# want every single library taking a dependency on the script interpreters. +target_link_libraries(liblldb PRIVATE + lldbPluginScriptInterpreterNone + lldbPluginScriptInterpreterPython + ) + set_target_properties(liblldb PROPERTIES VERSION ${LLDB_VERSION} diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index d901e728105..cd1e28e7115 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// #include "lldb/lldb-types.h" -#include "lldb/Core/SourceManager.h" + #include "lldb/Core/Listener.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObjectMultiword.h" diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index 01ad8157646..cccd9876be9 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -7,12 +7,23 @@ // //===----------------------------------------------------------------------===// +#if !defined(LLDB_DISABLE_PYTHON) +#include "Plugins/ScriptInterpreter/Python/lldb-python.h" +#endif + #include "lldb/API/SystemInitializerFull.h" +#include "lldb/API/SBCommandInterpreter.h" + +#if !defined(LLDB_DISABLE_PYTHON) +#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h" +#endif + #include "lldb/Core/Debugger.h" #include "lldb/Core/Timer.h" #include "lldb/Host/Host.h" #include "lldb/Initialization/SystemInitializerCommon.h" +#include "lldb/Interpreter/CommandInterpreter.h" #include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h" #include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h" @@ -38,6 +49,7 @@ #include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" #include "Plugins/Process/elf-core/ProcessElfCore.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemote.h" +#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h" #include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h" @@ -61,10 +73,6 @@ #include "Plugins/Process/Windows/ProcessWindows.h" #endif -#if !defined(LLDB_DISABLE_PYTHON) -#include "lldb/Interpreter/ScriptInterpreterPython.h" -#endif - #include "llvm/Support/TargetSelect.h" #include <string> @@ -221,9 +229,17 @@ SystemInitializerFull::~SystemInitializerFull() void SystemInitializerFull::Initialize() { + SystemInitializerCommon::Initialize(); + +#if !defined(LLDB_DISABLE_PYTHON) InitializeSWIG(); - SystemInitializerCommon::Initialize(); + // ScriptInterpreterPython::Initialize() depends on things like HostInfo being initialized + // so it can compute the python directory etc, so we need to do this after + // SystemInitializerCommon::Initialize(). + ScriptInterpreterNone::Initialize(); + ScriptInterpreterPython::Initialize(); +#endif // Initialize LLVM and Clang llvm::InitializeAllTargets(); @@ -380,8 +396,3 @@ SystemInitializerFull::Terminate() // Now shutdown the common parts, in reverse order. SystemInitializerCommon::Terminate(); } - -void SystemInitializerFull::TerminateSWIG() -{ - -} diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index 7d916539ce9..ac892d261e4 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -1764,6 +1764,110 @@ PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name) return NULL; } +#pragma mark ScriptInterpreter + +struct ScriptInterpreterInstance +{ + ScriptInterpreterInstance() + : name() + , language(lldb::eScriptLanguageNone) + , description() + , create_callback(NULL) + { + } + + ConstString name; + lldb::ScriptLanguage language; + std::string description; + ScriptInterpreterCreateInstance create_callback; +}; + +typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances; + +static Mutex & +GetScriptInterpreterMutex() +{ + static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive); + return g_instances_mutex; +} + +static ScriptInterpreterInstances & +GetScriptInterpreterInstances() +{ + static ScriptInterpreterInstances g_instances; + return g_instances; +} + +bool +PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language, + ScriptInterpreterCreateInstance create_callback) +{ + if (!create_callback) + return false; + ScriptInterpreterInstance instance; + assert((bool)name); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + instance.language = script_language; + Mutex::Locker locker(GetScriptInterpreterMutex()); + GetScriptInterpreterInstances().push_back(instance); + return false; +} + +bool +PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback) +{ + if (!create_callback) + return false; + Mutex::Locker locker(GetScriptInterpreterMutex()); + ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); + + ScriptInterpreterInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++pos) + { + if (pos->create_callback != create_callback) + continue; + + instances.erase(pos); + return true; + } + return false; +} + +ScriptInterpreterCreateInstance +PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) +{ + Mutex::Locker locker(GetScriptInterpreterMutex()); + ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); + if (idx < instances.size()) + return instances[idx].create_callback; + return nullptr; +} + +lldb::ScriptInterpreterSP +PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) +{ + Mutex::Locker locker(GetScriptInterpreterMutex()); + ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); + + ScriptInterpreterInstances::iterator pos, end = instances.end(); + ScriptInterpreterCreateInstance none_instance = nullptr; + for (pos = instances.begin(); pos != end; ++pos) + { + if (pos->language == lldb::eScriptLanguageNone) + none_instance = pos->create_callback; + + if (script_lang == pos->language) + return pos->create_callback(interpreter); + } + + // If we didn't find one, return the ScriptInterpreter for the null language. + assert(none_instance != nullptr); + return none_instance(interpreter); +} + #pragma mark SymbolFile struct SymbolFileInstance diff --git a/lldb/source/Host/macosx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/HostInfoMacOSX.mm index edaff083373..97388495d08 100644 --- a/lldb/source/Host/macosx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/HostInfoMacOSX.mm @@ -7,7 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/lldb-python.h" +#if !defined(LLDB_DISABLE_PYTHON) +#include "Plugins/ScriptInterpreter/Python/lldb-python.h" +#endif #include "lldb/Host/HostInfo.h" #include "lldb/Host/macosx/HostInfoMacOSX.h" diff --git a/lldb/source/Host/posix/HostInfoPosix.cpp b/lldb/source/Host/posix/HostInfoPosix.cpp index c04db71e1b8..632f422bc62 100644 --- a/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/lldb/source/Host/posix/HostInfoPosix.cpp @@ -7,7 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "lldb/lldb-python.h" +#if !defined(LLDB_DISABLE_PYTHON) +#include "Plugins/ScriptInterpreter/Python/lldb-python.h" +#endif + #include "lldb/Core/Log.h" #include "lldb/Host/posix/HostInfoPosix.h" diff --git a/lldb/source/Initialization/SystemInitializerCommon.cpp b/lldb/source/Initialization/SystemInitializerCommon.cpp index 51f32a2776a..dcf823e2dc7 100644 --- a/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -13,7 +13,6 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Core/Log.h" #include "lldb/Core/Timer.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" @@ -141,7 +140,6 @@ SystemInitializerCommon::Initialize() ProcessWindowsLog::Initialize(); #endif #ifndef LLDB_DISABLE_PYTHON - ScriptInterpreterPython::InitializePrivate(); OperatingSystemPython::Initialize(); #endif } diff --git a/lldb/source/Interpreter/CMakeLists.txt b/lldb/source/Interpreter/CMakeLists.txt index 413067f91fc..220e6a0b4e5 100644 --- a/lldb/source/Interpreter/CMakeLists.txt +++ b/lldb/source/Interpreter/CMakeLists.txt @@ -43,8 +43,5 @@ add_lldb_library(lldbInterpreter OptionGroupWatchpoint.cpp Options.cpp Property.cpp - PythonDataObjects.cpp ScriptInterpreter.cpp - ScriptInterpreterNone.cpp - ScriptInterpreterPython.cpp ) diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index 965ba5b7dc1..1147d1330de 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -41,9 +41,9 @@ #include "../Commands/CommandObjectWatchpoint.h" #include "../Commands/CommandObjectLanguage.h" - #include "lldb/Core/Debugger.h" #include "lldb/Core/Log.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamFile.h" @@ -62,8 +62,6 @@ #include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" -#include "lldb/Interpreter/ScriptInterpreterNone.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" #include "lldb/Target/Process.h" @@ -104,29 +102,23 @@ CommandInterpreter::GetStaticBroadcasterClass () return class_name; } -CommandInterpreter::CommandInterpreter -( - Debugger &debugger, - ScriptLanguage script_language, - bool synchronous_execution -) : - Broadcaster (&debugger, CommandInterpreter::GetStaticBroadcasterClass().AsCString()), - Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))), - IOHandlerDelegate (IOHandlerDelegate::Completion::LLDBCommand), - m_debugger (debugger), - m_synchronous_execution (synchronous_execution), - m_skip_lldbinit_files (false), - m_skip_app_init_files (false), - m_script_interpreter_ap (), - m_command_io_handler_sp (), - m_comment_char ('#'), - m_batch_command_mode (false), - m_truncation_warning(eNoTruncation), - m_command_source_depth (0), - m_num_errors(0), - m_quit_requested(false), - m_stopped_for_crash(false) - +CommandInterpreter::CommandInterpreter(Debugger &debugger, ScriptLanguage script_language, bool synchronous_execution) + : Broadcaster(&debugger, CommandInterpreter::GetStaticBroadcasterClass().AsCString()), + Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))), + IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand), + m_debugger(debugger), + m_synchronous_execution(synchronous_execution), + m_skip_lldbinit_files(false), + m_skip_app_init_files(false), + m_script_interpreter_sp(), + m_command_io_handler_sp(), + m_comment_char('#'), + m_batch_command_mode(false), + m_truncation_warning(eNoTruncation), + m_command_source_depth(0), + m_num_errors(0), + m_quit_requested(false), + m_stopped_for_crash(false) { debugger.SetScriptLanguage (script_language); SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit"); @@ -392,9 +384,9 @@ void CommandInterpreter::Clear() { m_command_io_handler_sp.reset(); - - if (m_script_interpreter_ap) - m_script_interpreter_ap->Clear(); + + if (m_script_interpreter_sp) + m_script_interpreter_sp->Clear(); } const char * @@ -2708,48 +2700,19 @@ CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file, } ScriptInterpreter * -CommandInterpreter::GetScriptInterpreter (bool can_create) +CommandInterpreter::GetScriptInterpreter(bool can_create) { - if (m_script_interpreter_ap.get() != nullptr) - return m_script_interpreter_ap.get(); - + if (m_script_interpreter_sp) + return m_script_interpreter_sp.get(); + if (!can_create) return nullptr; - - // <rdar://problem/11751427> - // we need to protect the initialization of the script interpreter - // otherwise we could end up with two threads both trying to create - // their instance of it, and for some languages (e.g. Python) - // this is a bulletproof recipe for disaster! - // this needs to be a function-level static because multiple Debugger instances living in the same process - // still need to be isolated and not try to initialize Python concurrently - static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive); - Mutex::Locker interpreter_lock(g_interpreter_mutex); - - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); - if (log) - log->Printf("Initializing the ScriptInterpreter now\n"); - + lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage(); - switch (script_lang) - { - case eScriptLanguagePython: -#ifndef LLDB_DISABLE_PYTHON - m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this)); - break; -#else - // Fall through to the None case when python is disabled -#endif - case eScriptLanguageNone: - m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this)); - break; - }; - - return m_script_interpreter_ap.get(); + m_script_interpreter_sp = PluginManager::GetScriptInterpreterForLanguage(script_lang, *this); + return m_script_interpreter_sp.get(); } - - bool CommandInterpreter::GetSynchronous () { diff --git a/lldb/source/Interpreter/ScriptInterpreterNone.cpp b/lldb/source/Interpreter/ScriptInterpreterNone.cpp deleted file mode 100644 index 909a1161c9c..00000000000 --- a/lldb/source/Interpreter/ScriptInterpreterNone.cpp +++ /dev/null @@ -1,42 +0,0 @@ -//===-- ScriptInterpreterNone.cpp -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Interpreter/ScriptInterpreterNone.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/StringList.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Interpreter/CommandInterpreter.h" - -using namespace lldb; -using namespace lldb_private; - -ScriptInterpreterNone::ScriptInterpreterNone (CommandInterpreter &interpreter) : - ScriptInterpreter (interpreter, eScriptLanguageNone) -{ -} - -ScriptInterpreterNone::~ScriptInterpreterNone () -{ -} - -bool -ScriptInterpreterNone::ExecuteOneLine (const char *command, CommandReturnObject *, const ExecuteScriptOptions&) -{ - m_interpreter.GetDebugger().GetErrorFile()->PutCString ("error: there is no embedded script interpreter in this mode.\n"); - return false; -} - -void -ScriptInterpreterNone::ExecuteInterpreterLoop () -{ - m_interpreter.GetDebugger().GetErrorFile()->PutCString ("error: there is no embedded script interpreter in this mode.\n"); -} - - diff --git a/lldb/source/Plugins/CMakeLists.txt b/lldb/source/Plugins/CMakeLists.txt index 9219560ff44..67ae85de81e 100644 --- a/lldb/source/Plugins/CMakeLists.txt +++ b/lldb/source/Plugins/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory(ObjectFile) add_subdirectory(OperatingSystem) add_subdirectory(Platform) add_subdirectory(Process) +add_subdirectory(ScriptInterpreter) add_subdirectory(SymbolFile) add_subdirectory(SystemRuntime) add_subdirectory(SymbolVendor) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index f5f134e80d6..e3d5bea0128 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -17,9 +17,6 @@ #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/StreamString.h" -#ifndef LLDB_DISABLE_PYTHON -#include "lldb/Interpreter/PythonDataObjects.h" -#endif #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Utils.h" diff --git a/lldb/source/Plugins/ScriptInterpreter/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/CMakeLists.txt new file mode 100644 index 00000000000..dc2a27d95a3 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(None) +add_subdirectory(Python) diff --git a/lldb/source/Plugins/ScriptInterpreter/None/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/None/CMakeLists.txt new file mode 100644 index 00000000000..5692d2f9071 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/None/CMakeLists.txt @@ -0,0 +1,3 @@ +add_lldb_library(lldbPluginScriptInterpreterNone + ScriptInterpreterNone.cpp + )
\ No newline at end of file diff --git a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp new file mode 100644 index 00000000000..1a352fa1987 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp @@ -0,0 +1,93 @@ +//===-- ScriptInterpreterNone.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ScriptInterpreterNone.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/StringList.h" +#include "lldb/Interpreter/CommandInterpreter.h" + +#include <mutex> + +using namespace lldb; +using namespace lldb_private; + +ScriptInterpreterNone::ScriptInterpreterNone(CommandInterpreter &interpreter) + : ScriptInterpreter(interpreter, eScriptLanguageNone) +{ +} + +ScriptInterpreterNone::~ScriptInterpreterNone() +{ +} + +bool +ScriptInterpreterNone::ExecuteOneLine(const char *command, CommandReturnObject *, const ExecuteScriptOptions &) +{ + m_interpreter.GetDebugger().GetErrorFile()->PutCString( + "error: there is no embedded script interpreter in this mode.\n"); + return false; +} + +void +ScriptInterpreterNone::ExecuteInterpreterLoop() +{ + m_interpreter.GetDebugger().GetErrorFile()->PutCString( + "error: there is no embedded script interpreter in this mode.\n"); +} + +void +ScriptInterpreterNone::Initialize() +{ + static std::once_flag g_once_flag; + + std::call_once(g_once_flag, []() + { + PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), + lldb::eScriptLanguageNone, CreateInstance); + }); +} + +void +ScriptInterpreterNone::Terminate() +{ +} + +lldb::ScriptInterpreterSP +ScriptInterpreterNone::CreateInstance(CommandInterpreter &interpreter) +{ + return std::make_shared<ScriptInterpreterNone>(interpreter); +} + +lldb_private::ConstString +ScriptInterpreterNone::GetPluginNameStatic() +{ + static ConstString g_name("script-none"); + return g_name; +} + +const char * +ScriptInterpreterNone::GetPluginDescriptionStatic() +{ + return "Null script interpreter"; +} + +lldb_private::ConstString +ScriptInterpreterNone::GetPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t +ScriptInterpreterNone::GetPluginVersion() +{ + return 1; +} diff --git a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h new file mode 100644 index 00000000000..d29600a7645 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h @@ -0,0 +1,62 @@ +//===-- ScriptInterpreterNone.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ScriptInterpreterNone_h_ +#define liblldb_ScriptInterpreterNone_h_ + +#include "lldb/Interpreter/ScriptInterpreter.h" + +namespace lldb_private +{ + +class ScriptInterpreterNone : public ScriptInterpreter +{ + public: + ScriptInterpreterNone(CommandInterpreter &interpreter); + + ~ScriptInterpreterNone(); + + bool + ExecuteOneLine(const char *command, CommandReturnObject *result, + const ExecuteScriptOptions &options = ExecuteScriptOptions()); + + void + ExecuteInterpreterLoop(); + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static lldb::ScriptInterpreterSP + CreateInstance(CommandInterpreter &interpreter); + + static lldb_private::ConstString + GetPluginNameStatic(); + + static const char * + GetPluginDescriptionStatic(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + virtual lldb_private::ConstString + GetPluginName(); + + virtual uint32_t + GetPluginVersion(); +}; + +} // namespace lldb_private + +#endif // #ifndef liblldb_ScriptInterpreterNone_h_ diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt new file mode 100644 index 00000000000..16efb4e1e1e --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt @@ -0,0 +1,4 @@ +add_lldb_library(lldbPluginScriptInterpreterPython + PythonDataObjects.cpp + ScriptInterpreterPython.cpp + ) diff --git a/lldb/source/Interpreter/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index a581a0b3601..4f81d07b3e5 100644 --- a/lldb/source/Interpreter/PythonDataObjects.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -7,23 +7,21 @@ // //===----------------------------------------------------------------------===// -// In order to guarantee correct working with Python, Python.h *MUST* be -// the *FIRST* header file included here. #ifdef LLDB_DISABLE_PYTHON // Python is disabled in this build #else -#include "lldb/lldb-python.h" - -#include <stdio.h> +#include "lldb-python.h" +#include "PythonDataObjects.h" +#include "ScriptInterpreterPython.h" #include "lldb/Core/Stream.h" #include "lldb/Host/File.h" -#include "lldb/Interpreter/PythonDataObjects.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" + +#include <stdio.h> using namespace lldb_private; using namespace lldb; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h new file mode 100644 index 00000000000..43963589cc1 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -0,0 +1,279 @@ +//===-- PythonDataObjects.h----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H + +// C Includes +// C++ Includes + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-defines.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/StructuredData.h" +#include "lldb/Core/Flags.h" +#include "lldb/Interpreter/OptionValue.h" + +namespace lldb_private { +class PythonString; +class PythonList; +class PythonDictionary; +class PythonObject; +class PythonInteger; + +class StructuredPythonObject : public StructuredData::Generic +{ + public: + StructuredPythonObject() + : StructuredData::Generic() + { + } + + StructuredPythonObject(void *obj) + : StructuredData::Generic(obj) + { + Py_XINCREF(GetValue()); + } + + virtual ~StructuredPythonObject() + { + if (Py_IsInitialized()) + Py_XDECREF(GetValue()); + SetValue(nullptr); + } + + bool + IsValid() const override + { + return GetValue() && GetValue() != Py_None; + } + + void Dump(Stream &s) const override; + + private: + DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); +}; + +enum class PyObjectType +{ + Unknown, + None, + Integer, + Dictionary, + List, + String +}; + + class PythonObject + { + public: + PythonObject () : + m_py_obj(NULL) + { + } + + explicit PythonObject (PyObject* py_obj) : + m_py_obj(NULL) + { + Reset (py_obj); + } + + PythonObject (const PythonObject &rhs) : + m_py_obj(NULL) + { + Reset (rhs.m_py_obj); + } + + virtual + ~PythonObject () + { + Reset (NULL); + } + + bool + Reset (const PythonObject &object) + { + return Reset(object.get()); + } + + virtual bool + Reset (PyObject* py_obj = NULL) + { + if (py_obj != m_py_obj) + { + if (Py_IsInitialized()) + Py_XDECREF(m_py_obj); + m_py_obj = py_obj; + if (Py_IsInitialized()) + Py_XINCREF(m_py_obj); + } + return true; + } + + void + Dump () const + { + if (m_py_obj) + _PyObject_Dump (m_py_obj); + else + puts ("NULL"); + } + + void + Dump (Stream &strm) const; + + PyObject* + get () const + { + return m_py_obj; + } + + PyObjectType GetObjectType() const; + + PythonString + Repr (); + + PythonString + Str (); + + explicit operator bool () const + { + return m_py_obj != NULL; + } + + bool + IsNULLOrNone () const; + + StructuredData::ObjectSP CreateStructuredObject() const; + + protected: + PyObject* m_py_obj; + }; + + class PythonString: public PythonObject + { + public: + PythonString (); + PythonString (PyObject *o); + PythonString (const PythonObject &object); + PythonString (llvm::StringRef string); + PythonString (const char *string); + virtual ~PythonString (); + + virtual bool + Reset (PyObject* py_obj = NULL); + + llvm::StringRef + GetString() const; + + size_t + GetSize() const; + + void SetString(llvm::StringRef string); + + StructuredData::StringSP CreateStructuredString() const; + }; + + class PythonInteger: public PythonObject + { + public: + + PythonInteger (); + PythonInteger (PyObject* py_obj); + PythonInteger (const PythonObject &object); + PythonInteger (int64_t value); + virtual ~PythonInteger (); + + virtual bool + Reset (PyObject* py_obj = NULL); + + int64_t GetInteger() const; + + void + SetInteger (int64_t value); + + StructuredData::IntegerSP CreateStructuredInteger() const; + }; + + class PythonList: public PythonObject + { + public: + + PythonList (bool create_empty); + PythonList (PyObject* py_obj); + PythonList (const PythonObject &object); + PythonList (uint32_t count); + virtual ~PythonList (); + + virtual bool + Reset (PyObject* py_obj = NULL); + + uint32_t GetSize() const; + + PythonObject GetItemAtIndex(uint32_t index) const; + + void + SetItemAtIndex (uint32_t index, const PythonObject &object); + + void + AppendItem (const PythonObject &object); + + StructuredData::ArraySP CreateStructuredArray() const; + }; + + class PythonDictionary: public PythonObject + { + public: + + explicit PythonDictionary (bool create_empty); + PythonDictionary (PyObject* object); + PythonDictionary (const PythonObject &object); + virtual ~PythonDictionary (); + + virtual bool + Reset (PyObject* object = NULL); + + uint32_t GetSize() const; + + PythonObject + GetItemForKey (const PythonString &key) const; + + const char * + GetItemForKeyAsString (const PythonString &key, const char *fail_value = NULL) const; + + int64_t + GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value = 0) const; + + PythonObject + GetItemForKey (const char *key) const; + + typedef bool (*DictionaryIteratorCallback)(PythonString* key, PythonDictionary* dict); + + PythonList + GetKeys () const; + + PythonString + GetKeyAtPosition (uint32_t pos) const; + + PythonObject + GetValueAtPosition (uint32_t pos) const; + + void + SetItemForKey (const PythonString &key, PyObject *value); + + void + SetItemForKey (const PythonString &key, const PythonObject& value); + + StructuredData::DictionarySP CreateStructuredDictionary() const; + }; + +} // namespace lldb_private + +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 88b98f66a79..b7e6cb1f44e 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -7,20 +7,20 @@ // //===----------------------------------------------------------------------===// -// In order to guarantee correct working with Python, Python.h *MUST* be -// the *FIRST* header file included here. #ifdef LLDB_DISABLE_PYTHON // Python is disabled in this build #else -#include "lldb/lldb-python.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" +#include "lldb-python.h" +#include "ScriptInterpreterPython.h" +#include "PythonDataObjects.h" #include <stdlib.h> #include <stdio.h> +#include <mutex> #include <string> #include "lldb/API/SBValue.h" @@ -29,6 +29,7 @@ #include "lldb/Breakpoint/WatchpointOptions.h" #include "lldb/Core/Communication.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Core/Timer.h" #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -37,7 +38,6 @@ #include "lldb/Host/Pipe.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/PythonDataObjects.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -178,7 +178,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete m_lock_count (0), m_command_thread_state (nullptr) { - assert(g_initialized && "ScriptInterpreterPython created but initialize has not been called!"); + assert(g_initialized && "ScriptInterpreterPython created but InitializePrivate has not been called!"); m_dictionary_name.append("_dict"); StreamString run_string; @@ -223,6 +223,59 @@ ScriptInterpreterPython::~ScriptInterpreterPython () } void +ScriptInterpreterPython::Initialize() +{ + static std::once_flag g_once_flag; + + std::call_once(g_once_flag, []() + { + InitializePrivate(); + + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), + lldb::eScriptLanguagePython, + CreateInstance); + }); +} + +void +ScriptInterpreterPython::Terminate() +{ + +} + +lldb::ScriptInterpreterSP +ScriptInterpreterPython::CreateInstance(CommandInterpreter &interpreter) +{ + return std::make_shared<ScriptInterpreterPython>(interpreter); +} + +lldb_private::ConstString +ScriptInterpreterPython::GetPluginNameStatic() +{ + static ConstString g_name("script-python"); + return g_name; +} + +const char * +ScriptInterpreterPython::GetPluginDescriptionStatic() +{ + return "Embedded Python interpreter"; +} + +lldb_private::ConstString +ScriptInterpreterPython::GetPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t +ScriptInterpreterPython::GetPluginVersion() +{ + return 1; +} + +void ScriptInterpreterPython::IOHandlerActivated (IOHandler &io_handler) { const char *instructions = nullptr; diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h new file mode 100644 index 00000000000..01814aac1f3 --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h @@ -0,0 +1,590 @@ +//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H + +#ifdef LLDB_DISABLE_PYTHON + +// Python is disabled in this build + +#else + +#include "lldb/lldb-private.h" +#include "PythonDataObjects.h" +#include "lldb/Core/IOHandler.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Host/Terminal.h" + +class IOHandlerPythonInterpreter; + +namespace lldb_private { + +class ScriptInterpreterPython : + public ScriptInterpreter, + public IOHandlerDelegateMultiline +{ +public: + typedef void (*SWIGInitCallback) (void); + + typedef bool (*SWIGBreakpointCallbackFunction) (const char *python_function_name, + const char *session_dictionary_name, + const lldb::StackFrameSP& frame_sp, + const lldb::BreakpointLocationSP &bp_loc_sp); + + typedef bool (*SWIGWatchpointCallbackFunction) (const char *python_function_name, + const char *session_dictionary_name, + const lldb::StackFrameSP& frame_sp, + const lldb::WatchpointSP &wp_sp); + + typedef bool (*SWIGPythonTypeScriptCallbackFunction) (const char *python_function_name, + void *session_dictionary, + const lldb::ValueObjectSP& valobj_sp, + void** pyfunct_wrapper, + const lldb::TypeSummaryOptionsSP& options, + std::string& retval); + + typedef void* (*SWIGPythonCreateSyntheticProvider) (const char *python_class_name, + const char *session_dictionary_name, + const lldb::ValueObjectSP& valobj_sp); + + typedef void* (*SWIGPythonCreateCommandObject) (const char *python_class_name, + const char *session_dictionary_name, + const lldb::DebuggerSP debugger_sp); + + typedef void* (*SWIGPythonCreateScriptedThreadPlan) (const char *python_class_name, + const char *session_dictionary_name, + const lldb::ThreadPlanSP& thread_plan_sp); + + typedef bool (*SWIGPythonCallThreadPlan) (void *implementor, const char *method_name, Event *event_sp, bool &got_error); + + typedef void* (*SWIGPythonCreateOSPlugin) (const char *python_class_name, + const char *session_dictionary_name, + const lldb::ProcessSP& process_sp); + + typedef size_t (*SWIGPythonCalculateNumChildren) (void *implementor); + typedef void* (*SWIGPythonGetChildAtIndex) (void *implementor, uint32_t idx); + typedef int (*SWIGPythonGetIndexOfChildWithName) (void *implementor, const char* child_name); + typedef void* (*SWIGPythonCastPyObjectToSBValue) (void* data); + typedef lldb::ValueObjectSP (*SWIGPythonGetValueObjectSPFromSBValue) (void* data); + typedef bool (*SWIGPythonUpdateSynthProviderInstance) (void* data); + typedef bool (*SWIGPythonMightHaveChildrenSynthProviderInstance) (void* data); + typedef void* (*SWIGPythonGetValueSynthProviderInstance) (void *implementor); + + typedef bool (*SWIGPythonCallCommand) (const char *python_function_name, + const char *session_dictionary_name, + lldb::DebuggerSP& debugger, + const char* args, + lldb_private::CommandReturnObject& cmd_retobj, + lldb::ExecutionContextRefSP exe_ctx_ref_sp); + + typedef bool (*SWIGPythonCallCommandObject) (void *implementor, + lldb::DebuggerSP& debugger, + const char* args, + lldb_private::CommandReturnObject& cmd_retobj, + lldb::ExecutionContextRefSP exe_ctx_ref_sp); + + + typedef bool (*SWIGPythonCallModuleInit) (const char *python_module_name, + const char *session_dictionary_name, + lldb::DebuggerSP& debugger); + + typedef bool (*SWIGPythonScriptKeyword_Process) (const char* python_function_name, + const char* session_dictionary_name, + lldb::ProcessSP& process, + std::string& output); + typedef bool (*SWIGPythonScriptKeyword_Thread) (const char* python_function_name, + const char* session_dictionary_name, + lldb::ThreadSP& thread, + std::string& output); + + typedef bool (*SWIGPythonScriptKeyword_Target) (const char* python_function_name, + const char* session_dictionary_name, + lldb::TargetSP& target, + std::string& output); + + typedef bool (*SWIGPythonScriptKeyword_Frame) (const char* python_function_name, + 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, + const lldb::TargetSP& target_sp); + + friend class ::IOHandlerPythonInterpreter; + + ScriptInterpreterPython (CommandInterpreter &interpreter); + + ~ScriptInterpreterPython (); + + bool + Interrupt() override; + + bool + ExecuteOneLine (const char *command, + CommandReturnObject *result, + const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; + + void + ExecuteInterpreterLoop () override; + + bool + ExecuteOneLineWithReturn (const char *in_string, + ScriptInterpreter::ScriptReturnType return_type, + void *ret_value, + const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; + + lldb_private::Error + ExecuteMultipleLines (const char *in_string, + const ExecuteScriptOptions &options = ExecuteScriptOptions()) override; + + Error + ExportFunctionDefinitionToInterpreter (StringList &function_def) override; + + bool + GenerateTypeScriptFunction (StringList &input, std::string& output, const void* name_token = NULL) override; + + bool + GenerateTypeSynthClass (StringList &input, std::string& output, const void* name_token = NULL) override; + + bool + GenerateTypeSynthClass (const char* oneliner, std::string& output, const void* name_token = NULL) override; + + // use this if the function code is just a one-liner script + bool + GenerateTypeScriptFunction (const char* oneliner, std::string& output, const void* name_token = NULL) override; + + bool + GenerateScriptAliasFunction (StringList &input, std::string& output) override; + + StructuredData::ObjectSP CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) override; + + StructuredData::GenericSP CreateScriptCommandObject (const char *class_name) override; + + StructuredData::ObjectSP CreateScriptedThreadPlan(const char *class_name, lldb::ThreadPlanSP thread_plan) override; + + bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override; + bool ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override; + lldb::StateType ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error) override; + + StructuredData::GenericSP OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp) override; + + StructuredData::DictionarySP OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) override; + + StructuredData::ArraySP OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) override; + + StructuredData::StringSP OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t thread_id) override; + + StructuredData::DictionarySP OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp, lldb::tid_t tid, + lldb::addr_t context) override; + + StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Error &error) override; + + StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, + lldb_private::Error &error) override; + + size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor) override; + + lldb::ValueObjectSP GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) override; + + int GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, const char *child_name) override; + + bool UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) override; + + bool MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor) override; + + lldb::ValueObjectSP GetSyntheticValue(const StructuredData::ObjectSP &implementor) override; + + bool + RunScriptBasedCommand(const char* impl_function, + const char* args, + ScriptedCommandSynchronicity synchronicity, + lldb_private::CommandReturnObject& cmd_retobj, + Error& error, + const lldb_private::ExecutionContext& exe_ctx) override; + + bool + RunScriptBasedCommand (StructuredData::GenericSP impl_obj_sp, + const char* args, + ScriptedCommandSynchronicity synchronicity, + lldb_private::CommandReturnObject& cmd_retobj, + Error& error, + const lldb_private::ExecutionContext& exe_ctx) override; + + Error + GenerateFunction(const char *signature, const StringList &input) override; + + Error + GenerateBreakpointCommandCallbackData (StringList &input, std::string& output) override; + + bool + GenerateWatchpointCommandCallbackData (StringList &input, std::string& output) override; + +// static size_t +// GenerateBreakpointOptionsCommandCallback (void *baton, +// InputReader &reader, +// lldb::InputReaderAction notification, +// const char *bytes, +// size_t bytes_len); +// +// static size_t +// GenerateWatchpointOptionsCommandCallback (void *baton, +// InputReader &reader, +// lldb::InputReaderAction notification, +// const char *bytes, +// size_t bytes_len); + + static bool + BreakpointCallbackFunction (void *baton, + StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + static bool + WatchpointCallbackFunction (void *baton, + StoppointCallbackContext *context, + lldb::user_id_t watch_id); + + bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, + const TypeSummaryOptions &options, std::string &retval) override; + + void + Clear () override; + + bool + GetDocumentationForItem (const char* item, std::string& dest) override; + + bool + GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string& dest) override; + + uint32_t + GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp) override; + + bool + GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string& dest) override; + + bool + CheckObjectExists (const char* name) override + { + if (!name || !name[0]) + return false; + std::string temp; + return GetDocumentationForItem (name,temp); + } + + bool + RunScriptFormatKeyword (const char* impl_function, + Process* process, + std::string& output, + Error& error) override; + + bool + RunScriptFormatKeyword (const char* impl_function, + Thread* thread, + std::string& output, + Error& error) override; + + bool + RunScriptFormatKeyword (const char* impl_function, + Target* target, + std::string& output, + Error& error) override; + + bool + RunScriptFormatKeyword (const char* impl_function, + StackFrame* frame, + std::string& output, + Error& error) override; + + bool + RunScriptFormatKeyword (const char* impl_function, + ValueObject* value, + std::string& output, + Error& error) override; + + bool LoadScriptingModule(const char *filename, bool can_reload, bool init_session, lldb_private::Error &error, + StructuredData::ObjectSP *module_sp = nullptr) override; + + bool + IsReservedWord (const char* word) override; + + std::unique_ptr<ScriptInterpreterLocker> + AcquireInterpreterLock () override; + + void + CollectDataForBreakpointCommandCallback (std::vector<BreakpointOptions *> &bp_options_vec, + CommandReturnObject &result) override; + + void + CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options, + CommandReturnObject &result) override; + + /// Set the callback body text into the callback for the breakpoint. + Error + SetBreakpointCommandCallback (BreakpointOptions *bp_options, + const char *callback_body) override; + + void + SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options, + const char *function_name) override; + + /// Set a one-liner as the callback for the watchpoint. + void + SetWatchpointCommandCallback (WatchpointOptions *wp_options, + const char *oneliner) override; + + StringList + ReadCommandInputFromUser (FILE *in_file); + + void ResetOutputFileHandle(FILE *new_fh) override; + + static void + InitializePrivate (); + + static void + InitializeInterpreter (SWIGInitCallback python_swig_init_callback, + SWIGBreakpointCallbackFunction swig_breakpoint_callback, + SWIGWatchpointCallbackFunction swig_watchpoint_callback, + SWIGPythonTypeScriptCallbackFunction swig_typescript_callback, + SWIGPythonCreateSyntheticProvider swig_synthetic_script, + SWIGPythonCreateCommandObject swig_create_cmd, + SWIGPythonCalculateNumChildren swig_calc_children, + SWIGPythonGetChildAtIndex swig_get_child_index, + SWIGPythonGetIndexOfChildWithName swig_get_index_child, + SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue , + SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue, + SWIGPythonUpdateSynthProviderInstance swig_update_provider, + SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider, + SWIGPythonGetValueSynthProviderInstance swig_getvalue_provider, + SWIGPythonCallCommand swig_call_command, + SWIGPythonCallCommandObject swig_call_command_object, + SWIGPythonCallModuleInit swig_call_module_init, + SWIGPythonCreateOSPlugin swig_create_os_plugin, + SWIGPythonScriptKeyword_Process swig_run_script_keyword_process, + 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); + + const char * + GetDictionaryName () + { + return m_dictionary_name.c_str(); + } + + + PyThreadState * + GetThreadState() + { + return m_command_thread_state; + } + + void + SetThreadState (PyThreadState *s) + { + if (s) + m_command_thread_state = s; + } + + //---------------------------------------------------------------------- + // IOHandlerDelegate + //---------------------------------------------------------------------- + void + IOHandlerActivated (IOHandler &io_handler) override; + + void + IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override; + + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static lldb::ScriptInterpreterSP + CreateInstance(CommandInterpreter &interpreter); + + static lldb_private::ConstString + GetPluginNameStatic(); + + static const char * + GetPluginDescriptionStatic(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + virtual lldb_private::ConstString + GetPluginName(); + + virtual uint32_t + GetPluginVersion(); + +protected: + + bool + EnterSession (uint16_t on_entry_flags, + FILE *in, + FILE *out, + FILE *err); + + void + LeaveSession (); + + void + SaveTerminalState (int fd); + + void + RestoreTerminalState (); + + class SynchronicityHandler + { + private: + lldb::DebuggerSP m_debugger_sp; + ScriptedCommandSynchronicity m_synch_wanted; + bool m_old_asynch; + public: + SynchronicityHandler(lldb::DebuggerSP, + ScriptedCommandSynchronicity); + ~SynchronicityHandler(); + }; + +public: + class Locker : public ScriptInterpreterLocker + { + public: + + enum OnEntry + { + AcquireLock = 0x0001, + InitSession = 0x0002, + InitGlobals = 0x0004, + NoSTDIN = 0x0008 + }; + + enum OnLeave + { + FreeLock = 0x0001, + FreeAcquiredLock = 0x0002, // do not free the lock if we already held it when calling constructor + TearDownSession = 0x0004 + }; + + Locker (ScriptInterpreterPython *py_interpreter = NULL, + uint16_t on_entry = AcquireLock | InitSession, + uint16_t on_leave = FreeLock | TearDownSession, + FILE *in = NULL, + FILE *out = NULL, + FILE *err = NULL); + + ~Locker (); + + private: + + bool + DoAcquireLock (); + + bool + DoInitSession (uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err); + + bool + DoFreeLock (); + + bool + DoTearDownSession (); + + static void + ReleasePythonLock (); + + bool m_teardown_session; + ScriptInterpreterPython *m_python_interpreter; +// FILE* m_tmp_fh; + PyGILState_STATE m_GILState; + }; +protected: + enum class AddLocation + { + Beginning, + End + }; + + static void AddToSysPath(AddLocation location, std::string path); + + uint32_t + IsExecutingPython () const + { + return m_lock_count > 0; + } + + uint32_t + IncrementLockCount() + { + return ++m_lock_count; + } + + uint32_t + DecrementLockCount() + { + if (m_lock_count > 0) + --m_lock_count; + return m_lock_count; + } + + enum ActiveIOHandler { + eIOHandlerNone, + eIOHandlerBreakpoint, + eIOHandlerWatchpoint + }; + PythonObject & + GetMainModule (); + + PythonDictionary & + GetSessionDictionary (); + + PythonDictionary & + GetSysModuleDictionary (); + + bool + GetEmbeddedInterpreterModuleObjects (); + + PythonObject m_saved_stdin; + PythonObject m_saved_stdout; + PythonObject m_saved_stderr; + PythonObject m_main_module; + PythonObject m_lldb_module; + PythonDictionary m_session_dict; + PythonDictionary m_sys_module_dict; + PythonObject m_run_one_line_function; + PythonObject m_run_one_line_str_global; + std::string m_dictionary_name; + TerminalState m_terminal_state; + ActiveIOHandler m_active_io_handler; + bool m_session_is_active; + bool m_pty_slave_is_open; + bool m_valid_session; + uint32_t m_lock_count; + PyThreadState *m_command_thread_state; +}; +} // namespace lldb_private + +#endif // #ifdef LLDB_DISABLE_PYTHON + +#endif // #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h b/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h new file mode 100644 index 00000000000..013492c39bf --- /dev/null +++ b/lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h @@ -0,0 +1,31 @@ +//===-- lldb-python.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H + +// Python.h needs to be included before any system headers in order to avoid redefinition of macros + +#ifdef LLDB_DISABLE_PYTHON +// Python is disabled in this build +#else +#if defined(__linux__) +// features.h will define _POSIX_C_SOURCE if _GNU_SOURCE is defined. This value +// may be different from the value that Python defines it to be which results +// in a warning. Undefine _POSIX_C_SOURCE before including Python.h The same +// holds for _XOPEN_SOURCE. +#undef _POSIX_C_SOURCE +#undef _XOPEN_SOURCE +#endif + +// Include python for non windows machines +#include <Python.h> +#endif // LLDB_DISABLE_PYTHON + +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H |