This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pow() fails with a segmentation fault when executed fromdynamically allocated memory


On Sat, Jan 28, 2012 at 1:21 PM, Carlos O'Donell
<carlos@systemhalted.org> wrote:
> On Sat, Jan 28, 2012 at 4:17 AM, Lars Magnusson <lavima@gmail.com> wrote:
>> Hello
>>
>> I'm having some trouble executing pow() from dynamically allocated
>> memory. The memory is allocated with mmap() and filled with x86-64
>> instructions. This seems to work fine for the most part, but it fails
>> with a segmentation fault when I try to invoke the pow function with x
>> < 0 and y non-integer (which should return NaN).
>>
>> I've reduced the problem down to the following code:
>>
>> double my_pow() {
>> ?printf("test\n");
>> ?double ret = pow(-2.0, 0.5);
>> ?printf("test2\n");
>> ?return ret;
>> }
>>
>> void execute() {
>>
>> ?uint8_t *code = ( uint8_t * ) mmap( NULL, 1024,
>> ? ?PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0 );
>>
>> ?code[0] = 0x49; code[1] = 0xbb;
>>
>> ?uint64_t addr = (uint64_t)&my_pow;
>> ?code[2] = addr % 0x100; code[3] = (addr % 0x10000) >> 8;
>> ?code[4] = (addr % 0x1000000) >> 16; code[5] = (addr % 0x100000000) >> 24;
>> ?code[6] = (addr % 0x10000000000) >> 32; code[7] = (addr %
>> 0x1000000000000) >> 40;
>> ?code[8] = (addr % 0x100000000000000) >> 48; code[9] = addr >> 56;
>>
>> ?code[10] = 0x41; code[11] = 0xff; code[12] = 0xd3; code[13] = 0xc3;
>>
>> ?double (*fun)(void) = (double (*)(void))code;
>>
>> ?printf("Result: %f\n", my_pow());
>> ?printf("Result: %f\n", fun());
>> }
>>
>> The normal invocation of my_pow works fine, but it fails with
>> segmentation fault from the the dynamic code on my machine with glibc
>> version 2.13. The code executes without trouble in both instances on
>> an older system with version 2.5 of glibc.
>>
>> My initial thought was that this was a kernel issues (which also
>> differs between the systems), but I wanted to hear what you think
>> before moving on.
>
> IIUC you have a code trampoline in dynamically allocated memory
> which calls my_pow() and somtimes it segfaults?
>
> Rather than making me decode the trampoline by hand, could you
> please provide the assembly instructions for the trampoline?
>
> Is there any reason you wrote the trampoline out by hand?
>
> My preference would have been to write the trampoline in C,
> let the compiler compile it, dynamically allocate the memory,
> and then memcpy the trampoline into place. The alternative
> being: compile the trampoline from an assembly file which has
> two symbols that mark the start and the end of the trampoline.
> In either case you get the benefit of the assembler which will
> double check your encoding and warn you if you made a mistake.
> If you use a C compiler it's even better because you then are
> assured you didn't make a procedure-call error.
>
> Cheers,
> Carlos.

Thanks for the reply.

The code is just for testing. The real situation is that we have a
system that generates millions of different programs in ML, which then
is compiled into assembly by a custom lightweight compiler. I can
provide you with more details if necessary.

The assembly is:
mov r11, address of my_pow
call r11
ret

The code always fails with a segmentation fault on my machine (ubuntu
11.10 with glibc 2.13), but it always work on an older one (glibc
2.5). It fails with the call to pow(-2.0, 0.5) i.e. the call to my_pow
is successful in both cases.

-Lars


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]