mirror of
https://github.com/open-goal/jak-project
synced 2026-06-04 10:49:04 -04:00
Add some debugger memory utilities (#109)
* add some memory utilities * run waitpid in a separate thread and support very simple breakpoints * fix breakpoints * add missing windows stub function * fix error message on exit
This commit is contained in:
@@ -106,4 +106,81 @@ TEST(Debugger, DebuggerWriteMemory) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Debugger, Symbol) {
|
||||
Compiler compiler;
|
||||
// evidently you can't ptrace threads in your own process, so we need to run the runtime in a
|
||||
// separate process.
|
||||
if (!fork()) {
|
||||
GoalTest::runtime_no_kernel();
|
||||
exit(0);
|
||||
} else {
|
||||
compiler.connect_to_target();
|
||||
compiler.poke_target();
|
||||
compiler.run_test_from_string("(dbg)");
|
||||
EXPECT_TRUE(compiler.get_debugger().do_continue());
|
||||
auto result = compiler.run_test_from_string("(define test-symbol (the int 123))");
|
||||
EXPECT_TRUE(compiler.get_debugger().do_break());
|
||||
auto addr = compiler.get_debugger().get_symbol_address("test-symbol");
|
||||
u32 value;
|
||||
EXPECT_TRUE(compiler.get_debugger().read_value(&value, addr));
|
||||
EXPECT_EQ(value, 123);
|
||||
EXPECT_TRUE(compiler.get_debugger().write_value<u32>(456, addr));
|
||||
EXPECT_TRUE(compiler.get_debugger().read_value(&value, addr));
|
||||
EXPECT_EQ(value, 456);
|
||||
|
||||
EXPECT_TRUE(compiler.get_debugger().do_continue());
|
||||
result = compiler.run_test_from_string("test-symbol");
|
||||
EXPECT_EQ(456, std::stoi(result.at(0)));
|
||||
|
||||
compiler.shutdown_target();
|
||||
|
||||
// and now the child process should be done!
|
||||
EXPECT_TRUE(wait(nullptr) >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Debugger, SimpleBreakpoint) {
|
||||
Compiler compiler;
|
||||
|
||||
if (!fork()) {
|
||||
GoalTest::runtime_no_kernel();
|
||||
exit(0);
|
||||
} else {
|
||||
compiler.connect_to_target();
|
||||
compiler.poke_target();
|
||||
compiler.run_test_from_string("(defun test-function () (+ 1 2 3 4 5 6))");
|
||||
;
|
||||
compiler.run_test_from_string("(dbg)");
|
||||
u32 func_addr;
|
||||
EXPECT_TRUE(compiler.get_debugger().get_symbol_value("test-function", &func_addr));
|
||||
EXPECT_TRUE(compiler.get_debugger().is_valid());
|
||||
EXPECT_TRUE(compiler.get_debugger().is_halted());
|
||||
|
||||
compiler.get_debugger().add_addr_breakpoint(func_addr); // todo from code.
|
||||
compiler.run_test_from_string("(:cont)");
|
||||
compiler.run_test_from_string("(test-function)");
|
||||
// wait for breakpoint to be hit.
|
||||
while (!compiler.get_debugger().is_halted()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
compiler.get_debugger().get_break_info();
|
||||
auto expected_instr_before_rip = compiler.get_debugger().get_x86_base_addr() + func_addr;
|
||||
auto rip = compiler.get_debugger().get_regs().rip;
|
||||
// instructions can be at most 15 bytes long.
|
||||
EXPECT_TRUE(rip > expected_instr_before_rip && rip < expected_instr_before_rip + 15);
|
||||
|
||||
EXPECT_TRUE(compiler.get_debugger().is_halted());
|
||||
compiler.get_debugger().remove_addr_breakpoint(func_addr);
|
||||
compiler.get_debugger().do_continue();
|
||||
|
||||
auto result = compiler.run_test_from_string("(test-function)");
|
||||
EXPECT_EQ(std::stoi(result.at(0)), 21);
|
||||
compiler.shutdown_target();
|
||||
|
||||
// and now the child process should be done!
|
||||
EXPECT_TRUE(wait(nullptr) >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user