Skip to content

Commit

Permalink
lldb: add lua builtin scripts for Unreal Engine debugging
Browse files Browse the repository at this point in the history
Signed-off-by: hexian000 <hexian000@outlook.com>
  • Loading branch information
hexian000 committed Jun 7, 2024
1 parent 768118d commit be7ab9d
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lldb/include/lldb/lldb-enumerations.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ enum ScriptLanguage {
eScriptLanguagePython,
eScriptLanguageLua,
eScriptLanguageUnknown,
eScriptLanguageDefault = eScriptLanguagePython
eScriptLanguageDefault = eScriptLanguageLua
};

/// Register numbering types.
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/API/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ if(LLDB_ENABLE_LUA)
set(lldb_lua_wrapper ${lua_bindings_dir}/LLDBWrapLua.cpp)
endif()

add_lldb_library(liblldb SHARED ${option_framework}
add_lldb_library(liblldb STATIC ${option_framework}
SBAddress.cpp
SBAttachInfo.cpp
SBBlock.cpp
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_lldb_library(lldbPluginScriptInterpreterLua PLUGIN
Lua.cpp
LuaBuiltin.cpp
ScriptInterpreterLua.cpp

LINK_LIBS
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Lua::Lua() : m_lua_state(luaL_newstate()) {
luaopen_lldb(m_lua_state);
lua_pushcfunction(m_lua_state, lldb_print);
lua_setglobal(m_lua_state, "print");

luaL_dostring(m_lua_state, m_builtin);
}

Lua::~Lua() {
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Lua {

private:
lua_State *m_lua_state;
static const char m_builtin[];
};

} // namespace lldb_private
Expand Down
103 changes: 103 additions & 0 deletions lldb/source/Plugins/ScriptInterpreter/Lua/LuaBuiltin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include "Lua.h"

namespace lldb_private {

const char Lua::m_builtin[] = u8R"Lua(
local function prepare()
lldb.debugger = lldb.SBDebugger.FindDebuggerWithID(1)
lldb.target = lldb.debugger:GetSelectedTarget()
lldb.process = lldb.target:GetProcess()
lldb.thread = lldb.process:GetSelectedThread()
lldb.frame = lldb.thread:GetSelectedFrame()
end
local function printf(s, ...)
print(string.format(s, ...))
end
local function cmdf(s, ...)
local cmd = string.format(s, ...)
local ret = lldb.SBCommandReturnObject()
local interpreter = lldb.debugger:GetCommandInterpreter()
interpreter:HandleCommand(cmd, ret)
if not ret:Succeeded() then
lldb.debugger:GetErrorFile():Flush()
local err = string.gsub(ret:GetError(), "\n$", "")
error(err)
end
lldb.debugger:GetOutputFile():Flush()
local out = string.gsub(ret:GetOutput(), "\n$", "")
return out
end
local function evalf(ctx, s, ...)
local expr = string.format(s, ...)
local value = ctx:EvaluateExpression(expr)
if not value:IsValid() then
error("failed evaluating: " .. expr)
end
return value:GetValue()
end
local function read_string(ctx, expr, len)
local value = ctx:EvaluateExpression(expr)
local err = lldb.SBError()
local process = value:GetProcess()
local buf = process:ReadCStringFromMemory(tonumber(value:GetValue()), len + 1, err)
if not err:Success() then
error(err:GetCString())
end
-- printf("read_string: [%d] %q", len, buf)
return buf
end
unreal = {}
function unreal.pname(index)
pcall(prepare)
local ctx = lldb.target
local shift = tonumber(evalf(ctx, "FNameDebugVisualizer::OffsetBits"))
local mask = tonumber(evalf(ctx, "FNameDebugVisualizer::OffsetMask"))
local stride = tonumber(evalf(ctx, "FNameDebugVisualizer::EntryStride"))
local i = index >> shift
local j = (index & mask) * stride
local entry = evalf(ctx, "&GNameBlocksDebug[%d][%d]", i, j)
-- printf("entry = %q", entry)
local len = tonumber(evalf(ctx, "((FNameEntry*)%s)->Header.Len", entry))
-- printf("len = %d", len)
local name = read_string(ctx, string.format("&((FNameEntry*)%s)->AnsiName", entry), len)
printf("FName(%d) = %q", index, name)
end
function unreal.pweak(index)
pcall(prepare)
local chunk = 65536
local i = index // chunk
local j = index % chunk
print(cmdf("print GUObjectArray.ObjObjects.Objects[%d][%d]", i, j))
end
function unreal.ptype(ptr)
pcall(prepare)
local vtable = tonumber(evalf(lldb.target, string.format("*(void**)0x%x", ptr)))
printf("vtable: 0x%x", vtable)
print(cmdf("target modules lookup -a 0x%x", vtable))
end
function unreal.vtable(vtable)
pcall(prepare)
local size = tonumber(evalf(lldb.target, "sizeof(void*)"))
for i = 0, 999 do
local vfunc = vtable + (i * size)
local line = cmdf("memory read -c 1 -f A 0x%x", vfunc)
local ptr = select(3, string.find(line, "^%s*%w+:%s+(%w+)"))
if tonumber(ptr) == 0 then
break
end
print(line)
end
end
)Lua";

} // namespace lldb_private
2 changes: 2 additions & 0 deletions lldb/tools/driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ add_lldb_tool(lldb

LINK_LIBS
liblldb
lldbPluginScriptInterpreterLua # hack for GNU ld
liblldb

LINK_COMPONENTS
Option
Expand Down
2 changes: 2 additions & 0 deletions lldb/tools/driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) {
if (auto *arg = args.getLastArg(OPT_script_language)) {
auto *arg_value = arg->getValue();
m_debugger.SetScriptLanguage(m_debugger.GetScriptingLanguage(arg_value));
} else {
m_debugger.SetScriptLanguage(lldb::ScriptLanguage::eScriptLanguageDefault);
}

if (args.hasArg(OPT_source_quietly)) {
Expand Down

0 comments on commit be7ab9d

Please sign in to comment.