A debugging and instruction tracing tool for LoongArch binaries.
The debug_test program executes LoongArch ELF binaries with detailed instruction-by-instruction tracing, register state monitoring, and optional objdump comparison. This tool is invaluable for debugging emulator behavior and understanding program execution.
From the project root:
mkdir build && cd build
cmake ..
makeThe debugger binary will be located at build/tests/debug_test.
debug_test [options] <binary>
| Option | Long Form | Description |
|---|---|---|
-h |
--help |
Show help message |
-i <num> |
--max-instructions |
Maximum instructions to execute (default: 10000000) |
-m <size> |
--memory |
Maximum memory in MiB (default: 256) |
-q |
--quiet |
Disable verbose loader and syscalls |
-r |
--registers |
Show register state after each instruction |
-o |
--compare-objdump |
Compare execution with objdump disassembly |
-s |
--short |
Use short output format |
Basic execution with full tracing:
./debug_test program.elfLimit execution to 1 million instructions with short output:
./debug_test --max-instructions 1000000 --short program.elfQuiet mode with hidden registers:
./debug_test -q -r program.elfCompare with objdump disassembly:
./debug_test --compare-objdump program.elfAllocate more memory:
./debug_test --memory 512 program.elfThe debugger provides detailed execution traces:
Starting execution at PC=0x120000790
PC=0x120000790 addi.d $sp, $sp, -48 ($sp = 0x40003ff0)
$sp = 0x40003ff0
PC=0x120000794 st.d $ra, $sp, 40 (MEM[0x40004018] = 0x0)
$ra = 0x0
Each instruction shows:
- Program counter (PC)
- Disassembly with operands
- Computed result (for relevant instructions)
- Affected register values
On platforms without getopt_long support, configuration can be done via environment variables:
| Variable | Description |
|---|---|
MAX_INSTRUCTIONS |
Maximum instructions to execute |
MEMORY_MAX |
Maximum memory in MiB |
QUIET |
Set to disable verbose output |
VERBOSE_REGISTERS |
Set to "0" to hide registers |
COMPARE_OBJDUMP |
Set to enable objdump comparison |
SHORT |
Set to enable short output format |
Example (Windows):
set MAX_INSTRUCTIONS=1000000
set SHORT=1
debug_test.exe program.elfExample (Unix):
QUIET=1 SHORT=1 ./debug_test program.elfVerify instruction decoder and execution correctness:
./debug_test --compare-objdump test_program.elfCount instructions for specific programs:
./debug_test --max-instructions 0 --short benchmark.elfTrace execution to find bugs in LoongArch binaries:
./debug_test --verbose program.elf 2>&1 | lessAutomate execution verification:
./debug_test --quiet --short test.elf && echo "PASS" || echo "FAIL"The debugger is used in continuous integration for instruction validation. See the GitHub Actions workflows for automated testing.
Ensure the binary path is correct and the file exists.
The guest program triggered an exception (invalid memory access, illegal instruction, etc.). Check the PC and register state in the error output.
The program exceeded the instruction limit. Increase with --max-instructions or use 0 for unlimited execution.
If using --compare-objdump, ensure loongarch64-linux-gnu-objdump is installed:
sudo apt-get install binutils-loongarch64-linux-gnuThe debugger wraps Machine with DebugMachine, which:
- Hooks into instruction execution
- Disassembles each instruction
- Tracks register changes
- Formats output for human readability
This is built on top of the core emulation library, providing a debugging layer without modifying the fast path.
- Unit Tests - Automated testing framework
- Emulator CLI - Production emulator
- API Documentation - Library integration guide