Skip to content

Commit c275139

Browse files
committed
wasmtime: add proper exit status handling
Signed-off-by: Maximilian Hüter <t4chib4ne@mailbox.org>
1 parent 08e6e1a commit c275139

File tree

1 file changed

+57
-11
lines changed

1 file changed

+57
-11
lines changed

src/libcrun/handlers/wasmtime.c

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
= libwasmtime_load_symbol ((cookie), "wasm_byte_vec_delete"); \
5050
void (*wasmtime_error_message) (const wasmtime_error_t *error, wasm_name_t *message) \
5151
= libwasmtime_load_symbol ((cookie), "wasmtime_error_message"); \
52+
bool (*wasmtime_error_exit_status) (const wasmtime_error_t *error, int *status) \
53+
= libwasmtime_load_symbol ((cookie), "wasmtime_error_exit_status"); \
5254
void (*wasmtime_error_delete) (wasmtime_error_t * error) \
5355
= libwasmtime_load_symbol ((cookie), "wasmtime_error_delete");
5456

@@ -171,10 +173,10 @@ libwasmtime_free_vm (void *cookie, struct libwasmtime_vm *vm)
171173
wasm_engine_delete (vm->engine);
172174
}
173175

174-
static void
176+
static int
175177
libwasmtime_run_module (void *cookie, struct libwasmtime_vm *vm, wasm_byte_vec_t *wasm);
176178

177-
static void
179+
static int
178180
libwasmtime_run_component (void *cookie, struct libwasmtime_vm *vm, wasm_byte_vec_t *wasm);
179181

180182
static int
@@ -183,6 +185,7 @@ libwasmtime_exec (void *cookie, libcrun_container_t *container arg_unused,
183185
{
184186
wasm_byte_vec_t error_message;
185187
wasm_byte_vec_t wasm_bytes;
188+
int status;
186189

187190
WASMTIME_COMMON_SYMBOLS (cookie)
188191
wasmtime_error_t *(*wasmtime_wat2wasm) (const char *wat, size_t wat_len, wasm_byte_vec_t *out)
@@ -231,14 +234,14 @@ libwasmtime_exec (void *cookie, libcrun_container_t *container arg_unused,
231234
libwasmtime_setup_vm (cookie, argv, &vm);
232235

233236
if (wasm_enc == WASM_ENC_MODULE)
234-
libwasmtime_run_module (cookie, &vm, &wasm);
237+
status = libwasmtime_run_module (cookie, &vm, &wasm);
235238
else if (wasm_enc == WASM_ENC_COMPONENT)
236-
libwasmtime_run_component (cookie, &vm, &wasm);
239+
status = libwasmtime_run_component (cookie, &vm, &wasm);
237240
else
238241
error (EXIT_FAILURE, 0, "unsupported wasm encoding detected");
239242

240243
libwasmtime_free_vm (cookie, &vm);
241-
exit (EXIT_SUCCESS);
244+
exit (status);
242245
}
243246

244247
static void *
@@ -251,7 +254,7 @@ libwasmtime_load_symbol (void *cookie, char *const symbol)
251254
return sym;
252255
}
253256

254-
static void
257+
static int
255258
libwasmtime_run_module (void *cookie, struct libwasmtime_vm *vm, wasm_byte_vec_t *wasm)
256259
{
257260
wasmtime_error_t *err;
@@ -292,6 +295,10 @@ libwasmtime_run_module (void *cookie, struct libwasmtime_vm *vm, wasm_byte_vec_t
292295
size_t nresults,
293296
wasm_trap_t **trap)
294297
= libwasmtime_load_symbol (cookie, "wasmtime_func_call");
298+
void (*wasm_trap_message) (const wasm_trap_t *trap, wasm_message_t *message)
299+
= libwasmtime_load_symbol (cookie, "wasm_trap_message");
300+
void (*wasm_trap_delete) (wasm_trap_t *)
301+
= libwasmtime_load_symbol (cookie, "wasm_trap_delete");
295302
void (*wasmtime_module_delete) (wasmtime_module_t *m)
296303
= libwasmtime_load_symbol (cookie, "wasmtime_module_delete");
297304

@@ -348,20 +355,31 @@ libwasmtime_run_module (void *cookie, struct libwasmtime_vm *vm, wasm_byte_vec_t
348355
error (EXIT_FAILURE, 0, "failed to locate default export for module %.*s", (int) error_message.size, error_message.data);
349356
}
350357

358+
int status = EXIT_SUCCESS;
351359
wasm_trap_t *trap = NULL;
352360
err = wasmtime_func_call (vm->context, &func, NULL, 0, NULL, 0, &trap);
353-
if (err != NULL || trap != NULL)
361+
if (err != NULL && ! wasmtime_error_exit_status (err, &status))
354362
{
363+
// The error does not describe an exit code thus we error out.
355364
wasmtime_error_message (err, &error_message);
356365
wasmtime_error_delete (err);
357366
error (EXIT_FAILURE, 0, "error calling default export: %.*s", (int) error_message.size, error_message.data);
358367
}
368+
if (trap != NULL)
369+
{
370+
wasm_trap_message (trap, &error_message);
371+
wasm_trap_delete (trap);
372+
fprintf (stderr, "trap tiggered in module: %.*s", (int) error_message.size, error_message.data);
373+
status = EXIT_FAILURE;
374+
}
359375

360376
// Clean everything
361377
wasmtime_module_delete (module);
378+
379+
return status;
362380
}
363381

364-
static void
382+
static int
365383
libwasmtime_run_component (void *cookie, struct libwasmtime_vm *vm, wasm_byte_vec_t *wasm)
366384
{
367385
const char *const wasi_cli_run_interface = "wasi:cli/run@0.2.0";
@@ -408,6 +426,8 @@ libwasmtime_run_component (void *cookie, struct libwasmtime_vm *vm, wasm_byte_ve
408426
wasmtime_component_val_t *results,
409427
size_t results_size)
410428
= libwasmtime_load_symbol (cookie, "wasmtime_component_func_call");
429+
wasmtime_error_t *(*wasmtime_component_func_post_return) (const wasmtime_component_func_t *func, wasmtime_context_t *context)
430+
= libwasmtime_load_symbol (cookie, "wasmtime_component_func_post_return");
411431
void (*wasmtime_component_export_index_delete) (wasmtime_component_export_index_t *export_index)
412432
= libwasmtime_load_symbol (cookie, "wasmtime_component_export_index_delete");
413433
void (*wasmtime_component_delete) (wasmtime_component_t *c)
@@ -479,20 +499,46 @@ libwasmtime_run_component (void *cookie, struct libwasmtime_vm *vm, wasm_byte_ve
479499
error (EXIT_FAILURE, 0, "failed to retrieve run function");
480500

481501
// Call the func
502+
int status = EXIT_SUCCESS;
503+
bool func_call_caused_error = false;
482504
wasmtime_component_val_t result = {};
483505
err = wasmtime_component_func_call (&run_func, vm->context, NULL, 0, &result, 1);
484506
if (err != NULL)
485507
{
486-
wasmtime_error_message (err, &error_message);
487-
wasmtime_error_delete (err);
488-
error (EXIT_FAILURE, 0, "error calling run function: %.*s", (int) error_message.size, error_message.data);
508+
if (wasmtime_error_exit_status (err, &status))
509+
{
510+
wasmtime_error_delete (err);
511+
func_call_caused_error = true;
512+
}
513+
else
514+
{
515+
// The error does not describe an exit code thus we error out.
516+
wasmtime_error_message (err, &error_message);
517+
wasmtime_error_delete (err);
518+
error (EXIT_FAILURE, 0, "error calling run function: %.*s", (int) error_message.size, error_message.data);
519+
}
520+
}
521+
522+
// Call its post-return __only__ if `wasmtime_component_func_call` was successful.
523+
// Even an error describing an exit code which may be 0 counts as not successful.
524+
if (! func_call_caused_error)
525+
{
526+
err = wasmtime_component_func_post_return (&run_func, vm->context);
527+
if (err != NULL)
528+
{
529+
wasmtime_error_message (err, &error_message);
530+
wasmtime_error_delete (err);
531+
error (EXIT_FAILURE, 0, "error calling run function post-return: %.*s", (int) error_message.size, error_message.data);
532+
}
489533
}
490534

491535
// Clean everything
492536
wasmtime_component_export_index_delete (run_func_idx);
493537
wasmtime_component_export_index_delete (run_interface_idx);
494538
wasmtime_component_linker_delete (linker);
495539
wasmtime_component_delete (component);
540+
541+
return status;
496542
}
497543

498544
static int

0 commit comments

Comments
 (0)