def test_single_step(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) bp_addr = module_load_addr + test_basic.BREAK_ADDRESS_0 reply = connection.RspRequest('Z0,%x,1' % bp_addr) self.assertEqual("OK", reply) reply = connection.RspRequest('c') gdb_rsp.AssertReplySignal(reply, gdb_rsp.SIGTRAP) # We expect 's' to stop at the next instruction. reply = connection.RspRequest('s') gdb_rsp.AssertReplySignal(reply, gdb_rsp.SIGTRAP) tid = gdb_rsp.ParseThreadStopReply(reply)['thread_id'] self.assertEqual(tid, 1) regs = gdb_rsp.DecodeRegs(connection.RspRequest('g')) self.assertEqual(regs['pc'], module_load_addr + test_basic.BREAK_ADDRESS_1) # Again. reply = connection.RspRequest('s') gdb_rsp.AssertReplySignal(reply, gdb_rsp.SIGTRAP) tid = gdb_rsp.ParseThreadStopReply(reply)['thread_id'] self.assertEqual(tid, 1) regs = gdb_rsp.DecodeRegs(connection.RspRequest('g')) self.assertEqual(regs['pc'], module_load_addr + test_basic.BREAK_ADDRESS_2) # Check that we can continue after single-stepping. reply = connection.RspRequest('c') gdb_rsp.AssertReplySignal(reply, gdb_rsp.SIGTRAP)
def test_reading_and_writing_memory(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) breakpoint_addr = module_load_addr + test_memory.FUNC0_START_ADDR self.RunToWasm(connection, breakpoint_addr) self.CheckReadMemoryAtInvalidAddr(connection) # Check reading code memory space. expected_data = b'\0asm' result = gdb_rsp.ReadCodeMemory(connection, module_load_addr, len(expected_data)) self.assertEqual(result, expected_data) # Check reading instance memory at a valid range. module_id = module_load_addr >> 32 reply = connection.RspRequest('qWasmMem:%d;%x;%x' % (module_id, 32, 4)) value = struct.unpack('I', gdb_rsp.DecodeHex(reply))[0] self.assertEquals(int(value), 0) # Check reading instance memory at an invalid range. reply = connection.RspRequest('qWasmMem:%d;%x;%x' % (module_id, 0xf0000000, 4)) self.assertEqual(reply, 'E03')
def test_trap(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) reply = connection.RspRequest('c') gdb_rsp.AssertReplySignal(reply, gdb_rsp.SIGSEGV) tid = gdb_rsp.ParseThreadStopReply(reply)['thread_id'] self.assertEqual(tid, 1) regs = gdb_rsp.DecodeRegs(connection.RspRequest('g')) self.assertEqual(regs['pc'], module_load_addr + test_trap.TRAP_ADDRESS)
def test_modifying_code_is_disallowed(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: # Pick an arbitrary address in the code segment. module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) breakpoint_addr = module_load_addr + test_basic.BREAK_ADDRESS_1 # Writing to the code area should be disallowed. data = '\x00' write_command = 'M%x,%x:%s' % (breakpoint_addr, len(data), gdb_rsp.EncodeHex(data)) reply = connection.RspRequest(write_command) self.assertEquals(reply, 'E03')
def test_wasm_call_stack(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) breakpoint_addr = module_load_addr + test_memory.FUNC0_START_ADDR self.RunToWasm(connection, breakpoint_addr) reply = connection.RspRequest('qWasmCallStack') stack = gdb_rsp.DecodeUInt64Array(reply) assert (len(stack) > 2 ) # At least two Wasm frames, plus one or more JS frames. self.assertEqual(stack[0], module_load_addr + test_memory.FUNC0_START_ADDR) self.assertEqual(stack[1], module_load_addr + test_memory.FUNC1_RETURN_ADDR)
def test_wasm_global(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) breakpoint_addr = module_load_addr + test_memory.FUNC0_START_ADDR self.RunToWasm(connection, breakpoint_addr) # Check reading valid global. reply = connection.RspRequest('qWasmGlobal:0;0') value = struct.unpack('I', gdb_rsp.DecodeHex(reply))[0] self.assertEqual(0, value) # Check reading invalid global. reply = connection.RspRequest('qWasmGlobal:0;9') self.assertEqual("E03", reply)
def test_wasm_local_float(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: self.RunToWasm(connection) module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) reply = connection.RspRequest('qWasmLocal:0;0') value = struct.unpack('f', gdb_rsp.DecodeHex(reply))[0] self.assertEqual(test_float.ARG_0, value) reply = connection.RspRequest('qWasmLocal:0;1') value = struct.unpack('f', gdb_rsp.DecodeHex(reply))[0] self.assertEqual(test_float.ARG_1, value) # invalid local reply = connection.RspRequest('qWasmLocal:0;9') self.assertEqual("E03", reply)
def test_checking_thread_state(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: # Query wasm thread id reply = connection.RspRequest('qfThreadInfo') match = re.match('m([0-9])$', reply) if match is None: raise AssertionError('Bad active thread list reply: %r' % reply) thread_id = int(match.group(1), 10) # There should not be other threads. reply = connection.RspRequest('qsThreadInfo') self.assertEqual("l", reply) # Test that valid thread should be alive. reply = connection.RspRequest('T%d' % (thread_id)) self.assertEqual("OK", reply) # Test invalid thread id. reply = connection.RspRequest('T42') self.assertEqual("E02", reply)
def test_reading_and_writing_data_section(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) breakpoint_addr = module_load_addr + test_memory.FUNC0_START_ADDR self.RunToWasm(connection, breakpoint_addr) # Check reading instance memory at a valid range. module_id = module_load_addr >> 32 reply = connection.RspRequest( 'qWasmData:%d;%x;%x' % (module_id, test_memory.DATA_OFFSET, test_memory.DATA_SIZE)) value = struct.unpack('I', gdb_rsp.DecodeHex(reply))[0] self.assertEquals(int(value), test_memory.DATA_CONTENT) # Check reading instance memory at an invalid range. reply = connection.RspRequest('qWasmData:%d;%x;%x' % (module_id, 0xf0000000, 4)) self.assertEqual(reply, 'E03')
def test_wasm_stack_value(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) breakpoint_addr = module_load_addr + test_basic.BREAK_ADDRESS_2 reply = connection.RspRequest('Z0,%x,1' % breakpoint_addr) self.assertEqual("OK", reply) reply = connection.RspRequest('c') gdb_rsp.AssertReplySignal(reply, gdb_rsp.SIGTRAP) reply = connection.RspRequest('qWasmStackValue:0;0') value = struct.unpack('I', gdb_rsp.DecodeHex(reply))[0] self.assertEqual(test_basic.ARG_0, value) reply = connection.RspRequest('qWasmStackValue:0;1') value = struct.unpack('I', gdb_rsp.DecodeHex(reply))[0] self.assertEqual(test_basic.ARG_1, value) # invalid index reply = connection.RspRequest('qWasmStackValue:0;2') self.assertEqual("E03", reply)
def test_setting_removing_breakpoint(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: module_load_addr = gdb_rsp.GetLoadedModuleAddress(connection) func_addr = module_load_addr + test_basic.BREAK_ADDRESS_1 # Set a breakpoint. reply = connection.RspRequest('Z0,%x,1' % func_addr) self.assertEqual(reply, 'OK') # When we run the program, we should hit the breakpoint. reply = connection.RspRequest('c') gdb_rsp.AssertReplySignal(reply, gdb_rsp.SIGTRAP) gdb_rsp.CheckInstructionPtr(connection, func_addr) # Check that we can remove the breakpoint. reply = connection.RspRequest('z0,%x,0' % func_addr) self.assertEqual(reply, 'OK') # Requesting removing a breakpoint on an address that does not # have one should return an error. reply = connection.RspRequest('z0,%x,0' % func_addr) self.assertEqual(reply, 'E03')
def test_loaded_modules(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: modules = gdb_rsp.GetLoadedModules(connection) connection.Close() assert (len(modules) > 0)
def test_setting_breakpoint_on_invalid_address(self): with gdb_rsp.LaunchDebugStub(COMMAND) as connection: # Requesting a breakpoint on an invalid address should give an error. reply = connection.RspRequest('Z0,%x,1' % (1 << 32)) self.assertEqual(reply, 'E03')
def test_initial_breakpoint(self): # Testing that the debuggee suspends when the debugger attaches. with gdb_rsp.LaunchDebugStub(COMMAND) as connection: reply = connection.RspRequest('?') gdb_rsp.AssertReplySignal(reply, gdb_rsp.SIGTRAP)