tail-call icon indicating copy to clipboard operation
tail-call copied to clipboard

Stack trace associated with failing return_call_indirect

Open yurydelendik opened this issue 2 years ago • 11 comments

Currently there are no strict requirements for produced stack in the ~~WebAssembly.Exception~~ Error. I wonder what will be expected stack trace for the return calls.

SpiderMonkey implementation of call_indirect checks the function signature at the callee side. Information about originating call site will be lost. The trap handler has no association of the trap code and its source/origin, so we are planning to start stack trace from the previous frame, or keep it empty if there are no other frames.

The https://github.com/WebAssembly/tail-call/blob/main/proposals/tail-call/Overview.md#execution-1 has no instructions on the subject.

yurydelendik avatar Feb 28 '23 19:02 yurydelendik

Yes. Technically, since EH is earlier in the standard cycle than tail call, that proposal should address this question. A related issue is what happens when you return_call in a try block. We did discuss that question, and the answer was that the semantics of a return_call is that you first of all 'return' and then 'call' the new function. (I.e., exceptions coming out of a return_called function in a try block are not expected to be caught in that try block. I suspect the same resolution will apply to traps.

fgmccabe avatar Feb 28 '23 19:02 fgmccabe

exceptions coming out of a return_called function in a try block are not expected to be caught in that try block

Just to narrow down the issue, let's scope this only to return_call_indirect and its calling with incorrect signature. The same will apply to return_call_ref.

yurydelendik avatar Feb 28 '23 20:02 yurydelendik

In general, traps are not catchable by wasm code.

fgmccabe avatar Feb 28 '23 21:02 fgmccabe

In general, traps are not catchable by wasm code.

That's correct.

I'm asking about content of the stack property for the ~~WebAssembly.Exception~~ WebAssembly.RuntimeError JS object.

yurydelendik avatar Feb 28 '23 21:02 yurydelendik

This should be pursued on the EH repo: https://github.com/WebAssembly/exception-handling

fgmccabe avatar Feb 28 '23 21:02 fgmccabe

(Sorry, changed the JS object name -- it is just regular JS Error since it is just trap) Not sure it is related to EH

yurydelendik avatar Feb 28 '23 22:02 yurydelendik

In V8 we check the signature from the caller, so if there is a signature mismatch during an return_call_indirect instruction, the caller does appear in the stack trace.

thibaudmichaud avatar Feb 28 '23 22:02 thibaudmichaud

Wizard also checks the signature before unwinding the caller frame. Off the top of my head, callee-side checking can still be accomplished if the callee is also responsible for retracting the machine stack pointer and the caller does save the calling address somewhere. (Perhaps using an actual machine call that retracts the caller frame and discards the return address).

titzer avatar Mar 01 '23 01:03 titzer

Off the top of my head, callee-side checking can still be accomplished if the callee is also responsible for retracting the machine stack pointer and the caller does save the calling address somewhere.

Yes, this is a backup plan. It will be really nice to not reserve a register and instructions to pass the caller callsite ID.

Is this functionality really expected/needed from users point of view? I can read into execution overview both ways.

yurydelendik avatar Mar 01 '23 13:03 yurydelendik

The spec text is not ambiguous about the order of operations: https://webassembly.github.io/tail-call/core/exec/instructions.html#xref-syntax-instructions-syntax-instr-control-mathsf-return-call-indirect-x The signature check happens before the indirect call, so I would expect the tail-caller to be the topmost item of the stack trace. It also seems nicer from the perspective of a user trying to debug where the trap comes from. But this is just my biased opinion, the spec doesn't have requirements for the stack property AFAIK.

thibaudmichaud avatar Mar 01 '23 14:03 thibaudmichaud

Indeed, the spec does not care either way. Since stack traces are only observable in JS, the core Wasm spec is agnostic to them. But even JS does not specify stack traces. So it's up to implementations.

Personally, I'd find having the call site, before unwinding the stack, as the origin more natural. Conceptually, it is the [return_]call_indirect instruction performing the type check, not the callee.

rossberg avatar Mar 01 '23 14:03 rossberg