WebAssembly / wasi-cli

Command-Line Interface (CLI) World for WASI
63 stars 11 forks source link

Exit statuses #11

Closed sunfishcode closed 2 months ago

sunfishcode commented 1 year ago

Currently the exit status of a command is a result<_, _>, meaning it's a boolean success or failure. That has the advantage that we don't need to think about the meanings of exit statuses across platforms, or hidden conventions between programs and their environments. However, it is more restrictive than the intersection of Unix and Windows, so we should consider supporting this intersection.

I was earlier under the impression that Windows had a convention of using error codes for exit statuses, and it appears some programs do do that, but it's not as common as I initially thought.

So the exit status space looks something like this:

0 = success 1 = generic failure 2 = custom uses in the wild 3 = abort on Windows

...various custom uses in the wild...

???-124 - Perhaps we should reserve some codes here in case Unix reserves them in the future?

125 - container failed to run (Unix) 126 - command not executable (Unix) 127 - command not found (Unix) 128 and up = program exited with signal (Unix) 256 and up = unrepresentable (Unix)

That suggests we should change the type to result<0, u8> and have the runtime trap if the u8 value is:

Open questions:

abrown commented 1 year ago

@sunfishcode, I opened what I think is a similar issue here: https://github.com/WebAssembly/WASI/issues/524. Can you take a look at that one and see if it should be merged here? I'm a 👍 for standardizing the error codes; if we have a consistent set of error codes then testing with wasi-testsuite will get easier.

sunfishcode commented 1 year ago

I'll leave https://github.com/WebAssembly/WASI/issues/524 open to track clarifying this for preview1.

For preview2, I'm now leaning towards saying "anything from [0,255] is permitted". Looking at programs in the real world, there are lots of programs that use values all throughout this range, and there doesn't seem to be a clean place to draw a boundary. So it seems best to just let the ambiguities through and let users figure it out.

yowl commented 1 year ago

I'm now leaning towards saying "anything from [0,255] is permitted"

That works for me 👍

codefromthecrypt commented 1 year ago

I agree that open [0-255] is more pragmatic, though not sure if anyone is taking advantage of the value type allowing larger values. In any case, open avoids a false expectations values will be used consistently.

yamt commented 1 year ago

i guess there are related but separate topics:

a. how wasi exit code looks like b. how to map wasi exit code to the host exit code (or other host concepts)

for a., [0-255] or even full u32 range is fine for me.

IMO, the idea to report wasi exit code via a host exit code is a hack at best. while we can have common conventions for each platforms, (unix, windows, ...) it's inherently platform-dependent. (whatever restrictions you put on the value, once you start thinking of implementing a wasm runtime cli in wasm, you will be in trouble.)

when you really need to know the exact exit code (eg. testsuite) it's probably simpler to use an embedder api like the following directly. https://github.com/bytecodealliance/wasm-micro-runtime/blob/ff0752b4ff5f505186fd7827fb80396e080b9ea7/core/iwasm/include/wasm_export.h#L542-L552 https://github.com/yamt/toywasm/blob/2c31a7cd644afd698536b7066d7d8aa3f9d455aa/libwasi/wasi.h#L12

SingleAccretion commented 3 months ago

With the migration of .NET to WASI P2, we are now hitting this lack of support for exit codes problem (same context as https://github.com/bytecodealliance/wasmtime/issues/6352).

It looks like a significant API gap - exit codes are a pretty old and established way to communicate execution summary back to the system. Indeed, the current API already includes an 'exit code', it's just a boolean-only value.

Exit codes are an application-specific concern (i. e. it is the application that defines what the exit codes mean, example: https://github.com/microsoft/binskim/blob/main/docs/UserGuide.md#--rich-return-code-truefalse), so I don't see the need to attach any specific meanings to any specific values, or reserve any of them. By the same logic, the exit code should be returned as-is from the host to the system for embeddings where the WASM application is the root of execution (i. e. wasmtime myapp.wasm).

dicej commented 2 months ago

FYI, I spoke with @sunfishcode and @lukewagner about this the other day, and we agreed that adding a new exit-with-code: func(code: u8); function to wasi:cli/exit would be appropriate for e.g. WASI 0.2.2. I'll open a PR for that as soon as I've caught up with the state of WIT versioning.