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