Skip to content

Rewrite signal emulation again - #4858

Draft
kalaposfos13 wants to merge 5 commits into
shadps4-emu:mainfrom
kalaposfos13:all-the-signals
Draft

Rewrite signal emulation again#4858
kalaposfos13 wants to merge 5 commits into
shadps4-emu:mainfrom
kalaposfos13:all-the-signals

Conversation

@kalaposfos13

Copy link
Copy Markdown
Member

VSH has a check that failed under the previous implementation, because it tried to install a handler for every possible signal, of which there are 128 on the PS4, but only 64 and 32 on Linux and macOS, respectively (on Windows, this wasn't an issue because signal code is still mostly stubbed, and the things that aren't, are software emulated anyway). Previously, every guest signal was mapped to a host signal, and then everything was transparently forwarded to the host OS, which worked pretty well up until something actually came along and started using those higher signal numbers not available on host platforms. Since VSH only checked their availibility, but didn't actually make use of them, it was rather easy to just ignore those signals and return dummy successes, but it nonetheless prompted me to rewrite signal emulation on POSIX systems once again.

This PR is a draft for now, because it's only been tested on Linux, and Windows is most likely broken in new and interesting ways on it, so that first has to be fixed, preferably not by me.

The new logic works roughly like so:
Signals can be grouped into two categories, hardware ones that are raised by the host hardware/OS, like SIGSEGV, SIGILL, SIGFPE etc, and there are software ones, that can only come from the guest invoking raise/pthread_kill themselves as an internal signaling mechanism. The first group has a host signal handler installed for them as well, and (after first checking if our HLE was responsible for the signal in cases of SIGSEGV or SIGBUS) the signal and its accompanying info gets forwarded to g_curthread for consumption (if no handler is installed, do the default action which is "crash" for most and "ignore" for some signals, if the thread is in sigwait, wake it, if it's in sigsuspend, call the handler then wake it, otherwise call the handler). For the other set of signals, pthread_kill will first queue the signal on the thread, check if the signal is blocked, and if not, sends a notification to the thread via a host SIGUSR1 signal, whose handler on the other end will inspect its thread's state, and figure out what to do from there (see above, but prepend a signal queue lookup to it with respect to the signal mask). The other sig* functions follow a similar setup as well.

The Pthread backend can be reused for Windows I'm pretty sure, and it might even allow for a better hardware signal emulation as well (just make use of the same backend from Windows's SignalHandler at signals.cpp:29, the only code I know is that 0xc0000005 is the SIGSEGV equivalent), but for now I've kept everything POSIX only because I use Arch Linux (BTW Edition) btw don't use Windows nor do I care about it.

sigaction also had a quite dumb bug that I can't even blame on anyone else because it was me who introduced it months ago, which is that it used the sce wrapper functions' callback function signature instead of the POSIX signature(s), meaning guest apps were getting garbage parameters aside from the signal number itself, which only wasn't found earlier because most games only use the sce wrappers, and those were fine.

Testing would be appreciated, because while I'm pretty sure I didn't break anything (on Linux), one must never be too sure.

This time, use only one host signal as a communication primitive, instead of trying to map host -> guest signals to each other. This allows us to ignore host limits and emulate an arbitrary amount of signals at the cost of more manual bookkeeping. Hardware signals like SIGSEGV or SIGILL have their own logic, but ultimately also slot into the same backend.

i read way more man pages for this than one might think
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.

1 participant