Re: Memory corruption (?) I don't understand
BERTRAND Joël <[email protected]> Wed, 23 Jun 2021 09:15:50 +0200
| Newsgroups | gmane.comp.hardware.avr.gcc |
|---|---|
| Message-ID | <[email protected]> |
Some news.
In lorawan/ldl_mac.c is defined LDL_MAC_otaa :
enum ldl_mac_status LDL_MAC_otaa(struct ldl_mac *self)
{
enum ldl_mac_status retval;
union ldl_mac_response_arg arg;
LDL_PEDANTIC(self != NULL)
if(self->ctx.joined){
retval = LDL_STATUS_JOINED;
}
else if(self->op == LDL_OP_NONE){
if(self->devNonce <= U32(UINT16_MAX)){
forgetNetwork(self);
self->trials = 0;
self->day = U32(60) * U32(60) * U32(24) * timeTPS;
#if defined(LDL_ENABLE_L2_1_1)
LDL_OPS_deriveJoinKeys(self);
#endif
fillJoinBuffer(self, U16(self->devNonce));
self->devNonce++;
arg.dev_nonce_updated.nextDevNonce = self->devNonce;
self->handler(self->app, LDL_MAC_DEV_NONCE_UPDATED, &arg);
self->tx.power = 0;
self->op = LDL_OP_JOINING;
if(self->state == LDL_STATE_IDLE){
self->state = LDL_STATE_WAIT_OTAA;
LDL_MAC_timerSet(self, LDL_TIMER_WAITA, 0);
}
retval = LDL_STATUS_OK;
LDL_DEBUG("OTAA is pending")
}
else{
/* need to re-init with a different JoinEUI */
retval = LDL_STATUS_DEVNONCE;
}
}
else{
retval = LDL_STATUS_BUSY;
}
return retval;
}
In this function, there is a call to self->handler(self->app,
LDL_MAC_DEV_NONCE_UPDATED, &arg). If I comment out this line, firmware
doesn't crash anymore. I think in a first time that self->handler is
nullified by something. OK, I've checked and I have added just before
self->handler() :
if (self->handler == NULL) for(;;);
After recompilation, firmware runs as expected (!) and doesn't enter in
loop (!). I don't understand why this test fix this bug. I have tried to
replace in a second time :
self->handler(self->app, LDL_MAC_DEV_NONCE_UPDATED, &arg);
by a direct call to app_handler function (and of course without previous
test):
app_handler(self->app, LDL_MAC_DEV_NONCE_UPDATED, &arg);
Thus :
- self->handler() triggers the bug ;
- I'm not sure that self->handler is really nullified as execution
doesn't enter in if (self->handler == NULL) for(;;);
- why and how does the line if (self->handler == NULL) for(;;); fix this
issue ?
self->handler() seems to be modified by something or CPU is not able to
jump to specified address. Is there a difference in generated asm code
between a call to a function pointer and a direct call ?
I can post three firmware.elf if required :
- original that crashes ;
- modified with if (self->handler == NULL) for(;;); that runs as expected :
- modified without test but with direct call to app_handler() that runs.
Best regards,
JKB