Re: [rvm-research] Potential issues with longjmp in bootImageRunner

Erik Brangs <[email protected]>
Newsgroups gmane.comp.java.jikes.rvm.devel
Message-ID <[email protected]>
Hi,

On 10.04.2013 18:05, Carl Ritson wrote:
> In bootImageRunner/sys.C, the function sysThreadTerminate() uses
> longjmp() to return from the VM stack to the thread stack at thread
> termination.
> 
> In recent versions of glibc, longjmp() passes through a checking
> function __longjmp_chk() which attempts to ensure that the jump is to
> a valid stack frame.  It does this by asserting that the new stack
> pointer is either greater than then current one, or contained on the
> alternate signal stack.  As stacks grow downward (on x86 at least),
> this ensures that longjmp() only ever unwinds the stack.  This
> assertion is obviously flawed when an separately allocated stack is
> used, such as in JikesRVM.
> 
> On a modern Linux kernel mmap() allocates memory top-down, so
> successive allocations (tend to) fall on lower addresses.  Thus in
> practice thread stacks are higher in memory than VM stacks, so the
> __longjmp_chk() assertion succeeds.  However, a legacy mode of
> bottom-up allocation is also supported, this can be activated by
> setting the process personality (e.g. setarch -L) or having an
> unlimited stack size in the process resource limits (e.g. ulimit -s
> unlimited).  The second of these is obscure, but it what resulted in
> my discovery of this issue.
> 
> In bottom-up mode thread stacks are allocated below the VM memory area
> (at least on x86_64 32-bit mode), and hence __longjmp_chk fails.
> For JikesRVM in production configuration on x86_64-linux the error
> looks like the following (produced from DaCapo 2006 eclipse, on Ubuntu
> 12.04 LTS):
> 
> *** longjmp causes uninitialized stack frame ***:
> dist/gc/production/JikesRVM terminated
> ======= Backtrace: =========
> /lib32/libc.so.6(__fortify_fail+0x45)[0x557e0675]
> /lib32/libc.so.6(+0x1035ca)[0x557e05ca]
> /lib32/libc.so.6(__longjmp_chk+0x4b)[0x557e053b]
> dist/gc/production/JikesRVM(sysLongDivide+0x0)[0x804e68b]
> [0x64707099]

thanks for the bug report. This seems to be the same problem that
Kathiravelu Pradeeban mentioned a few days ago.

On my Ubuntu 12.10 x64 machine, using "ulimit -s unlimited" does not
seem to cause the problem (I already had it set to unlimited) but I was
able to reproduce the problem using "setarch x86_64 -L".

Moreover, it seems that the problem is related to another problem with
longjmp that I have on a PPC-32 machine: applying your patch also fixes
that problem. For the PPC problem, I don't get a backtrace at all and
the crash happens in sysThreadTerminate(). Interestingly, the PPC
problem disappears when compiling the bootimage runner without
optimizations (i.e. -O0 instead of -O in the appropriate file in
build/hosts). Is that also the case for the problem on your machine?

> There are a number of approaches to dealing with this:
>  1. assume allocation will always be top-down and ignore,
>  2. explicitly allocate thread stacks (these can be passed to pthread_create),
>  3. replace use of setjmp/longjmp with savecontext/swapcontext
> (although these are deprecated in POSIX),
>  4. implement a local version of longjmp without a check,
>  5. bypass the __longjmp_chk by using glibc's internal __libc_longjmp().
> 
> Disregarding (1), (5) is the smallest change set.

I'd also disregard (1). (3) and (4) don't seem attractive to me; we
ought to rely on non-deprecated methods from the system libraries as
much as possible.

>From your remarks, I gather that the problem is on our side and not
related to some limitation in the longjmp check in glibc.

If there's a way to fix our code without having to resort to using
internal (i.e. non-api) functions, I'd prefer that way, even if it's a
larger diff and/or more risky change. The code in sys.C hasn't seen any
real changes for quite some time and is in need of refactoring anyway.
(There are some refactorings in the code of the Metacircular Research
Platform but we haven't gotten around to pulling them yet.)

That said, my C is really rusty so I probably won't be providing related
patches in the near future.

I've created a tracking bug at https://jira.codehaus.org/browse/RVM-1027
(it only points to this thread).


Kind regards,

Erik Brangs

------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.