dc hitting a compiler bug, or undefined behavior
Rich Felker
dalias at aerifal.cx
Thu Apr 3 01:19:29 UTC 2014
On Mon, Mar 31, 2014 at 02:17:33PM +0200, Denys Vlasenko wrote:
> On Sun, Mar 30, 2014 at 11:18 AM, Lauri Kasanen <curaga at operamail.com> wrote:
> > Hi,
> >
> > I'm seeing busybox dc acting funny when compiled with some versions of
> > gcc. This is on busybox git. The x86 binary busybox_unstripped and
> > config are attached.
> >
> > gcc 4.2.2 - ok
> > gcc 4.7.2:
> > nc 10 1 add p
> > 2.738e+93
> >
> > So either bb is hitting a compiler bug,
>
> Looks like a compiler bug:
>
> d = strtod(argument, &end);
> if (end != argument && *end == '\0') {
> push(d);
>
> is compiled to this:
>
> 0x08049490 <+27>: call 0x80488b0 <strtod at plt>
> 0x08049495 <+32>: mov -0x14(%ebp),%eax
> 0x08049498 <+35>: pop %ecx
> 0x08049499 <+36>: pop %ebx
> 0x0804949a <+37>: cmp %esi,%eax
> 0x0804949c <+39>: je 0x80494b1 <stack_machine+60>
> 0x0804949e <+41>: cmpb $0x0,(%eax)
> 0x080494a1 <+44>: jne 0x80494b5 <stack_machine+64>
> 0x080494a3 <+46>: push %eax
> 0x080494a4 <+47>: push %eax
> 0x080494a5 <+48>: fstpl (%esp) <============ HERE
> 0x080494a8 <+51>: call 0x8048f10 <push>
>
> Note how push(double a) argument gets passed on stack.
> But push() starts with this:
>
> Dump of assembler code for function push:
> => 0x08048f10 <+0>: fldl (%edi)
>
> which reads argument from some bogus location instead
> of stack:
>
> (gdb) nexti <=========== EXECUTE fldl
> 0x08048f12 in push ()
> (gdb) p $st0
> $1 = 2.0554264135011661055418432229752339e-314
>
> That's not 10!
> 10 exists on stack all right:
>
> (gdb) p *(double*)($esp+4)
> $5 = 10
>
> the program just doesn't fetch it correctly.
It really looks to me like some non-default optimization is going on
and misbehaving. I've never seen gcc emit this kind of 'bare' function
without prologue/epilogue (or in this case, the ugly prologue moved
inside the conditional just before the function call). Is the busybox
build system doing anything behind the scenes (or perhaps with #pragma
or hidden attribte tags?) to get gcc to adjust the calling convention
for some functions?
Rich
More information about the busybox
mailing list