Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22080

What determines where the exception frame goes on Cortex-M4?

$
0
0

I'm struggling with an exception stack frame writing over my local/automatic/stack variables.

I'm using FreeRTOS 8.2.1 and Microchip ASF for SAM4LDeveloping with Eclipse MCU 2018/09 and Segger J-Link 6.40.

[EDIT]
The very first time through the loop, r7 has a different value (0x200044D0), which looks like it might be the correct value (same as SP). I'm thinking now that r7 is being changed while waiting on an RTOS message queue, which happens at the top of the loop (but not the first time through!)

    for(;;){        if(WaitTx(MSG_WAIT_TIME)){  calls xQueuePeek(...)            do{>> First time here, r7 has the value  0x200044D0>> Subsequent times, r7 has the value 0x200044B0                // Keep sending data until no more data                 MsgBlock_t *tosend = BuildFrame(MSG_MAX_LEN);                if(tosend){

[/EDIT]

I have an RTOS thread running a top level loop. Two local variables in the thread function are getting clobbered. Setting a watchpoint on one of the variables, I see it trigger while executing the second instruction of an interrupt handler. Memory dump shows an exception stack frame has been written over 32 bytes of the thread's stack. The lowest 5 stacked values correspond to the registers r0-r3,r12. Presumably the other 3 correspond to the orignal lr, pc and xpsr. The values look right.Code:

          TC02_Handler:00013f84:   push    {r0, r1, r2, r4, r5, r6, r7, lr}2141        tc_get_status(TC, BOARD_TC_CH_CMX);00013f86:   movs    r1, #2            <<< Watchpoint triggers halt here00013f88:   ldr     r0, [pc, #132]  ; 

Registers:

r0 = 0x0             == Memory location 0x200044B0r1 = 0x8             == Memory location 0x200044B4r2 = 0x0             == Memory location 0x200044B8r3 = 0x2000aab0      == Memory location 0x200044BCr4 = 0x2000cd10r5 = 0x0000cee3r6 = 0x200044b0r7 = 0x200044b0r8-r11 all 0xa5a5a5a5  (RTOS fills stack with this value at startup)r12= 0x6             == Memory location 0x200044C0sp = 0x2000e3f8      (nowhere near where exception frame was stacked)lr = 0xfffffffd

Memory:

0x200044B0: 00000000 00000008 00000000 2000AAB00x200044C0: 00000006 0000CECB 0000CECC 01000000 ---0x2000E3F8: 00000000 00000008 00000000 2000CD100x2000E408: 0000CEE3 200044B0 200044B0 FFFFFFFD

The thing that I don't understand is that when the watchpoint triggers at the entry to the handler, the stack pointer is pointing to a completely different location. The exception stack frame gets written to locations 0x200044B0 through 0x200044CF, but the stack pointer (After the watchpoint halts the micro) has the value 0x2000E3F8.

The first instruction of the exception handler pushes r0-r2, r4-r7 and lr. These values are pushed at the stack location pointed to by the sp at 0x2000E3F8 - 0x2000E417

Should the stack pointer be pointing to the bottom of the exception stack frame on entry to the exception handler?

Some other clues that my be relevant

  • The debugger looks at the wrong address for these automatic variables. The debugger "thinks" my variables should be at locations 200044E4 and 200044E8.

  • When the code accesses them, they are loaded from locations 200044C0 and 200044C4. These are accessed as an offset from r7.

ldr r0,[r7,#16]  (r7 is 0x200044B0).and ldr r0,[r7,#20]  (r7 is 0x200044B0).
  • During execution of the thread that is being corrupted, the stack pointer has the value 0x200044d0, but r7 (which I guess is being used as a "frame pointer") has the value 0x200044b0. The exception stack frame is placed correctly according to the value of sp.

Thanks


Viewing all articles
Browse latest Browse all 22080

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>