Skip to content

Commit

Permalink
c-api: Enable debugger DWARF export for guest code (bytecodealliance#…
Browse files Browse the repository at this point in the history
…9915)

* c-api: Enable debugger DWARF export for guest code

In order to allow source level debugging of hosted webassembly code in
C-based embeddings, we must enable the debug-builtins cargo feature when
building the C api.

* c-api test: assert that the debug info is created

Previously we were testing and confirming only that the options can be
set using the API, not that they actually have any effect.

In order to (simply) confirm that enabling debug information actually
created some debug information, we can somewhat hackily inspect the
generated GDB JIT descriptor to see that it's populated.
  • Loading branch information
puremourning authored Dec 30, 2024
1 parent 90e6651 commit 6a95189
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ gc-drc = ["wasmtime/gc-drc"]
gc-null = ["wasmtime/gc-null"]
cranelift = ['wasmtime/cranelift']
winch = ['wasmtime/winch']
debug-builtins = ['wasmtime/debug-builtins']
# ... if you add a line above this be sure to change the other locations
# marked WASMTIME_FEATURE_LIST
2 changes: 2 additions & 0 deletions crates/c-api/artifact/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ default = [
'gc-null',
'cranelift',
'winch',
'debug-builtins',
# ... if you add a line above this be sure to change the other locations
# marked WASMTIME_FEATURE_LIST
]
Expand All @@ -58,5 +59,6 @@ gc-drc = ["wasmtime-c-api/gc-drc"]
gc-null = ["wasmtime-c-api/gc-null"]
cranelift = ["wasmtime-c-api/cranelift"]
winch = ["wasmtime-c-api/winch"]
debug-builtins = ["wasmtime-c-api/debug-builtins"]
# ... if you add a line above this be sure to read the comment at the end of
# `default`
1 change: 1 addition & 0 deletions crates/c-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const FEATURES: &[&str] = &[
"GC_NULL",
"CRANELIFT",
"WINCH",
"DEBUG_BUILTINS",
];
// ... if you add a line above this be sure to change the other locations
// marked WASMTIME_FEATURE_LIST
Expand Down
1 change: 1 addition & 0 deletions crates/c-api/cmake/features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ feature(gc-null ON)
feature(async ON)
feature(cranelift ON)
feature(winch ON)
feature(debug-builtins ON)
# ... if you add a line above this be sure to change the other locations
# marked WASMTIME_FEATURE_LIST
1 change: 1 addition & 0 deletions crates/c-api/include/wasmtime/conf.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#cmakedefine WASMTIME_FEATURE_ASYNC
#cmakedefine WASMTIME_FEATURE_CRANELIFT
#cmakedefine WASMTIME_FEATURE_WINCH
#cmakedefine WASMTIME_FEATURE_DEBUG_BUILTINS
// ... if you add a line above this be sure to change the other locations
// marked WASMTIME_FEATURE_LIST

Expand Down
2 changes: 2 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ function(CREATE_TARGET TARGET TARGET_PATH)
target_compile_options(wasmtime-${TARGET} PRIVATE /W3)
endif()

target_compile_definitions(wasmtime-${TARGET} PRIVATE WASMTIME_TEST_ONLY)

set_target_properties(wasmtime-${TARGET} PROPERTIES
OUTPUT_NAME wasmtime-${TARGET}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/$<0:>
Expand Down
53 changes: 53 additions & 0 deletions examples/fib-debug/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,41 @@
#include <wasm.h>
#include <wasmtime.h>

#ifdef WASMTIME_TEST_ONLY
// These are the declarations provided from GDB documentation, used to validate
// that we actually added some DWARF info:
// https://sourceware.org/gdb/current/onlinedocs/gdb.html/Declarations.html#Declarations
//
// NOTE: These are not required in your code, rather they are used for wasmtime
// testing only.
typedef enum {
JIT_NOACTION = 0,
JIT_REGISTER_FN,
JIT_UNREGISTER_FN
} jit_actions_t;

struct jit_code_entry {
struct jit_code_entry *next_entry;
struct jit_code_entry *prev_entry;
const char *symfile_addr;
uint64_t symfile_size;
};

struct jit_descriptor {
uint32_t version;
/* This type should be jit_actions_t, but we use uint32_t
to be explicit about the bitwidth. */
uint32_t action_flag;
struct jit_code_entry *relevant_entry;
struct jit_code_entry *first_entry;
};

/*
* Import the descriptor, defined elsewhere in wasmtime
*/
extern struct jit_descriptor __jit_debug_descriptor;
#endif

#define own

static void exit_with_error(const char *message, wasmtime_error_t *error,
Expand All @@ -24,6 +59,15 @@ int main(int argc, const char *argv[]) {
wasmtime_store_t *store = wasmtime_store_new(engine, NULL, NULL);
wasmtime_context_t *context = wasmtime_store_context(store);

#ifdef WASMTIME_TEST_ONLY
// NOTE: This validation is for wasmtime testing and should not be included in
// your code.
if (__jit_debug_descriptor.first_entry != NULL) {
fprintf(stderr, "FAIL: JIT descriptor is already initialized\n");
return 1;
}
#endif

// Load binary.
printf("Loading binary...\n");
FILE *file = fopen("target/wasm32-unknown-unknown/debug/fib.wasm", "rb");
Expand Down Expand Up @@ -60,6 +104,15 @@ int main(int argc, const char *argv[]) {
exit_with_error("failed to instantiate", error, trap);
wasmtime_module_delete(module);

#ifdef WASMTIME_TEST_ONLY
// NOTE: This validation is for wasmtime testing and should not be included in
// your code.
if (__jit_debug_descriptor.first_entry == NULL) {
fprintf(stderr, "FAIL: JIT descriptor is NOT initialized\n");
return 1;
}
#endif

// Extract export.
wasmtime_extern_t fib;
bool ok = wasmtime_instance_export_get(context, &instance, "fib", 3, &fib);
Expand Down

0 comments on commit 6a95189

Please sign in to comment.