If you encounter unexpected shutdowns or panics like:
panicked at 'explicit panic', src/syscall.rs:167:9
TRACE:
0x000000000000f876
0x0000000000039d10
0x0000000000007189
0x0000000000008d3e
0x0000000000008b58
P 0x0000000000001279
P 0x000000000000102c
or
Error: Shutdown Ok(
kvm_regs {
rax: 0x29f47,
rbx: 0x2a014,
rcx: 0x15475,
rdx: 0x246e8,
rsi: 0x269b0,
rdi: 0x1e2db,
rsp: 0xffffff8000433900,
rbp: 0xffffff8000433a70,
r8: 0x129cb,
r9: 0x29ed7,
r10: 0x2a074,
r11: 0x154f5,
r12: 0x259b0,
r13: 0x268f0,
r14: 0x109ac,
r15: 0x30889,
rip: 0xffffff8000230662,
rflags: 0x10046,
},
)
you might get a meaningful stack backtrace with the helper/parse-trace.sh
script:
$ ./helper/parse-trace.sh <shim> [<exec>]
parse-trace.sh
needs addr2line
from binutils
, so make sure that is installed.
To find the shim with the debug info and not stripped run this:
$ find target -wholename '*linux-musl/*/shim-sev'
Then choose either the debug
or release
, depending with which version the panic occurred.
$ ./helper/parse-trace.sh \
target/debug/build/*/out/internal/shim-sev/x86_64-unknown-linux-musl/debug/shim-sev \
< traceback.txt
$ cargo run -- exec <exec> |& ./helper/parse-trace.sh \
target/debug/build/*/out/internal/shim-sev/x86_64-unknown-linux-musl/debug/shim-sev
To enable gdb support, compile enarx with the gdb
feature:
$ cargo clean
$ cargo build --features gdb
Find the "shim" of the TEE. Normally this is shim-sev
:
$ find target -wholename '*linux-musl/*/shim-sev'
target/debug/build/enarx-f0e8a07172ba3be9/out/internal/shim-sev/x86_64-unknown-linux-musl/debug/shim-sev
Find the "exec" of the TEE. Normally this is wasmldr
:
$ find target -wholename '*linux-musl/*/wasmldr'
target/debug/build/enarx-f0e8a07172ba3be9/out/internal/wasmldr/x86_64-unknown-linux-musl/debug/wasmldr
Start the TEE:
$ ./target/debug/enarx run ~/git/zerooneone/target/wasm32-wasi/debug/zerooneone.wasm
[…]
Starting GDB session...
symbol-file -o 0xffffff8000000000 <shim>
add-symbol-file -o 0x7f6ffbef8000 <exec>
[…]
Waiting for a GDB connection on "localhost:23456"...
You can set the listen address with --gdblisten <address>
.
Now connect with gdb
from another terminal and load the symbols from the debug executables as mentioned by the output
with the offsets mentioned. Note: the offsets can vary for every run due to address space layout randomization (ASLR).
$ gdb
[…]
(gdb) symbol-file -o 0xffffff8000000000 target/debug/build/enarx-f0e8a07172ba3be9/out/internal/shim-sev/x86_64-unknown-linux-musl/debug/shim-sev
Reading symbols from target/debug/build/enarx-f0e8a07172ba3be9/out/internal/shim-sev/x86_64-unknown-linux-musl/debug/shim-sev...
(gdb) add-symbol-file -o 0x7f6ffbef8000 target/debug/build/enarx-f0e8a07172ba3be9/out/internal/wasmldr/x86_64-unknown-linux-musl/debug/wasmldr
add symbol table from file "target/debug/build/enarx-f0e8a07172ba3be9/out/internal/wasmldr/x86_64-unknown-linux-musl/debug/wasmldr" with all sections offset by 0xfbef8000
(y or n) y
[…]
(gdb) target remote localhost:23456
Remote debugging using localhost:23456
[…]
0x00007f434ee83cc9 in _start ()
The current execution is stopped in the "exec" executable at the ELF entry point _start
. You can now start debugging the "exec".
(gdb) br wasmldr::main
Breakpoint 1 at 0x7f434efddbeb: file src/main.rs, line 72.
(gdb) cont
Continuing.
Breakpoint 1, wasmldr::main () at src/main.rs:72
72 env_logger::Builder::from_default_env().init();
(gdb) list
67 fn main() {
68 // KEEP-CONFIG HACK: we've inherited stdio and the shim sets
69 // "RUST_LOG=debug", so this should make logging go to stderr.
70 // FUTURE: we should have a keep-provided debug channel where we can
71 // (safely, securely) send logs. Might need our own logger for that..
72 env_logger::Builder::from_default_env().init();
73
74 info!("version {} starting up", env!("CARGO_PKG_VERSION"));
75
76 warn!("🌭DEV-ONLY BUILD, NOT FOR PRODUCTION USE🌭");
(gdb) print $pc
$1 = (*mut fn ()) 0x7f434efddbeb <wasmldr::main+11>
(gdb) stepi
0x00007f434efddbf2 72 env_logger::Builder::from_default_env().init();
(gdb) print $pc
$2 = (*mut fn ()) 0x7f434efddbf2 <wasmldr::main+18>
(gdb) stepi
0x00007f434efddbf9 72 env_logger::Builder::from_default_env().init();
(gdb) print $pc
$3 = (*mut fn ()) 0x7f434efddbf9 <wasmldr::main+25>
Find the "shim" of the TEE. Normally this is shim-sgx
:
$ find target -wholename '*linux-musl/*/shim-sgx'
target/debug/build/enarx-f0e8a07172ba3be9/out/internal/shim-sgx/x86_64-unknown-linux-musl/debug/shim-sgx
Find the "exec" of the TEE. Normally this is wasmldr
:
$ find target -wholename '*linux-musl/*/wasmldr'
target/debug/build/enarx-f0e8a07172ba3be9/out/internal/wasmldr/x86_64-unknown-linux-musl/debug/wasmldr
Start the TEE:
$ ./target/debug/enarx run ~/git/zerooneone/target/wasm32-wasi/debug/zerooneone.wasm
[…]
Starting GDB session...
symbol-file -o 0x7fcf00000000 <shim>
symbol-file -o 0x7fcf00400000 <exec>
Waiting for a GDB connection on "localhost:23456"...
You can set the listen address with --gdblisten <address>
.
Now connect with gdb
from another terminal and load the symbols from the debug executables as mentioned by the output
with the offsets mentioned. Note: the offsets can vary for every run due to address space layout randomization (ASLR).
$ gdb
[…]
(gdb) symbol-file -o 0x7fcf00400000 target/debug/build/enarx-f0e8a07172ba3be9/out/internal/wasmldr/x86_64-unknown-linux-musl/debug/wasmldr
Reading symbols from target/debug/build/enarx-f0e8a07172ba3be9/out/internal/wasmldr/x86_64-unknown-linux-musl/debug/wasmldr...
warning: Missing auto-load script at offset 0 in section .debug_gdb_scripts
of file /home/harald/git/enarx/enarx/target/debug/build/enarx-f0e8a07172ba3be9/out/internal/wasmldr/x86_64-unknown-linux-musl/debug/wasmldr.
Use `info auto-load python-scripts [REGEXP]' to list them.
(gdb) target remote localhost:23456
Remote debugging using localhost:23456
[…]
0x00007f434ee83cc9 in _start ()
The current execution is stopped in the "exec" executable at the ELF entry point _start
. You can now start debugging the "exec".
NOTE: stepping does not work (yet) in SGX.
(gdb) br wasmldr::main
Breakpoint 1 at 0x7fcf007368cb: file src/main.rs, line 72.
(gdb) cont
Continuing.
Breakpoint 1, wasmldr::main () at src/main.rs:72
72 env_logger::Builder::from_default_env().init();
(gdb) list
67 fn main() {
68 // KEEP-CONFIG HACK: we've inherited stdio and the shim sets
69 // "RUST_LOG=debug", so this should make logging go to stderr.
70 // FUTURE: we should have a keep-provided debug channel where we can
71 // (safely, securely) send logs. Might need our own logger for that..
72 env_logger::Builder::from_default_env().init();
73
74 info!("version {} starting up", env!("CARGO_PKG_VERSION"));
75
76 warn!("🌭DEV-ONLY BUILD, NOT FOR PRODUCTION USE🌭");
(gdb) br workload::run
Breakpoint 2 at 0x7fcf005f6c64: file src/workload.rs, line 81.
(gdb) cont
Continuing.
Breakpoint 2, wasmldr::workload::run<alloc::string::String, alloc::string::String, alloc::vec::Vec<u8, alloc::alloc::Global>, alloc::vec::Vec<alloc::string::String, alloc::alloc::Global>, alloc::vec::Vec<(alloc::string::String, alloc::string::String), alloc::alloc::Global>> (bytes=..., args=..., envs=...) at src/workload.rs:81
81 debug!("configuring wasmtime engine");
(gdb) list
76 pub fn run<T: AsRef<str>, U: AsRef<str>>(
77 bytes: impl AsRef<[u8]>,
78 args: impl IntoIterator<Item = T>,
79 envs: impl IntoIterator<Item = (U, U)>,
80 ) -> Result<Box<[wasmtime::Val]>> {
81 debug!("configuring wasmtime engine");
82 let mut config = wasmtime::Config::new();
83 // Support module-linking (https://github.com/webassembly/module-linking)
84 config.wasm_module_linking(true);
85 // module-linking requires multi-memory