Skip to content

Commit f2d5440

Browse files
jsturtevantdblnz
andauthored
Add crashdump example and include snapshot/scratch in core dumps (#1264)
* Include snapshot and scratch regions in crash dumps Co-authored-by: Doru Blânzeanu <dblnz@pm.me> Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Add sentinel page for clean GDB backtraces Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Tighten runtime config plumbing for crash dumps The runtime config was passed by reference into set_up_hypervisor_partition then immediately cloned, but no caller needs it afterward so it is now passed by value. The entry point field uses Option<u64> instead of a bare zero default so a missing value is detectable rather than silently producing a bogus AT_ENTRY. Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * Add explicit dump directory API for crash dumps generate_crashdump_to_dir accepts the output directory as a parameter instead of requiring callers to set the HYPERLIGHT_CORE_DUMP_DIR environment variable. This removes the need for unsafe std::env::set_var in tests while preserving the existing env-var fallback path for the automatic dump and the no-argument generate_crashdump method. Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * fixup! Include snapshot and scratch regions in crash dumps Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * fixup! Add sentinel page for clean GDB backtraces Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * fixup! Include snapshot and scratch regions in crash dumps Signed-off-by: James Sturtevant <jsturtevant@gmail.com> * fixup! Add sentinel page for clean GDB backtraces Signed-off-by: James Sturtevant <jsturtevant@gmail.com> --------- Signed-off-by: James Sturtevant <jsturtevant@gmail.com> Co-authored-by: Doru Blânzeanu <dblnz@pm.me>
1 parent 0dbbce5 commit f2d5440

File tree

14 files changed

+1046
-50
lines changed

14 files changed

+1046
-50
lines changed

Justfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ test-rust-gdb-debugging target=default-target features="":
248248
# rust test for crashdump
249249
test-rust-crashdump target=default-target features="":
250250
{{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} {{ if features =="" {'--features crashdump'} else { "--features crashdump," + features } }} -- test_crashdump
251+
{{ cargo-cmd }} test --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example crashdump {{ if features =="" {'--features crashdump'} else { "--features crashdump," + features } }}
251252

252253
# rust test for tracing
253254
test-rust-tracing target=default-target features="":
@@ -353,6 +354,7 @@ run-rust-examples target=default-target features="":
353354
run-rust-examples-linux target=default-target features="": (run-rust-examples target features)
354355
{{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example tracing {{ if features =="" {''} else { "--features " + features } }}
355356
{{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example tracing {{ if features =="" {"--features function_call_metrics" } else {"--features function_call_metrics," + features} }}
357+
{{ cargo-cmd }} run --profile={{ if target == "debug" { "dev" } else { target } }} {{ target-triple-flag }} --example crashdump {{ if features =="" {'--features crashdump'} else { "--features crashdump," + features } }}
356358

357359

358360
#########################

docs/how-to-debug-a-hyperlight-guest.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,48 @@ The crashdump should be available `/tmp` or in the crash dump directory (see `HY
264264
After the core dump has been created, to inspect the state of the guest, load the core dump file using `gdb` or `lldb`.
265265
**NOTE: This feature has been tested with version `15.0` of `gdb` and version `17` of `lldb`, earlier versions may not work, it is recommended to use these versions or later.**
266266

267+
#### Using gdb
268+
269+
Load the core dump alongside the guest binary that was running when the crash occurred:
270+
271+
```bash
272+
gdb <guest-binary> -c <core-dump-file>
273+
```
274+
275+
For example:
276+
277+
```bash
278+
gdb src/tests/rust_guests/bin/debug/simpleguest -c /tmp/hl_dumps/hl_core_20260225_T165358.517.elf
279+
```
280+
281+
Common commands for inspecting the dump:
282+
283+
```gdb
284+
# View all general-purpose registers (rip, rsp, rflags, etc.)
285+
(gdb) info registers
286+
287+
# Disassemble around the crash site
288+
(gdb) x/10i $rip
289+
290+
# View the stack
291+
(gdb) x/16xg $rsp
292+
293+
# Backtrace (requires debug info in guest binary)
294+
(gdb) bt
295+
296+
# List all memory regions in the dump (snapshot, scratch, mapped regions)
297+
(gdb) info files
298+
299+
# Read memory at a specific address
300+
(gdb) x/s <address> # null-terminated string
301+
(gdb) x/32xb <address> # 32 bytes in hex
302+
```
303+
304+
See the `crashdump` example (`cargo run --example crashdump --features crashdump`)
305+
for a runnable demonstration of both automatic and on-demand crash dumps.
306+
307+
#### Using VSCode
308+
267309
To do this in vscode, the following configuration can be used to add debug configurations:
268310

269311
```vscode

src/hyperlight_guest_bin/src/arch/amd64/dispatch.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ unsafe extern "C" {
5858
core::arch::global_asm!("
5959
.global dispatch_function
6060
dispatch_function:
61+
.cfi_startproc
62+
.cfi_undefined rip
6163
jnz flush_done
6264
mov rdi, cr4
6365
xor rdi, 0x80
@@ -67,4 +69,5 @@ core::arch::global_asm!("
6769
flush_done:
6870
call {internal_dispatch_function}\n
6971
hlt\n
72+
.cfi_endproc
7073
", internal_dispatch_function = sym crate::guest_function::call::internal_dispatch_function);

src/hyperlight_guest_bin/src/arch/amd64/init.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,22 @@ unsafe extern "C" {
157157
) -> !;
158158
}
159159

160+
// Mark this as the bottom-most frame for debuggers:
161+
// - .cfi_undefined rip: tells DWARF unwinders there is no return
162+
// address to recover (i.e. no caller frame).
163+
// - xor ebp, ebp: sets the frame pointer to zero so frame-pointer-
164+
// based unwinders recognise this as the end of the chain.
165+
// See System V AMD64 ABI: https://gitlab.com/x86-psABIs/x86-64-ABI
166+
// §3.4.1 (Initial Stack and Register State)
167+
// §6.3 Unwinding Through Assembler Code
160168
core::arch::global_asm!("
161169
.global pivot_stack\n
162170
pivot_stack:\n
171+
.cfi_startproc\n
172+
.cfi_undefined rip\n
163173
mov rsp, r8\n
174+
xor ebp, ebp\n
164175
call {generic_init}\n
165176
hlt\n
177+
.cfi_endproc\n
166178
", generic_init = sym crate::generic_init);

0 commit comments

Comments
 (0)