Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 5 May 2013 09:37:48 -0700
From:      Tim Kientzle <tim@kientzle.com>
To:        Andrew Turner <andrew@fubar.geek.nz>
Cc:        freebsd-arm@freebsd.org
Subject:   Re: Is this related to the general panic discussed in freebsd-current?
Message-ID:  <D0B02568-E7AB-410E-8717-E9F9C745E6ED@kientzle.com>
In-Reply-To: <20130505140006.0d671ba5@bender>
References:  <51835891.4050409@thieprojects.ch> <03971BD1-4ADE-4435-BDD0-B94B62634F1D@bsdimp.com> <5183BF8C.4040406@thieprojects.ch> <CCABA43A-6D7E-4310-9F68-AEE54C88F431@kientzle.com> <6D0E82C9-79D1-4804-9B39-3440F99AA8FE@kientzle.com> <20130505140006.0d671ba5@bender>

next in thread | previous in thread | raw e-mail | index | archive | help

On May 5, 2013, at 6:00 AM, Andrew Turner wrote:

> On Sat, 4 May 2013 15:44:37 -0700
> Tim Kientzle <tim@kientzle.com> wrote:
>> I'm baffled.  If I insert a printf into the loop in stack_capture,
>> the kernel boots. But the generated assembly looks perfectly correct
>> to me in either case.  So inserting the printf must have some
>> side-effect.
>>=20
>> The stack does end up aligned differently:  The failing version puts
>> 16 bytes on the stack, the working version puts 24 bytes.  But I
>> can't figure out how that would explain what I'm seeing...
>=20
> It feels like an alignment issue but those stack sizes should both be
> valid. Are you able to send me the asm for the working and broken
> versions of the function?
>=20
> Also which ABI are you using? I have not been able to reproduce it =
with
> EABI, but that may have been because I have a patched clang I've been
> using to track down another issue.

I'm using whatever the default is in FreeBSD-CURRENT.  I've seen
this consistently with both RaspberryPi and BeagleBone kernels
for the last few weeks.

The disassembly is below.  The interleaved C is my attempt to
reverse-engineer the assembly into C syntax, which is why it's
not quite the same as the code in sys/arm/arm/stack_machdep.c.

The working version adds=20
                printf("%s: frame=3D%p\n", __func__, frame);=20
just before the !INKERNEL(frame) check.

If you see anything actually wrong with the "Broken version",
I'm very curious.  I spent much of yesterday afternoon staring
at it and cannot for the life of me see a problem with it.

I have experimented with other variations on the C code and
have found a bunch of other variations that work or fail to work
but have yet to explain why.

Cheers,

Tim

/* Working version */

c0519d20 <stack_save>:
void
stack_save(struct stack *st)
{
c0519d20:       e92d48f0        push    {r4, r5, r6, r7, fp, lr}
c0519d24:       e28db010        add     fp, sp, #16     ; 0x10
        u_int32_t *frame; /* r7 */

        stack_zero(st);
c0519d28:       e1a04000        mov     r4, r0
c0519d2c:       ebf9ca49        bl      c038c658 <stack_zero>
                printf("%s: frame=3D%p\n", __func__, frame);=20
c0519d30:       e59f0054        ldr     r0, [pc, #84]   ; c0519d8c =
<_end+0xffd94e70>
c0519d34:       e59f1054        ldr     r1, [pc, #84]   ; c0519d90 =
<_end+0xffd94e74>
c0519d38:       e1a0200b        mov     r2, fp
c0519d3c:       ebf9a87d        bl      c0383f38 <printf>
                if (!INKERNEL(frame))
				break; /* =3D=3D=3D> return */=20
c0519d40:       e35b0103        cmp     fp, #-1073741824        ; =
0xc0000000
c0519d44:       38bd88f0        popcc   {r4, r5, r6, r7, fp, pc}

c0519d48:       e59f503c        ldr     r5, [pc, #60]   ; c0519d8c =
<_end+0xffd94e70>
c0519d4c:       e59f603c        ldr     r6, [pc, #60]   ; c0519d90 =
<_end+0xffd94e74>
         frame =3D (u_int32_t *)__builtin_frame_address(0);
c0519d50:       e1a0700b        mov     r7, fp
do {
               callpc =3D frame[FR_SCP];
 c0519d54:       e5971000        ldr     r1, [r7]
                if (stack_put(st, callpc) =3D=3D -1)
                        break; /* =3D=3D> return */
c0519d58:       e1a00004        mov     r0, r4
c0519d5c:       ebf9ca2c        bl      c038c614 <stack_put>
c0519d60:       e3700001        cmn     r0, #1  ; 0x1
c0519d64:       0a000007        beq     c0519d88 <stack_save+0x68>
                frame =3D (u_int32_t *)(frame[FR_RFP]); /* FR_RFP =3D=3D =
-3 */
c0519d68:       e247000c        sub     r0, r7, #12     ; 0xc
c0519d70:       e5907000        ldr     r7, [r0]
                printf("%s: frame=3D%p\n", __func__, frame);=20
c0519d6c:       e1a01006        mov     r1, r6
c0519d74:       e1a00005        mov     r0, r5
c0519d78:       e1a02007        mov     r2, r7
c0519d7c:       ebf9a86d        bl      c0383f38 <printf>
}                while (INKERNEL(frame));
c0519d80:       e3570103        cmp     r7, #-1073741824        ; =
0xc0000000
c0519d84:       2afffff2        bcs     c0519d54 <stack_save+0x34>
}
c0519d88:       e8bd88f0        pop     {r4, r5, r6, r7, fp, pc}


/* Broken version */
c0519cec <stack_save>:
void
stack_save(struct stack *st)
{
c0519cec:       e92d4830        push    {r4, r5, fp, lr}
c0519cf0:       e28db008        add     fp, sp, #8      ; 0x8
        u_int32_t *frame; /* r5 */

        stack_zero(st);
 c0519cf4:       e1a04000        mov     r4, r0
 c0519cf8:       ebf9ca56        bl      c038c658 <stack_zero>
                if (!INKERNEL(frame))
                        break;
c0519cfc:       e35b0103        cmp     fp, #-1073741824        ; =
0xc0000000
c0519d00:       38bd8830        popcc   {r4, r5, fp, pc}

         frame =3D (u_int32_t *)__builtin_frame_address(0);
 c0519d04:       e1a0500b        mov     r5, fp
do {
                callpc =3D frame[FR_SCP];
 c0519d08:       e5951000        ldr     r1, [r5]
                if (stack_put(st, callpc) =3D=3D -1)
                        break;
 c0519d0c:       e1a00004        mov     r0, r4
c0519d10:       ebf9ca3f        bl      c038c614 <stack_put>
c0519d14:       e3700001        cmn     r0, #1  ; 0x1
c0519d18:       0a000003        beq     c0519d2c <stack_save+0x40>
                frame =3D (u_int32_t *)(frame[FR_RFP]);
c0519d1c:       e245000c        sub     r0, r5, #12     ; 0xc
c0519d20:       e5905000        ldr     r5, [r0]
  } while (INKERNEL(frame));
c0519d24:       e3550103        cmp     r5, #-1073741824        ; =
0xc0000000
c0519d28:       2afffff6        bcs     c0519d08 <stack_save+0x1c>
}
c0519d2c:       e8bd8830        pop     {r4, r5, fp, pc}




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?D0B02568-E7AB-410E-8717-E9F9C745E6ED>