[uClibc] brk, mmap and unwinding in uclibc

Erik Andersen andersen at codepoet.org
Fri May 14 20:15:03 UTC 2004


On Fri May 14, 2004 at 09:03:40PM +0200, Peter S. Mazinger wrote:
> Hello!
> 
> I have tried to build upx (a compressor) against uclibc, and had some 
> discussions w/ the developers of upx. Here are their relevant comments:
> 
> part1:
> I created a synthetic testcase 'short.c' [attached], and built it.
> 
> The required datafile 'empty' is created by:
> 	dd if=/dev/zero bs=45424 count=1 > empty
> Finally, I ran
> 	LD_LIBRARY_PATH=. ./short

Why are you messing with LD_LIBRARY_PATH?

> On a kernel-2.4.20-28.9 system, running the 'short' example always works;
> the output is "39992\n".  But on a kernel-2.6.5 system that uses
> exec-shield-randomize, it aborts with SIGSEGV about 25% to 30% of the time.
> Turning off exec-shield-randomize on the same kernel-2.6.5-1.358 system
> enables the 'short' testcase to work 100% of the time.  This behavior
> indicates that uClibc cannot handle the random placement of mmap()
> that the kernel uses when exec-shield-randomize is 1.  Also, I suspect
> that there may be a problem with the uClibc implementation of brk()
> under exec-shield-randomize.


Your example (after fixing up a few obvious things like the main
prototype, casting the printf arguments to match the conversion
specifier, including stdio.h, etc) outputs "39992\n" with uClibc
with stock 2.4.26 and 2.6.6 kernels.

As has been discussed several times, uClibc does not presently
support exec-shield-randomize stuff.  As you are the only person
I am presently aware of that is using uClibc in this way, the
burden for adding support for this stuff lies with you...  Thus
far, it is pretty clear you have not managed to interest any of
the uClibc maintainers in researching this stuff and adding
support for this.  Repeatedly posting the details of your
favorite unsupported feature is guaranteed to not help much.

> part2:
> > Under glibc running upx against an already packed file exits w/ code 2, on 
> > uclibc it gets signal 6, coredumps (and the protection in my kernel 
> > catches this, exits w/ 134), the kernel is although the same
> 
> There are signs of an incompatibility between uClibc startup code
> and libgcc_s 'throw'.  Under glibc, trying to pack a file that is
> already packed gets a message on stderr:
> 	upx: date: AlreadyPackedException: already packed by UPX
> This occurs as a result of throwing a C++ exception with a constructor
> that takes a  char *  argument.  The exceptions are caught, the message
> is printed, and then exit(2).
> 
> I tried packing an already-packed executable using upx with uClibc.
> I saw no message on stderr, did see the kill() that results from
> not finding the right catcher, and the traceback was:
[----------snip-----------]
> So, the throw+catch are not hooking up properly under uClibc.
> This is uClibc's problem.

What version of uClibc?  gcc?  binutils?  How did you build your
toolchain?  Was gcc built with --enable-sjlj-exceptions?  What
kernel version are you using?

> part3:
> comment on gdb #5: __cxa_throw ()
> >From the backtrace above it looks that somethings goes wrong during stack 
> unwinding - does exception catching work for other C++ programs ?

It does if gcc was built properly...

    http://codepoet.org/throw1.cpp
    http://codepoet.org/throw2.cpp

# g++ -Wall -O2 throw1.cpp -o throw1
# ldd ./throw1
        libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40007000)
        libm.so.0 => /lib/libm.so.0 (0x40075000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x40083000)
        libc.so.0 => /lib/libc.so.0 (0x4008a000)
        ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x40000000)
# ./throw1
caught an exception

# g++ -Wall -O2 throw2.cpp -o throw2
# ldd ./throw2
        libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40007000)
        libm.so.0 => /lib/libm.so.0 (0x40075000)
        libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x40083000)
        libc.so.0 => /lib/libc.so.0 (0x4008a000)
        ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x40000000)
# ./throw2
1  Throwing out_of_range()
    Catching: out_of_range out_of_range meaningful comment
2  Throwing exception()   // Can't specify comment
    Catching: St9exception
3  Throwing underflow_error  // caught by base class
(runtime_error)
    Catching: runtime_error underflow_error
4  Throwing runtime_error
    Catching: runtime_error a comment
5  Throwing length_error   // caught be super-super-class
(exception)
    Catching: St9exception
6  Throwing int
    Catching: int 26
7  Throwing const char*
    Catching: const char* This is a const char*
8  Throwing string
    Catching: string I'm a string
9  Throwing float
    ERROR: Nobody caught this!
10  Throwing up

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--



More information about the uClibc mailing list