Skip to content

Implement default signal handlers #20257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 15, 2023
Merged

Implement default signal handlers #20257

merged 8 commits into from
Sep 15, 2023

Conversation

RReverser
Copy link
Collaborator

@RReverser RReverser commented Sep 14, 2023

This implements best-effort attempt to implement default signal handlers as per https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html:

  • Terminate action is mapped to _Exit aka wasi_proc_exit - variant of exit that doesn't run atexit handlers. Exit code is set to 128 + sig like it is on other platforms.
  • Abort action (terminate with core dump) is mapped to __builtin_trap aka Wasm unreachable instruction.
  • Process pause/continue actions are ignored as it's unclear what that would do in Wasm (maybe use Asyncify in the future?).

Fixes #20254.

@RReverser RReverser requested a review from sbc100 September 14, 2023 21:19
@RReverser
Copy link
Collaborator Author

@sbc100 Are there any tests from POSIX test suite we could reuse here or do I need to implement my own?

@sbc100
Copy link
Collaborator

sbc100 commented Sep 14, 2023

@sbc100 Are there any tests from POSIX test suite we could reuse here or do I need to implement my own?

Except for the pthreads tests we have been writing out own. (we also write our own pthreads tests in addition to the posttest suite ones).

@sbc100
Copy link
Collaborator

sbc100 commented Sep 14, 2023

I think you can/should just extend the existing test/test_signals.c

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! lgtm with test

@RReverser
Copy link
Collaborator Author

I think you can/should just extend the existing test/test_signals.c

I don't think that will work since it's being executed as a core test and the program is expected to finish. Whereas here we want kinda the opposite - to test that it exits abnormally.

@RReverser
Copy link
Collaborator Author

OTOH... it does verify output, so maybe.

@sbc100
Copy link
Collaborator

sbc100 commented Sep 14, 2023

OTOH... it does verify output, so maybe.

You can also death tests using assert_returncode=NON_ZERO if you want.

@RReverser
Copy link
Collaborator Author

Yeah it just gets a bit more complicated if I want to test several signals (one for abort, one for terminate behaviour)... I could do that via argument parsing but I think I'd better add a separate test instead.

@RReverser
Copy link
Collaborator Author

Heh looks like it caught a test that assumed SIGUSR1 will do nothing. I'll change it to SIGCHLD which is ignored per spec.

@RReverser
Copy link
Collaborator Author

RReverser commented Sep 14, 2023

Just realised that this is not fully correct approach. It should instead implement WASI's proc_raise so that it's compatible both with this emulated approach and with standalone engines.

I think I'll just wrap it into #ifndef EMSCRIPTEN_STANDALONE_WASM for now right in the C code + add alternative branch.

@RReverser
Copy link
Collaborator Author

Hm #ifndef EMSCRIPTEN_STANDALONE_WASM code seems to get compiled even when using -s PURE_WASI or -s STANDALONE_WASM... Do I need another ifdef?

@RReverser
Copy link
Collaborator Author

Oh I see, looks like libc is not built separately for standalone Wasm as it expects that WASI will be implemented only in JS? I guess I can move this implementation into JS, but seems unfortunate...

@sbc100
Copy link
Collaborator

sbc100 commented Sep 14, 2023

Why don't you ignore the standalone wasm stuff for now and just land this without that support. We can try to move to an external proc_raise as a followup maybe?

@RReverser
Copy link
Collaborator Author

I guess I could do that. It's just that when I noticed that CI error I decided to test my tests in standalone Wasm mode as well and it was a rabbit hole.

That said, I'm almost done - but now noticed that Wasmtime doesn't support proc_raise yet so I'll have to disable it as a runner anyway 😅

@sbc100
Copy link
Collaborator

sbc100 commented Sep 15, 2023

I guess I could do that. It's just that when I noticed that CI error I decided to test my tests in standalone Wasm mode as well and it was a rabbit hole.

That said, I'm almost done - but now noticed that Wasmtime doesn't support proc_raise yet so I'll have to disable it as a runner anyway 😅

We use an old/pinned version of wasmtime in CI .. it might already be fixed.

That being said, I'd prefer to land the smaller/simpler version of this change first, is possible.

@RReverser
Copy link
Collaborator Author

We use an old/pinned version of wasmtime in CI .. it might already be fixed.

No, I already checked Github.

That being said, I'd prefer to land the smaller/simpler version of this change first, is possible.

I could revert the JS change I guess... It just seemed better to do this the right way from the start rather than have to rewrite later.

The only complicated addition is that I also added all the signal codes to generated struct info. I needed this for the --js-library anyway and was planning to send as a PR, but now that it's needed by proc_raise implementation too, might as well kill two birds with one stone.

@RReverser
Copy link
Collaborator Author

RReverser commented Sep 15, 2023

Ah interesting... apparently they want to remove proc_raise from WASI? Weird but okay. I guess in that case it's better to revert to C implementation after all... bytecodealliance/wasmtime#420

Or should we keep it? What do you think?

@RReverser
Copy link
Collaborator Author

One benefit of the new implementation is that it uses abort with strsignal and can print a nice message. But otherwise I don't care either way.

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. lgtm!

I wonder if there is an open bug for wasmtime? Seems odd they wouldn't support it.

@sbc100
Copy link
Collaborator

sbc100 commented Sep 15, 2023

Run test_gen_struct_info --rebase to regenerate the struct info files.

@RReverser
Copy link
Collaborator Author

I wonder if there is an open bug for wasmtime? Seems odd they wouldn't support it.

See the link above - apparently they didn't implement it because it didn't make sense and they want to remove it from WASI at some point in the future instead. But I don't get it - for this scenario (invoking default handler) it seems to make perfect sense IMO.

Run test_gen_struct_info --rebase to regenerate the struct info files.

Oh, weird that it worked locally but fails on CI. Will try.

@RReverser
Copy link
Collaborator Author

I don't see test_gen_struct_info. Did you mean tools/gen_struct_info? If so, I did run it.

@sbc100
Copy link
Collaborator

sbc100 commented Sep 15, 2023

I wonder if there is an open bug for wasmtime? Seems odd they wouldn't support it.

See the link above - apparently they didn't implement it because it didn't make sense and they want to remove it from WASI at some point in the future instead. But I don't get it - for this scenario (invoking default handler) it seems to make perfect sense IMO.

Right, but you might as well implement it in wasm though, right? I don't see any advantage to having the host do it.. is there one?

Run test_gen_struct_info --rebase to regenerate the struct info files.

Oh, weird that it worked locally but fails on CI. Will try.

@sbc100
Copy link
Collaborator

sbc100 commented Sep 15, 2023

I don't see test_gen_struct_info. Did you mean tools/gen_struct_info? If so, I did run it.

Sorry ./test/runner other.test_gen_struct_info --rebase

@RReverser
Copy link
Collaborator Author

RReverser commented Sep 15, 2023

Right, but you might as well implement it in wasm though, right? I don't see any advantage to having the host do it.. is there one?

In this particular case I wanted to do it in the host because Wasmtime prohibits from exiting with exit code >127. And signals are supposed to exit with 128+sig like I did in my implementation, so my test failed when executed in Wasmtime.

I thought, okay, then I'll use proper WASI method for that, I assume proc_raise will set the correct exit code while also making my implementation simpler for standalone case... but nope, because proc_raise is not implemented altogether.

Turned out to be waste of time, one way or another if we want to support Wasmtime, we'll have to change exit code just for them.

@RReverser
Copy link
Collaborator Author

But yeah, to your general question, if Wasmtime didn't prohibit such exit codes, I think implementing in Wasm would be fully analogous.

@RReverser RReverser force-pushed the default-signal-handelrs branch from 558785d to 8fba77e Compare September 15, 2023 00:45
@sbc100 sbc100 enabled auto-merge (squash) September 15, 2023 00:49
@RReverser
Copy link
Collaborator Author

I reverted to non-JS implementation to keep things simple; I'll submit the cDefs thing as a separate PR.

@sbc100
Copy link
Collaborator

sbc100 commented Sep 15, 2023

Awesome! Thanks

This implements best-effort attempt to implement default signal handlers as per https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html:
 - Terminate action is mapped to `_Exit` aka `wasi_proc_exit` - variant of exit that doesn't run `atexit` handlers.
 - Abort action (terminate with core dump) is mapped to `__builtin_trap` aka Wasm `unreachable` instruction.
 - Process pause/continue actions are ignored as it's unclear what that would do in Wasm (maybe use Asyncify in the future?).

Fixes #20254.
SIGTRAP is not available on Windows.
@RReverser RReverser force-pushed the default-signal-handelrs branch from b6201e7 to 89166d1 Compare September 15, 2023 11:22
Deleted during rebase?
@RReverser
Copy link
Collaborator Author

Sigh, anotyer failing test. This was supposed to be a trivial PR 😂

@sbc100
Copy link
Collaborator

sbc100 commented Sep 15, 2023

The test_pthread_proxying_refcount is a known flake

@RReverser
Copy link
Collaborator Author

More unrelated tests failing. @sbc100 can you please force-merge it for me?

@sbc100 sbc100 disabled auto-merge September 15, 2023 17:29
@sbc100
Copy link
Collaborator

sbc100 commented Sep 15, 2023

Yup.. I have fixed for the current failures: #20263

@sbc100 sbc100 merged commit aab180a into main Sep 15, 2023
@sbc100 sbc100 deleted the default-signal-handelrs branch September 15, 2023 17:30
@kripken
Copy link
Member

kripken commented Sep 18, 2023

@sbc100
Copy link
Collaborator

sbc100 commented Sep 18, 2023

Fix in flight here: #20272

@kripken
Copy link
Member

kripken commented Sep 18, 2023

Thanks for the quick fix!

Any idea how this passed the initial chromium roll, btw? That's really mysterious... it's like chromium CI ran the wrong checkout for the tests. cc @dschuff

@sbc100
Copy link
Collaborator

sbc100 commented Sep 19, 2023

Its very odd that the try job succeeded yes. Try job only runs 907 tests but the normal runner runs 909 tests in core0. Very odd

@sbc100
Copy link
Collaborator

sbc100 commented Sep 19, 2023

The trybot does seem to sync the correct emscripten rev:

https://logs.chromium.org/logs/emscripten-releases/buildbucket/cr-buildbucket/8769867725819477137/+/u/bot_update/stdout

_____ emscripten-releases\emscripten at aab180a72739c4865d3e9b4c4403991f45b5f572

aab180a is Implement default signal handlers (#20257)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Set up default signal handlers
3 participants