def test_remote_exec(self): """ Tests execution on a remote target """ self.log.info("Testing execution on a remote target") hit_breakpoint = False s = gdb.GDBServer() g = gdb.GDB() cmd = '-file-exec-and-symbols %s' % self.return99_binary_path r = g.cmd(cmd) self.assertEqual(r.result.class_, 'done') cmd = 'set remote exec-file %s' % self.return99_binary_path r = g.cmd(cmd) self.assertEqual(r.result.class_, 'done') cmd = "-break-insert %s" % 'main' r = g.cmd(cmd) self.assertEqual(r.result.class_, 'done') r = g.cmd('-exec-run') other_messages = g.read_until_break() for msg in other_messages: parsed_msg = gdb.parse_mi(msg) if (hasattr(parsed_msg, 'class_') and parsed_msg.class_ == 'stopped' and parsed_msg.result.reason == 'breakpoint-hit'): hit_breakpoint = True self.assertTrue(hit_breakpoint) g.exit() s.exit()
def test_disconnect_raw(self): """ Connect/disconnect repeatedly from a remote debugger using raw commands """ self.log.info("Testing connecting and disconnecting repeatedly using " "raw commands") s = gdb.GDBServer() g = gdb.GDB() # Do 100 cycle of target (kind of connects) and disconnects for _ in range(0, 100): cmd = '-target-select extended-remote :%s' % s.port r = g.cmd(cmd) self.assertEqual(r.result.class_, 'connected') r = g.cmd('-target-disconnect') self.assertEqual(r.result.class_, 'done') # manual server shutdown cmd = '-target-select extended-remote :%s' % s.port r = g.cmd(cmd) self.assertEqual(r.result.class_, 'connected') r = g.cli_cmd('monitor exit') self.assertEqual(r.result.class_, 'done') g.exit() s.exit()
def test_generate_core(self): """ Load a file that will cause a segfault and produce a core dump """ self.log.info("Testing that a core dump will be generated") g = gdb.GDB() file_cmd = "-file-exec-and-symbols %s" % self.segfault_binary_path r = g.cmd(file_cmd) self.assertEqual(r.result.class_, 'done') run_cmd = "-exec-run" r = g.cmd(run_cmd) self.assertEqual(r.result.class_, 'running') other_messages = g.read_until_break() core_path = None for msg in other_messages: parsed_msg = gdb.parse_mi(msg) if (hasattr(parsed_msg, 'class_') and (parsed_msg.class_ == 'stopped') and (parsed_msg.result.signal_name == 'SIGSEGV')): core_path = "%s.core" % self.segfault_binary_path gcore_cmd = 'gcore %s' % core_path gcore_cmd = gdb.encode_mi_cli(gcore_cmd) r = g.cmd(gcore_cmd) self.assertEqual(r.result.class_, 'done') self.assertTrue(os.path.exists(core_path)) g.exit()
def test_load_set_breakpoint_run_exit_raw(self): """ Test a common GDB cycle using raw commands: load, set break, run, exit """ self.log.info("Testing that GDB loads a file and sets a breakpoint") g = gdb.GDB() file_cmd = "-file-exec-and-symbols %s" % self.return99_binary_path r = g.cmd(file_cmd) self.assertEqual(r.result.class_, 'done') break_cmd = "-break-insert 5" r = g.cmd(break_cmd) self.assertEqual(r.result.class_, 'done') self.assertEqual(r.result.result.bkpt.number, '1') self.assertEqual(r.result.result.bkpt.enabled, 'y') break_del_cmd = "-break-delete 1" r = g.cmd(break_del_cmd) self.assertEqual(r.result.class_, 'done') run_cmd = "-exec-run" r = g.cmd(run_cmd) self.assertEqual(r.result.class_, 'running') g.cmd("-gdb-exit") self.assertEqual(g.process.wait(), 0)
def test_stream_messages(self): """ Tests if the expected response appears in the result stream messages """ self.log.info("Testing that messages appears in the result stream") g = gdb.GDB() r = g.cmd("-gdb-version") self.assertIn("GNU GPL version", r.get_stream_messages_text())
def test_set_multiple_break(self): """ Tests that multiple breakpoints do not interfere with each other """ self.log.info("Testing setting multiple breakpoints") g = gdb.GDB() g.set_file(self.return99_binary_path) g.set_break('empty') g.set_break('7') g.exit()
def test_load_set_breakpoint_run_exit(self): """ Test a common GDB cycle: load, set break, del break, run, exit """ self.log.info("Testing a common GDB cycle") g = gdb.GDB() g.set_file(self.return99_binary_path) g.set_break("5") g.del_break(1) g.run() g.exit()
def test_start_exit(self): """ Tests execution of multiple GDB instances without any blocking or race """ self.log.info("Testing execution of multiple GDB instances") process_count = 10 gdb_instances = [] for i in range(0, process_count): gdb_instances.append(gdb.GDB()) for i in range(0, process_count): self.assertEqual(gdb_instances[i].exit(), 0)
def test_existing_commands(self): g = gdb.GDB() self.log.info("Testing existing (valid) GDB commands using utility " "methods") for cmd in self.VALID_CMDS: self.assertTrue(g.cmd_exists(cmd)) g.cmd(cmd) self.log.info("Testing non-existing (invalid) GDB commands using " "utility methods") for cmd in self.INVALID_CMDS: self.assertFalse(g.cmd_exists(cmd))
def test_server_stdout(self): self.log.info('Testing server stdout/stderr collection') s = gdb.GDBServer() c = gdb.GDB() c.connect(s.port) c.set_file(self.return99_binary_path) c.run() s.exit() self.assertTrue(os.path.exists(s.stdout_path)) self.assertTrue(os.path.exists(s.stderr_path)) stdout_lines = genio.read_all_lines(s.stdout_path) self.assertIn("return 99\n", stdout_lines)
def test(self): """ Execute 'print_variable'. """ path = os.path.join(self.workdir, self.__binary) app = gdb.GDB() app.set_file(path) app.set_break(6) app.run() self.log.info("\n".join([line.decode() for line in app.read_until_break()])) app.cmd("set variable a = 0xff") app.cmd("c") out = "\n".join([line.decode() for line in app.read_until_break()]) self.log.info(out) app.exit() self.assertIn("MY VARIABLE 'A' IS: ff", out)
def test_disconnect(self): """ Connect/disconnect repeatedly from a remote debugger using utilities """ self.log.info("Testing connecting and disconnecting repeatedly") s = gdb.GDBServer() g = gdb.GDB() for i in range(0, 100): r = g.connect(s.port) self.assertEqual(r.result.class_, 'connected') r = g.disconnect() self.assertEqual(r.result.class_, 'done') g.exit() s.exit()
def test_existing_commands_raw(self): """ Tests the GDB response to commands that exist and to those that do not """ g = gdb.GDB() self.log.info("Testing existing (valid) GDB commands using raw commands") for cmd in self.VALID_CMDS: info_cmd = "-info-gdb-mi-command %s" % cmd[1:] r = g.cmd(info_cmd) self.assertEqual(r.result.result.command.exists, 'true') self.log.info("Testing non-existing (invalid) GDB commands using raw " "commands") for cmd in self.INVALID_CMDS: info_cmd = "-info-gdb-mi-command %s" % cmd[1:] r = g.cmd(info_cmd) self.assertEqual(r.result.result.command.exists, 'false')
def test_multiple_servers(self): """ Tests multiple server instances without any blocking or race condition """ self.log.info("Testing execution of multiple GDB server instances") process_count = 10 server_instances = [] for i in range(0, process_count): s = gdb.GDBServer() c = gdb.GDB() c.connect(s.port) c.cmd('show-version') c.disconnect() server_instances.append(s) for i in range(0, process_count): self.assertTrue(self.is_process_alive(server_instances[i].process)) server_instances[i].exit() self.assertFalse(self.is_process_alive(server_instances[i].process))
def test_remote_exec(self): """ Tests execution on a remote target """ self.log.info("Testing execution on a remote target") hit_breakpoint = False s = gdb.GDBServer() g = gdb.GDB() cmd = f"-file-exec-and-symbols {self.return99_binary_path}" r = g.cmd(cmd) self.assertEqual(r.result.class_, "done") cmd = f"set remote exec-file {self.return99_binary_path}" r = g.cmd(cmd) self.assertEqual(r.result.class_, "done") cmd = f"-break-insert {'main'}" r = g.cmd(cmd) self.assertEqual(r.result.class_, "done") r = g.cmd("-exec-run") other_messages = g.read_until_break() for msg in other_messages: parsed_msg = gdb.parse_mi(msg.decode()) if ( hasattr(parsed_msg, "class_") and parsed_msg.class_ == "stopped" and parsed_msg.result.reason == "breakpoint-hit" ): hit_breakpoint = True self.assertTrue(hit_breakpoint) g.exit() s.exit()