Messages in this thread | | | From | Stas Sergeev <> | Subject | sigaltstack breaks swapcontext() | Date | Wed, 6 Jan 2016 18:45:37 +0300 |
| |
Hello.
swapcontext() can be used with signal handlers, it swaps the signal masks together with the other parts of the context. Unfortunately, linux implements the sigaltstack() in a way that makes it impossible to use with swapcontext(). Per the man page, sigaltstack is allowed to return EPERM if the process is altering its sigaltstack while running on sigaltstack. This is likely needed to consistently return oss->ss_flags, that indicates whether the process is being on sigaltstack or not. Unfortunately, linux takes that permission to return EPERM too literally: it returns EPERM even if you don't want to change to another sigaltstack, but only want to disable sigaltstack with SS_DISABLE. To my reading of a man page, this is not a desired behaviour. Moreover, you can't use swapcontext() without disabling sigaltstack first, or the stack will be re-used and overwritten by a subsequent signal.
The work-around from this, is not even trivial: I have to use the shm tricks to duplicate the sigaltstack in the VA space, and move the stack pointer to another mirror before calling sigaltstack. Then I use longjmp() to restore the stack pointer. Then I can finally use swapcontext(). This is an unpleasant work-around.
The fix on a kernel side looks simple: kernel should just use ss_flags to determine whether the sigaltstack is active. I can make a patch for that, but the problem is that the arch-specific code is not using any helper function to check for sigaltstack; instead it just uses "if (ss_size)" checks. So the patch will need to update all arches... I wonder if maybe someone can fix that problem and update the arch-specific code. If not, I'll probably need to update only the x86-specific code and add an arch-specific define, which is a bit nasty.
Any suggestions?
| |