This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Stack Guard and MPU

Hi, I'm trying to get the nrf_stack_guard and nrf_mpu libraries to catch writes past the end of the stack. My stack is 8kB in size (0x2000E000-0x20010000). This is the log output after initializing the Stack Guard module:

<debug> nrf_mpu: MPU region creating (location: 0x2000E000-0x2000E07F)
<debug> nrf_mpu: MPU region 0 created (location: 0x2000E000-0x2000E07F, access: RO/RO, type: Normal, flags: XN).
<info> stack_guard: Stack Guard: 0x2000E000-0x2000E07F (usable stack area: 8064 bytes)

I'm having a little trouble understanding how the MPU works. I'd expect a write to 0x2000E000 to trigger the HardFault_Handler, but in reality nothing is triggered. The write just happens and silentlly corrupts RAM below the stack.

I'm using the nrf gcc hardfault library implementation and am able to catch NULL dereferences and other faults, so that should be correctly set up.

What am I missing?

Parents
  • I see two possible causes

    1. The C optimizer eliminated the write completely or placed it somewhere else (where it would not be executed).
    2. The write buffer delayed the fault and you were only checking with a breakpoint directly after the write instruction.

    In any case we would need to see your source code...

  • Hi, thank you for the timely reply.

    Please see the below C++ snippet. I'm simulating this by allocating too big of a structure on the stack and writing to each element. If I break directly after this snippet, it leaves MSP at 0x2000d388 (beyond the stack limits).

    std::array<uint8_t, 8192> tmp{};
    NRF_LOG_INFO("MSP: %p", __get_MSP());
    for (int i = 0; i < 8192; ++i)
        tmp[i] = i;
    
    NRF_LOG_DEBUG("%p %p", tmp.begin(), tmp.end());
    NRF_LOG_INFO("MSP: %p", __get_MSP());
        
    illegal_write((void*) 0x2000E000);

    Then I tried directly writing to the protected stack area with the `illegal_write`, which is placed in another compilation unit. I'm running a debug build without any optimizations.

    void illegal_write(void* addr)
    {
        auto* p = (uint32_t*) addr;
        *p = 1;
    }

Reply
  • Hi, thank you for the timely reply.

    Please see the below C++ snippet. I'm simulating this by allocating too big of a structure on the stack and writing to each element. If I break directly after this snippet, it leaves MSP at 0x2000d388 (beyond the stack limits).

    std::array<uint8_t, 8192> tmp{};
    NRF_LOG_INFO("MSP: %p", __get_MSP());
    for (int i = 0; i < 8192; ++i)
        tmp[i] = i;
    
    NRF_LOG_DEBUG("%p %p", tmp.begin(), tmp.end());
    NRF_LOG_INFO("MSP: %p", __get_MSP());
        
    illegal_write((void*) 0x2000E000);

    Then I tried directly writing to the protected stack area with the `illegal_write`, which is placed in another compilation unit. I'm running a debug build without any optimizations.

    void illegal_write(void* addr)
    {
        auto* p = (uint32_t*) addr;
        *p = 1;
    }

Children
No Data
Related