Pierwszy raz się spotkałem z czymś takim, o to problematyczny fragment kodu:
const char *connectionFailureStrings[] = { "NULL", /* 0 - not used */ "NULL", /* 1 - not used */ "WF_JOIN_FAILURE", /* 2 */ "WF_AUTHENTICATION_FAILURE", /* 3 */ "WF_ASSOCIATION_FAILURE", /* 4 */ "WF_WEP_HANDSHAKE_FAILURE", /* 5 */ "WF_PSK_CALCULATION_FAILURE", /* 6 */ "WF_PSK_HANDSHAKE_FAILURE", /* 7 */ "WF_ADHOC_JOIN_FAILURE", /* 8 */ "WF_SECURITY_MISMATCH_FAILURE", /* 9 */ "WF_NO_SUITABLE_AP_FOUND_FAILURE", /* 10 */ "WF_RETRY_FOREVER_NOT_SUPPORTED_FAILURE"/*11*/ };
static void OutputConnectionFailedMsg(UINT16 eventInfo) { UINT8 status; UINT8 reason; status = (UINT8)(eventInfo >> 8); reason = (UINT8)(eventInfo & 0xff);
printf (" status %d %p\r\n",status,connectionFailureStrings[status]); printf("WF_Event: Connection Failed: %s ",connectionFailureStrings[status]); }
Mamy tablicę stringów umieszczoną we flash (pamięci stałej) dzięki const. Niestety w losowych przypadkach drugi printf generuje wyjątek adresu z poza zakresu. Zmienna status nie przekracza zakresu i zawsze nawet jak jest wyjątek ma wartość 3. Okazuje się, że gdy jest wyjątek to wskaźnik (%p w pierwszym printf) pokazuje jakiś bzdurny adres, co oczywiście doprowadza do wyjątku w drugim printf. Jak to możliwe, że adres jest bzdurny?? Przecież tablica jest we flash, adres tutaj powinien być stały i wygenerowany na etapie kompilacji. Oczywiście w większości przypadków gdy wszystko jest OK printf pokazuje prawidłowy adres 3 indeksu w tej tablicy. Ale raz na 10 startów kodu nie... Co ciekawe wygląda na to, że bzdurny adres pojawia się przy pierwszym uruchomieniu kodu po flashowaniu mcu ale też nie za każdym razem...
Cały kod jest dość obszerny (75 tys linii), nie ma innych problemów, to jedyne miejsce, więc chyba można wykluczyć problem z mcu/flash...