-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Bruno Haible on 6/6/2008 5:29 AM: | The type of the third argument, according to POSIX, is 'void *ucp'. Why does | it have to be cast? Why is it not directly 'ucontext_t *ucp' (since, as you | say, ucontext_t will be defined in <signal.h>)?
I think POSIX is catering to the fact that older platforms (in particular BSD) typed it as 'struct sigcontext *sc' instead. More importantly, ucontext_t is an XSI extension; you can be POSIX compliant but not XSI compliant; in that case, you lack ucontext_t, and the third argument to a sigaction handler must be an unusable void* (which is pretty much what I discovered about OpenBSD 4.0). | |> The receiving thread may currently be in the alternate stack, but |> the signal was delivered when the thread was still in the primary stack. So |> maybe we should file this as a bug with the kernel folks, and hope that a |> future version of Linux change uc_stack to supply the information we want. |> After all, we don't need uc_stack to learn about the current (alternate) stack; |> we can use sigaltstack() for that. | | I think you are misunderstanding things, and there is no Linux kernel bug here. Where would I even go to ask a Linux developer this question? | When a signal S has been specified to execute on the alternate stack (via | SA_ONSTACK), and SA_NODEFER is specified as well, when the signal S occurs a | second time while the first signal occurrence is still being processed, | the stack pointer cannot be set to the top of the alternating stack again - | this room is already in use. So the second time the signal handling must | behave as if there was no alternate stack. This is a semantic difference | between the "context" of the main thread (where alternate signal stacks will | be used when a signal occurs) and the "context" of signal handler (where | alternate signal stacks will be ignored). This is why ucontext_t has a | field 'uc_stack'. I understand that - the ucontext_t of any secondary signals should certainly be the alternate stack, because execution was interrupted while the alternate stack was in use. But I still claim that the _first_ segv interrupted the main stack, and not the alternate stack; and it is the first segv that I'm worried about. | | Whether sigaltstack(), when called during the signal handler, reports the | existence of an alternate stack or not, is irrelevant. What matters, is the | actual behaviour when a nested signal occurs. And how we work around such behavior. | | Some systems (OpenBSD, IRIX, Solaris) store the fact that the alternate stack | is temporarily deactivated as a bit in the kernel. Others (Linux, MacOS X) | determine it by looking whether the current stack pointer is in the range | of the alternate stack. | | The description of 'uc_stack' in http://www.opengroup.org/susv3/basedefs/ucontext.h.html | is so vague that I would not base any program on it. Yet that's exactly what c-stack is trying to do with HAVE_XSI_STACK_OVERFLOW_HEURISTIC. |> At any rate, the current implementation of c-stack precludes any |> detection of non-stack overflow segv's on Linux (at least for the kernel |> versions I was testing), because it claims ALL segvs are stack overflow, |> whether or not that is true. | | Yes. Distinguishing between random SIGSEGV and stack overflow is a feature that | IMO is unique to libsigsegv. So it looks like when libsigsegv is not compiled in, and uc_stack is not reliable, then I'm down to a choice of c-stack's false positives (reporting program bugs as stack overflow) instead of m4's false negatives (reporting stack overflow as a program bug). | |> So c-stack could use a mincore()-like |> capability to quickly determine whether all memory from the page near the fault |> over to the stack location saved at the time the handler was registered is |> currently mapped (whether or not all of those pages are in core) (and |> using /proc/self/maps when that is faster than mincore()). | | I agree with you that c-stack's use of 'uc_stack' is bogus, and on Linux, | FreeBSD, OpenBSD, NetBSD, mincore() will give better results. I guess I'll ask on the Austin group for some more ammunition as to whether uc_stack is intended to be useful (whether or not current kernels populate it with bogus data). - -- Don't work too hard, make some time for fun as well! Eric Blake [EMAIL PROTECTED] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkhJLJwACgkQ84KuGfSFAYARqACgp5xU+ErkqK/+XFdTSoldy5OV GD8An1EhfhaUei83hFXfK0r2wWK6zJgv =tf+C -----END PGP SIGNATURE-----