OK, the source of scariness seems to be in pth_mctx.c which does some
evil-looking things in order to implement userspace threading.

In order to switch threads with an accompanying switch of stack,
setjmp() is called from inside a signal handler which has an alternate
signal stack set up. [1]

eglibc barfs when the corresponding longjmp() from the main thread tries
to jump back into the signal handler after the signal handler returns
(!)  The maintainers claim this is portable within POSIX, but I'm less
than convinced.  POSIX is somewhat vague about the circumstances in
which it's safe to longjmp() out of a signal handler, to say nothing of
what happens on a modern kernel with interruptible system calls etc.
..., and expressly prohibits longjmp'ing back into a function which has
returned. Behaviour for siglongjmp in this situation appears to be
undefined, but my conclusion is that this is not supposed to be
supported either [2]  If so, and if I've understood the implications
correctly, this would invalidate any claim of strict portability in pth.

I haven't read the full rationale [3] but it contains some interesting caveats:
"Even on operating systems which have working POSIX functions, our approach may 
theoretically still not work, because longjmp [...] [may branch] to 
error-handling code if it detects that the caller tries to jump up the stack, 
i.e., into a stack frame which has already returned"

We may be hitting just such a check here.

Notwithstanding this, the contents of the jmp_buf otherwise looks sane
when the failing longjmp call occurs.  See the attached debug log: the
sp and pc values saved in the jmp_buf for pth_mctx_set_trampoline at
pth_mctx.c:394 appear to match those in the jmp_buf passed to longjmp at
pth_mctx.c:362

[1] see http://bazaar.launchpad.net/~ubuntu-
branches/ubuntu/maverick/pth/maverick/annotate/head%3A/pth_mctx.c

[2] See IEEE Std 1003.1-2008 (System Interfaces: longjmp)
http://www.opengroup.org/onlinepubs/9699919799/

"The longjmp() function shall restore the environment saved by the most
recent invocation of setjmp() in the same thread, with the corresponding
jmp_buf argument. If [...] the function containing the invocation of
setjmp() has terminated execution in the interim [...] the behavior is
undefined."

(This specification derives directly from ISO C)

[3] "Portable Multithreading - The Signal Stack Trick For User-Space
Thread Creation", Ralf S. Engelschall: http://bazaar.launchpad.net
/%7Eubuntu-branches/ubuntu/maverick/pth/maverick/annotate/head%3A/rse-
pmt.ps


** Attachment added: "gdb session"
   
https://bugs.launchpad.net/ubuntu/+source/pth/+bug/599862/+attachment/1523038/+files/pth-debug-2.log

-- 
pth_init() aborts on armel with "longjmp causes uninitialized stack frame"
https://bugs.launchpad.net/bugs/599862
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to