Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Problems with packages on a netbsd-6 sparc



On Wed, 2 May 2012, Chris Ross wrote:

> On 05/02/2012 04:34 AM, Martin Husemann wrote:
> > Most likely a sudo bug, compile it with "-g -O2" and check the core.
> 
>   Is it really a bug in sudo if the non-optimized code works, but the
> optimized code causes a crash?
> 
>   Looking at it in gdb it certainly looks like a mis-aligned access.  But, I'm
> not sure what "<optimized out>" means.
> 
> Program received signal SIGBUS, Bus error.
> 0x00024e24 in make_pwitem (pw=0x204a7aa8, name=0x0) at ./pwutil.c:178
> 178         memcpy(newpw, pw, sizeof(struct passwd));
> (gdb) print newpw
> $1 = <optimized out>
> (gdb) print pw
> $2 = (const struct passwd *) 0x204a7aa8
> (gdb)
> 
> 
>   I'll take a look at the code directly, but I still don't understand how it
> could be a code bug, rather than an optimizer bug, that only shows when code
> is optimized.

Did it really die in "memcpy()"?

It may be an optimization bug... sortof.

The gcc optimizer will sometimes inline memcpy() instead of calling the 
real thing if it thinks it can do a better job.  In this case it probably 
thinks it knows the size of the copy and makes the assumption that both 
the source and destination are properly aligned so it can generate code 
that looks sorta like this:

        for (i=0; i<sizeof(struct passwd)/sizeof(long); i++)
                ((long *)&newpw)[i] = ((long *)&pw)[i];

Of course if one of those buffers happens to be unaligned, things go boom.
And if you turn off optimization it calls the real memcpy() which does all 
sorts of fancy things like check for unaligned buffers and DTRT.  

Most likely the code is actually buggy in the sense that it passes in an 
unaligned buffer and assigns it to a "struct passwd *" variable, something 
that according to the C standard I believe is undefined.  It's also 
something that the optimizer can't really know about.

I think all you need to do is give gcc the parameter to tell it to turn 
off the inlined memcpy() support, something like "-mno-memcpy".

Eduardo


Home | Main Index | Thread Index | Old Index