Is this related to the general panic discussed in freebsd-current?

Tim Kientzle tim at kientzle.com
Sun May 5 16:37:57 UTC 2013


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

> On Sat, 4 May 2013 15:44:37 -0700
> Tim Kientzle <tim at 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.
>> 
>> 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...
> 
> 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?
> 
> 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 
                printf("%s: frame=%p\n", __func__, frame); 
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=%p\n", __func__, frame); 
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; /* ===> return */ 
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 = (u_int32_t *)__builtin_frame_address(0);
c0519d50:       e1a0700b        mov     r7, fp
do {
               callpc = frame[FR_SCP];
 c0519d54:       e5971000        ldr     r1, [r7]
                if (stack_put(st, callpc) == -1)
                        break; /* ==> 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 = (u_int32_t *)(frame[FR_RFP]); /* FR_RFP == -3 */
c0519d68:       e247000c        sub     r0, r7, #12     ; 0xc
c0519d70:       e5907000        ldr     r7, [r0]
                printf("%s: frame=%p\n", __func__, frame); 
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 = (u_int32_t *)__builtin_frame_address(0);
 c0519d04:       e1a0500b        mov     r5, fp
do {
                callpc = frame[FR_SCP];
 c0519d08:       e5951000        ldr     r1, [r5]
                if (stack_put(st, callpc) == -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 = (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}



More information about the freebsd-arm mailing list