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

Setting a watchpoint dynamically

Hello,

I am trying to spot a bug in which some memory corruption is happening. I don't know in advance at which address the corruption will happen, as it happens in some circular buffer. Maybe something is wrongly reading an address referring to this buffer and then writing there. I don't know.

Anyhow, I have found some way to store in some global variable mem_corruption_address the  data memory address at which the corruption before it happens, just in case it would happen, and what I want to do it call some watch_corruption_enable function at some point before code section in which the corruption may happen and watch_corruption_disable after this code section.

So here is the code which I have written : 

extern uint32_t const volatile* volatile mem_corruption_address;
uint32_t const volatile* volatile mem_corruption_address = NULL;

nrf_atomic_flag_t watch_corruption;

static void watch_corruption_set_watchpoint(void)
{
    if (watch_corruption) {
        DWT->COMP0     = (uintptr_t)mem_corruption_address;
        DWT->MASK0     = 0; // range = 1 × 32bit word.
        DWT->FUNCTION0 = (6<<0) // generate watch point debug event on WO match
            | (0<<7) // FUNCTION0.CYCMATCH == 0 for address comparison
            | (0<<8) // FUNCTIONn.DATAVMATCH == 0 for address comparison
            | (1<<5) // FUNCTIONn.EMITRANGE == 1 for trace packet generation
            ;
    }
}

static void watch_corruption_reset_watchpoint(void)
{
    DWT->FUNCTION0 = 0;
}

void watch_corruption_enable(void)
{
    nrf_atomic_flag_set(&watch_corruption);
}

void watch_corruption_disable(void)
{
    if (nrf_atomic_flag_clear_fetch(&watch_corruption)) {
        watch_corruption_reset_watchpoint();
    }
}

The watch_corruption_set_watchpoint is called after each valid writing to the potentially corrupted memory, so that a valid write won't trigger the watchpoint, and I am also sure that no subsequent valid writing can occur before watch_corruption_disable is called.

Now, I am debugging with the Segger JTracePro with Ozone IDE (so I compiled my FW with ENABLE_TRACE #define'd). My hope was after the watchpoint is triggered I can browse back the instruction trace to find what made the corruption.

So, my problem is the following : instead of what I expected/hoped to get, I get Ozone more or less frozen at some point of time, I cannot stop the debugging session. I need to for the Ozone application stop from system. So, it seems that what I am doing it messing up how Ozone interfaces with the JTracePro.

I would like to know how to do it properly. 

Related