mirror of
https://github.com/intel/llvm.git
synced 2026-02-06 06:31:50 +08:00
[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
This commit is contained in:
@@ -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<std::mutex> lock(m_mutex);
|
||||
int error =
|
||||
luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer") ||
|
||||
lua_pcall(m_lua_state, 0, 0, 0);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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<ScriptInterpreterLua>(debugger);
|
||||
|
||||
@@ -43,8 +43,12 @@ public:
|
||||
|
||||
Lua &GetLua();
|
||||
|
||||
llvm::Error EnterSession(lldb::user_id_t debugger_id);
|
||||
llvm::Error LeaveSession();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Lua> m_lua;
|
||||
bool m_session_is_active = false;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
@@ -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)")
|
||||
@@ -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())
|
||||
@@ -0,0 +1,2 @@
|
||||
script
|
||||
print(lldb.target, lldb.debugger:GetSelectedTarget())
|
||||
@@ -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
|
||||
@@ -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
|
||||
12
lldb/test/Shell/ScriptInterpreter/Lua/nested_sessions.test
Normal file
12
lldb/test/Shell/ScriptInterpreter/Lua/nested_sessions.test
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user