Skip to content

Commit 0b441f7

Browse files
Run rb_vm_bugreport when something went wrong
This would be extremely helpful for debugging which operation triggers Asyncify buffer exhaustion.
1 parent 00a8824 commit 0b441f7

File tree

7 files changed

+40
-6
lines changed

7 files changed

+40
-6
lines changed

ext/witapi/bindgen/rb-abi-guest.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,7 @@ void __wasm_export_rb_abi_guest_rstring_ptr_post_return(int32_t arg0) {
201201
free((void*) (*((int32_t*) (arg0 + 0))));
202202
}
203203
}
204+
__attribute__((export_name("rb-vm-bugreport: func() -> ()")))
205+
void __wasm_export_rb_abi_guest_rb_vm_bugreport(void) {
206+
rb_abi_guest_rb_vm_bugreport();
207+
}

ext/witapi/bindgen/rb-abi-guest.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ extern "C"
6767
rb_abi_guest_rb_abi_value_t rb_abi_guest_rb_errinfo(void);
6868
void rb_abi_guest_rb_clear_errinfo(void);
6969
void rb_abi_guest_rstring_ptr(rb_abi_guest_rb_abi_value_t value, rb_abi_guest_string_t *ret0);
70+
void rb_abi_guest_rb_vm_bugreport(void);
7071
#ifdef __cplusplus
7172
}
7273
#endif

ext/witapi/bindgen/rb-abi-guest.wit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ rb-errinfo: func() -> rb-abi-value
1616
rb-clear-errinfo: func()
1717

1818
rstring-ptr: func(value: rb-abi-value) -> string
19+
20+
rb-vm-bugreport: func()

ext/witapi/witapi-core.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,8 @@ uint32_t rb_abi_guest_rb_abi_value_data_ptr(rb_abi_guest_rb_abi_value_t self) {
247247
return (uint32_t)DATA_PTR(obj);
248248
}
249249

250+
void rb_vm_bugreport(const void *);
251+
252+
void rb_abi_guest_rb_vm_bugreport(void) { rb_vm_bugreport(NULL); }
253+
250254
void Init_witapi(void) {}

packages/npm-packages/ruby-wasm-wasi/src/bindgen/rb-abi-guest.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export class RbAbiGuest {
7979
rbErrinfo(): RbAbiValue;
8080
rbClearErrinfo(): void;
8181
rstringPtr(value: RbAbiValue): string;
82+
rbVmBugreport(): void;
8283
}
8384

8485
export class RbIseq {

packages/npm-packages/ruby-wasm-wasi/src/bindgen/rb-abi-guest.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ export class RbAbiGuest {
158158
this._exports["cabi_post_rstring-ptr"](ret);
159159
return result1;
160160
}
161+
rbVmBugreport() {
162+
this._exports['rb-vm-bugreport: func() -> ()']();
163+
}
161164
}
162165

163166
export class RbIseq {

packages/npm-packages/ruby-wasm-wasi/src/index.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,21 @@ const checkStatusTag = (
471471
}
472472
};
473473

474+
function wrapRbOperation<R>(vm: RubyVM, body: () => R): R {
475+
try {
476+
return body();
477+
} catch (e) {
478+
if (e instanceof WebAssembly.RuntimeError && e.message === "unreachable") {
479+
vm.guest.rbVmBugreport();
480+
const error = new RbError(`Something went wrong in Ruby VM: ${e}`);
481+
error.stack = e.stack;
482+
throw error;
483+
} else {
484+
throw e;
485+
}
486+
}
487+
}
488+
474489
const callRbMethod = (
475490
vm: RubyVM,
476491
privateObject: RubyVMPrivate,
@@ -479,14 +494,18 @@ const callRbMethod = (
479494
args: RbAbi.RbAbiValue[]
480495
) => {
481496
const mid = vm.guest.rbIntern(callee + "\0");
482-
const [value, status] = vm.guest.rbFuncallvProtect(recv, mid, args);
483-
checkStatusTag(status, vm, privateObject);
484-
return value;
497+
return wrapRbOperation(vm, () => {
498+
const [value, status] = vm.guest.rbFuncallvProtect(recv, mid, args);
499+
checkStatusTag(status, vm, privateObject);
500+
return value;
501+
});
485502
};
486503
const evalRbCode = (vm: RubyVM, privateObject: RubyVMPrivate, code: string) => {
487-
const [value, status] = vm.guest.rbEvalStringProtect(code + "\0");
488-
checkStatusTag(status, vm, privateObject);
489-
return new RbValue(value, vm, privateObject);
504+
return wrapRbOperation(vm, () => {
505+
const [value, status] = vm.guest.rbEvalStringProtect(code + "\0");
506+
checkStatusTag(status, vm, privateObject);
507+
return new RbValue(value, vm, privateObject);
508+
});
490509
};
491510

492511
/**

0 commit comments

Comments
 (0)