From 45c971f7eef18ef2b77a5f64133dbd7bd5939d5f Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 9 Jan 2020 08:15:01 -0800 Subject: [PATCH] [lldb/Lua] Make lldb.debugger et al available to Lua The Python script interpreter makes the current debugger, target, process, thread and frame available to interactive scripting sessions through convenience variables. This patch does the same for Lua. Differential revision: https://reviews.llvm.org/D71801 --- lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp | 2 +- lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h | 2 +- .../ScriptInterpreter/Lua/ScriptInterpreterLua.cpp | 35 +++++++++++++++++++++- .../ScriptInterpreter/Lua/ScriptInterpreterLua.h | 4 +++ .../Lua/Inputs/independent_state.in | 6 ++++ .../Lua/Inputs/nested_sessions.in | 6 ++++ .../Lua/Inputs/nested_sessions_2.in | 2 ++ .../Lua/convenience_variables.test | 17 +++++++++++ .../ScriptInterpreter/Lua/independent_state.test | 6 ++++ .../ScriptInterpreter/Lua/nested_sessions.test | 12 ++++++++ 10 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 lldb/test/Shell/ScriptInterpreter/Lua/Inputs/independent_state.in create mode 100644 lldb/test/Shell/ScriptInterpreter/Lua/Inputs/nested_sessions.in create mode 100644 lldb/test/Shell/ScriptInterpreter/Lua/Inputs/nested_sessions_2.in create mode 100644 lldb/test/Shell/ScriptInterpreter/Lua/convenience_variables.test create mode 100644 lldb/test/Shell/ScriptInterpreter/Lua/independent_state.test create mode 100644 lldb/test/Shell/ScriptInterpreter/Lua/nested_sessions.test diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp index dc64139..1dd0a9e 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp @@ -10,9 +10,9 @@ #include "llvm/Support/FormatVariadic.h" using namespace lldb_private; +using namespace lldb; llvm::Error Lua::Run(llvm::StringRef buffer) { - std::lock_guard lock(m_mutex); int error = luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer") || lua_pcall(m_lua_state, 0, 0, 0); diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h index ed1d159..adc6c61 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h @@ -9,6 +9,7 @@ #ifndef liblldb_Lua_h_ #define liblldb_Lua_h_ +#include "lldb/lldb-types.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -38,7 +39,6 @@ public: llvm::Error Run(llvm::StringRef buffer); private: - std::mutex m_mutex; lua_State *m_lua_state; }; diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp index d5423b7..e46851c 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -27,7 +27,13 @@ public: : IOHandlerEditline(debugger, IOHandler::Type::LuaInterpreter, "lua", ">>> ", "..> ", true, debugger.GetUseColor(), 0, *this, nullptr), - m_script_interpreter(script_interpreter) {} + m_script_interpreter(script_interpreter) { + llvm::cantFail(m_script_interpreter.EnterSession(debugger.GetID())); + } + + ~IOHandlerLuaInterpreter() { + llvm::cantFail(m_script_interpreter.LeaveSession()); + } void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { @@ -89,6 +95,33 @@ void ScriptInterpreterLua::Initialize() { void ScriptInterpreterLua::Terminate() {} +llvm::Error ScriptInterpreterLua::EnterSession(user_id_t debugger_id) { + if (m_session_is_active) + return llvm::Error::success(); + + const char *fmt_str = + "lldb.debugger = lldb.SBDebugger.FindDebuggerWithID({0}); " + "lldb.target = lldb.debugger:GetSelectedTarget(); " + "lldb.process = lldb.target:GetProcess(); " + "lldb.thread = lldb.process:GetSelectedThread(); " + "lldb.frame = lldb.thread:GetSelectedFrame()"; + return m_lua->Run(llvm::formatv(fmt_str, debugger_id).str()); +} + +llvm::Error ScriptInterpreterLua::LeaveSession() { + if (!m_session_is_active) + return llvm::Error::success(); + + m_session_is_active = false; + + llvm::StringRef str = "lldb.debugger = nil; " + "lldb.target = nil; " + "lldb.process = nil; " + "lldb.thread = nil; " + "lldb.frame = nil"; + return m_lua->Run(str); +} + lldb::ScriptInterpreterSP ScriptInterpreterLua::CreateInstance(Debugger &debugger) { return std::make_shared(debugger); diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h index b34c7d0..550e103 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h @@ -43,8 +43,12 @@ public: Lua &GetLua(); + llvm::Error EnterSession(lldb::user_id_t debugger_id); + llvm::Error LeaveSession(); + private: std::unique_ptr m_lua; + bool m_session_is_active = false; }; } // namespace lldb_private diff --git a/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/independent_state.in b/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/independent_state.in new file mode 100644 index 0000000..6e15a8f --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/independent_state.in @@ -0,0 +1,6 @@ +script foobar = 40 + 7 +script print(foobar) +script d = lldb.SBDebugger.Create() +script d:HandleCommand("script foobar = 40 + 2") +script print(foobar) +script d:HandleCommand("script print(foobar)") diff --git a/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/nested_sessions.in b/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/nested_sessions.in new file mode 100644 index 0000000..75c57e3 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/nested_sessions.in @@ -0,0 +1,6 @@ +script +print(lldb.target, lldb.debugger:GetSelectedTarget()) +lldb.debugger:SetSelectedTarget(lldb.debugger:GetTargetAtIndex(0)) +print(lldb.target, lldb.debugger:GetSelectedTarget()) +lldb.debugger:HandleCommand("script print(lldb.target, lldb.debugger:GetSelectedTarget())") +print(lldb.target, lldb.debugger:GetSelectedTarget()) diff --git a/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/nested_sessions_2.in b/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/nested_sessions_2.in new file mode 100644 index 0000000..a8cc2a5 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Lua/Inputs/nested_sessions_2.in @@ -0,0 +1,2 @@ +script +print(lldb.target, lldb.debugger:GetSelectedTarget()) diff --git a/lldb/test/Shell/ScriptInterpreter/Lua/convenience_variables.test b/lldb/test/Shell/ScriptInterpreter/Lua/convenience_variables.test new file mode 100644 index 0000000..022f2e3 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Lua/convenience_variables.test @@ -0,0 +1,17 @@ +# REQUIRES: lua +# +# This tests that the convenience variables are not nil. Given that there is no +# target we only expect the debugger to be valid. +# +# RUN: cat %s | %lldb --script-language lua 2>&1 | FileCheck %s +script +print(string.format("lldb.debugger is valid: %s", lldb.debugger:IsValid())) +print(string.format("lldb.target is valid: %s", lldb.target:IsValid())) +print(string.format("lldb.process is valid: %s", lldb.process:IsValid())) +print(string.format("lldb.thread is valid: %s", lldb.thread:IsValid())) +print(string.format("lldb.frame is valid: %s", lldb.frame:IsValid())) +# CHECK: debugger is valid: true +# CHECK: target is valid: false +# CHECK: process is valid: false +# CHECK: thread is valid: false +# CHECK: frame is valid: false diff --git a/lldb/test/Shell/ScriptInterpreter/Lua/independent_state.test b/lldb/test/Shell/ScriptInterpreter/Lua/independent_state.test new file mode 100644 index 0000000..2ade1b9 --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Lua/independent_state.test @@ -0,0 +1,6 @@ +# REQUIRES: lua +# +# RUN: %lldb --script-language lua -s %S/Inputs/independent_state.in 2>&1 | FileCheck %s +# CHECK: 47 +# CHECK: 47 +# CHECK: 42 diff --git a/lldb/test/Shell/ScriptInterpreter/Lua/nested_sessions.test b/lldb/test/Shell/ScriptInterpreter/Lua/nested_sessions.test new file mode 100644 index 0000000..a81418b --- /dev/null +++ b/lldb/test/Shell/ScriptInterpreter/Lua/nested_sessions.test @@ -0,0 +1,12 @@ +# REQUIRES: lua +# RUN: mkdir -p %t +# RUN: echo "int main() { return 0; }" | %clang_host -x c - -o %t/foo +# RUN: echo "int main() { return 0; }" | %clang_host -x c - -o %t/bar +# RUN: %lldb --script-language lua -o "file %t/bar" -o "file %t/foo" -s %S/Inputs/nested_sessions.in -s %S/Inputs/nested_sessions_2.in 2>&1 | FileCheck %s +# CHECK: script +# CHECK-NEXT: foo foo +# CHECK-NEXT: foo bar +# CHECK-NEXT: foo bar +# CHECK-NEXT: foo bar +# CHECK: script +# CHECK-NEXT: bar bar -- 2.7.4