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