Index: lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h =================================================================== --- lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h +++ 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" @@ -35,11 +36,15 @@ luaL_openlibs(m_lua_state); } + llvm::Error EnterSession(lldb::user_id_t debugger_id); + llvm::Error LeaveSession(); + llvm::Error Run(llvm::StringRef buffer); private: std::mutex m_mutex; lua_State *m_lua_state; + bool m_session_is_active = false; }; } // namespace lldb_private Index: lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp =================================================================== --- lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp +++ lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp @@ -10,6 +10,7 @@ #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); @@ -26,3 +27,27 @@ lua_pop(m_lua_state, 1); return e; } + +llvm::Error Lua::EnterSession(user_id_t debugger_id) { + if (m_session_is_active) + return llvm::Error::success(); + + m_session_is_active = true; + std::string buffer = llvm::formatv( + "lldb.debugger = lldb.SBDebugger.FindDebuggerWithID({0})", debugger_id); + buffer.append("; lldb.target = lldb.debugger:GetSelectedTarget()"); + buffer.append("; lldb.process = lldb.target:GetProcess()"); + buffer.append("; lldb.thread = lldb.process:GetSelectedThread()"); + buffer.append("; lldb.frame = lldb.thread:GetSelectedFrame ()"); + return Run(buffer); +} + +llvm::Error Lua::LeaveSession() { + m_session_is_active = false; + std::string buffer = "lldb.debugger = nil"; + buffer.append("; lldb.target = nil"); + buffer.append("; lldb.process = nil"); + buffer.append("; lldb.thread = nil"); + buffer.append("; lldb.frame = nil"); + return Run(buffer); +} Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp =================================================================== --- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -27,7 +27,14 @@ : 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.GetLua().EnterSession(debugger.GetID())); + } + + ~IOHandlerLuaInterpreter() { + llvm::cantFail(m_script_interpreter.GetLua().LeaveSession()); + } void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { Index: lldb/test/Shell/ScriptInterpreter/Lua/convenience_variables.test =================================================================== --- /dev/null +++ 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