1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
-- Make lldb available in global
lldb = require('lldb')
-- Global assertion functions
function assertTrue(x)
if not x then error('assertTrue failure') end
end
function assertFalse(x)
if x then error('assertNotNil failure') end
end
function assertNotNil(x)
if x == nil then error('assertNotNil failure') end
end
function assertEqual(x, y)
if type(x) == 'table' and type(y) == 'table' then
for k, _ in pairs(x) do
assertEqual(x[k], y[k])
end
elseif type(x) ~= type(y) then
error('assertEqual failure')
elseif x ~= y then
error('assertEqual failure')
end
end
function assertStrContains(x, y)
if not string.find(x, y, 1, true) then
error('assertStrContains failure')
end
end
-- Global helper functions
function read_file_non_empty_lines(f)
local lines = {}
while true do
local line = f:read('*l')
if not line then break end
if line ~= '\n' then table.insert(lines, line) end
end
return lines
end
function split_lines(str)
local lines = {}
for line in str:gmatch("[^\r\n]+") do
table.insert(lines, line)
end
return lines
end
function get_stopped_threads(process, reason)
local threads = {}
for i = 0, process:GetNumThreads() - 1 do
local t = process:GetThreadAtIndex(i)
if t:IsValid() and t:GetStopReason() == reason then
table.insert(threads, t)
end
end
return threads
end
function get_stopped_thread(process, reason)
local threads = get_stopped_threads(process, reason)
if #threads ~= 0 then return threads[1]
else return nil end
end
-- Test helper
local _M = {}
local _m = {}
local _mt = { __index = _m }
function _M.create_test(name, exe, output, input)
print('[lldb/lua] Create test ' .. name)
exe = exe or os.getenv('TEST_EXE')
output = output or os.getenv('TEST_OUTPUT')
input = input or os.getenv('TEST_INPUT')
lldb.SBDebugger.Initialize()
local debugger = lldb.SBDebugger.Create()
-- Ensure that debugger is created
assertNotNil(debugger)
assertTrue(debugger:IsValid())
debugger:SetAsync(false)
local lua_language = debugger:GetScriptingLanguage('lua')
assertNotNil(lua_language)
debugger:SetScriptLanguage(lua_language)
local test = setmetatable({
output = output,
input = input,
name = name,
exe = exe,
debugger = debugger
}, _mt)
_G[name] = test
return test
end
function _m:create_target(exe)
local target
if not exe then exe = self.exe end
target = self.debugger:CreateTarget(exe)
-- Ensure that target is created
assertNotNil(target)
assertTrue(target:IsValid())
return target
end
function _m:handle_command(command, collect)
if collect == nil then collect = true end
if collect then
local ret = lldb.SBCommandReturnObject()
local interpreter = self.debugger:GetCommandInterpreter()
assertTrue(interpreter:IsValid())
interpreter:HandleCommand(command, ret)
self.debugger:GetOutputFile():Flush()
self.debugger:GetErrorFile():Flush()
assertTrue(ret:Succeeded())
return ret:GetOutput()
else
self.debugger:HandleCommand(command)
self.debugger:GetOutputFile():Flush()
self.debugger:GetErrorFile():Flush()
end
end
function _m:run()
local tests = {}
for k, v in pairs(self) do
if string.sub(k, 1, 4) == 'Test' then
table.insert(tests, k)
end
end
table.sort(tests)
for _, t in ipairs(tests) do
print('[lldb/lua] Doing test ' .. self.name .. ' - ' .. t)
local success = xpcall(self[t], function(e)
print(debug.traceback())
end, self)
if not success then
print('[lldb/lua] Failure in test ' .. self.name .. ' - ' .. t)
return 1
end
end
return 0
end
return _M
|