Subject: Re: kern/26661: bug in VM causes segfaul
To: Manuel Bouyer <bouyer@antioche.lip6.fr>
From: Christoph Egger <Christoph_Egger@gmx.de>
List: netbsd-bugs
Date: 08/15/2004 23:13:54
> On Sat, Aug 14, 2004 at 12:51:06PM +0000, Christoph_Egger@gmx.de wrote:
> > Hi!
> > 
> > 
> > All applications that do the following crashes on the sparc64
> > port (I don't know, if the crash happens on other ports, too):
> > 
> > 
> > #include <stdio.h>
> > 
> > 
> > struct foo_t {
> >         int a;
> >         unsigned char buf[8192];
> > };
> > 
> > struct bar_t {
> >         int i1;
> >         int i2;
> > 
> >         double d1;
> >         double d2;
> > };
> > 
> > 
> > int main(void)
> > {
> >         int a = 0;
> >         struct foo_t f;
> >         struct bar_t *b;
> > 
> >         memset(&f, 0, sizeof(f));
> >         f.buf[2] = 2;
> > 
> >         b = (struct bar_t *)(f.buf + 2);
> >         a = b->i2;  // <-- accessing b causes segfault
> > 
> >         printf("a: %i\n", a);
> >         return 0;
> > }
> > 
> > 
> > I have tested it on other OS's (Darwin/ppc32, Solaris/sparc64)
> > and this small app does NOT crash there.
> 
> This is not a bug in the VM, it's a bug in your program. When you do
>          b = (struct bar_t *)(f.buf + 2);
> b is not 32-bits-aligned, and this will cause a trap on sparc64.
> testing on ppc32 is irrelevant, because alignement issues are
> architecture-dependants.
> To understand how it works on Solaris/sparc64 you should look closely at
> what is happening, because on solaris the kernel may emulate this 
> instruction by itself (as NetSD does on the alpha).
> It may also be the compiler optimising this differently, or detecting
> that the access won't be aligigned and correcting this by itself.
> 
> In any cases, doing such nonaligned access is non-portable and should not
> be used.

I have found a solution with memcpy(). The working main() routine
is this:

int main(void)
{
        int a = 0;
        struct foo_t f;
        struct bar_t b;

        memset(&f, 0, sizeof(f));
        f.buf[2] = 2;
 
        memcpy(&b, (struct bar_t *)(f.buf + 2), sizeof(b));
        a = b->i2;
 
        printf("a: %i\n", a);
        return 0;
}

-- 
CU,

Christoph Egger
E-Mail: Christoph_Egger@gmx.de

NEU: WLAN-Router für 0,- EUR* - auch für DSL-Wechsler!
GMX DSL = supergünstig & kabellos http://www.gmx.net/de/go/dsl