-
1. Data: 2023-05-17 21:23:00
Temat: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Marek <f...@f...com>
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...
--
Marek
-
2. Data: 2023-05-17 21:43:10
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Jacek Radzikowski <j...@s...die.die.die.piranet.org>
On 5/17/23 15:23, Marek wrote:
> 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...
Nie testowałem, ale na pierwszy rzut oka to w deklaracji brakuje jednego
consta:
https://stackoverflow.com/questions/28320538/creatin
g-a-const-array-of-const-elements#28320734
W obecnej formie masz tablicę, która wskazuje na stringi we flashu. To
jest inicjowana stała, więc można by przypuszczać ze zawsze będzie miała
taką samą zawartość, ale czasami coś się popsuje.
Sprawdź w jakim segmencie jest umieszczona tablica, i jeśli w RAMie, to
zacznij szukać gdzie masz bląd w programie, bo najprawdopodobniej coś
gdzieś wyjeżdża poza zaalokowany obszar i nadpisuje losowe rejony pamięci.
Jacek
-
3. Data: 2023-05-17 22:02:05
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Zbych <z...@n...org>
Marek wrote on 17.05.2023 21:23:
> Pierwszy raz się spotkałem z czymś takim, o to problematyczny
> fragment kodu:
>
>
> const char *connectionFailureStrings[] = {
> Mamy tablicę stringów umieszczoną we flash (pamięci stałej) dzięki
> const.
Nie, string masz we flashu, ale tablicę wskaźników do nich masz w RAMie.
Trzeba było napisać:
const char * const connectionFailureStrings[] = {
}
-
4. Data: 2023-05-17 22:05:28
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Marek <f...@f...com>
On Wed, 17 May 2023 15:43:10 -0400, Jacek Radzikowski
<j...@s...die.die.die.piranet.org> wrote:
> Sprawdź w jakim segmencie jest umieszczona tablica, i jeśli w RAMie,
Jest we flash, tak jak powinno. Gdy wszystko działa jak należy
wskaźnik wskazuje na adres we flash, dump mapy pamięci kodu również
wskazuje, że ta tablica jest we flash. Ten fragment kodu nawet nie
jest mój, to fragment z biblioteki MCHP, zresztą *to* nie wygląda na
błąd w kodzie.
Jedyne podejrzenie to użycie uint8 zamiast int jako indexu ale to nie
powinno powodować problemu.
--
Marek
-
5. Data: 2023-05-17 22:16:05
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Marek <f...@f...com>
On Wed, 17 May 2023 22:02:05 +0200, Zbych <z...@n...org> wrote:
> Trzeba było napisać:
> const char * const connectionFailureStrings[] = {
Okok faktycznie. Dobra, szukam dalej co po tej tablicy jeździ..
--
Marek
-
6. Data: 2023-05-18 08:55:51
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Janusz <j...@o...pl>
W dniu 17.05.2023 o 21:23, Marek pisze:
> 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]);
> }
Dla mnie trochę dziwny jest ten fragment, reason-nie wykorzystana
zmienna a komunikat (z tablicy) dwa razy wywołujesz ten sam, zmienna
status.
--
Janusz
-
7. Data: 2023-05-18 12:18:05
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Marek <f...@f...com>
On Thu, 18 May 2023 08:55:51 +0200, Janusz <j...@o...pl> wrote:
> Dla mnie trochę dziwny jest ten fragment, reason-nie wykorzystana
> zmienna a komunikat (z tablicy) dwa razy wywołujesz ten sam,
> zmienna
> status.
Kod na potrzeby posta trochę uprościłem.
Znalazłem dziada:
unsigned short BT[300];
int i;
for (i=0; i<sizeof(BT);i++)
BT[i] = getval(i);
Analizując mapę linkera widać, że BT była umieszczona tuż przed tamtą
tablicą ze wskaźnikami do stringów.
Na starość to trzepać worki po cemencie a nie programować....
For
--
Marek
-
8. Data: 2023-05-18 12:44:11
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Janusz <j...@o...pl>
W dniu 18.05.2023 o 12:18, Marek pisze:
> On Thu, 18 May 2023 08:55:51 +0200, Janusz <j...@o...pl> wrote:
>> Dla mnie trochę dziwny jest ten fragment, reason-nie wykorzystana
>> zmienna a komunikat (z tablicy) dwa razy wywołujesz ten sam, zmienna
>> status.
>
> Kod na potrzeby posta trochę uprościłem. Znalazłem dziada:
>
> unsigned short BT[300];
> int i;
>
> for (i=0; i<sizeof(BT);i++)
> BT[i] = getval(i);
>
> Analizując mapę linkera widać, że BT była umieszczona tuż przed tamtą
> tablicą ze wskaźnikami do stringów.
No i co z tego, przecież to dwie osobne tablice i osobno się adresują i
chyba kompilator czy linkier nie ma tu błędu w adresacji?
> Na starość to trzepać worki po cemencie a nie programować....
Eee tam, ja mam już prawie 63 i dalej piszę programy i naprawiam
elektronikę.
A zaczynałem przygodę z komputerami od Mery 9150 i jej asemblera w
połowie lat '80 czyli dość późno.
--
Janusz
-
9. Data: 2023-05-18 13:05:16
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Marek <f...@f...com>
On Thu, 18 May 2023 12:44:11 +0200, Janusz <j...@o...pl> wrote:
> No i co z tego, przecież to dwie osobne tablice i osobno się
> adresują i
> chyba kompilator czy linkier nie ma tu błędu w adresacji?
Chodzi o to, że BT namierzyłem z mapy linkera bo było zaadrasowane
tuż przed tamtą, więc stała się podejrzaną o przepełnienie. Błedne
użycie sizeof() powodowało przepełnienie w tym for() i wjazd na tą
drugą.
Jak widzisz wiek ma jednak znaczenie ;)
--
Marek
-
10. Data: 2023-05-18 13:08:13
Temat: Re: Dziwny problem z kodem w C (gcc mips/pic32)
Od: Dawid Rutkowski <d...@w...pl>
czwartek, 18 maja 2023 o 12:44:14 UTC+2 Janusz napisał(a):
> W dniu 18.05.2023 o 12:18, Marek pisze:
> > On Thu, 18 May 2023 08:55:51 +0200, Janusz <j...@o...pl> wrote:
> >> Dla mnie trochę dziwny jest ten fragment, reason-nie wykorzystana
> >> zmienna a komunikat (z tablicy) dwa razy wywołujesz ten sam, zmienna
> >> status.
> >
> > Kod na potrzeby posta trochę uprościłem. Znalazłem dziada:
> >
> > unsigned short BT[300];
> > int i;
> >
> > for (i=0; i<sizeof(BT);i++)
> > BT[i] = getval(i);
> >
> > Analizując mapę linkera widać, że BT była umieszczona tuż przed tamtą
> > tablicą ze wskaźnikami do stringów.
> No i co z tego, przecież to dwie osobne tablice i osobno się adresują i
> chyba kompilator czy linkier nie ma tu błędu w adresacji?
Wykonaj kod na kartce to się dowiesz.
To nie turbo pascal tylko C na uC - i tak się dziwię, że OP pisze tu o jakichś
wyjątkach, może to w wersji mips pod jakimś unixem.
A chwalisz się tym asemblerem Mery 9150 - nie ma to jak używać terminala
jako komputera, stąd się przecież wziął bodajże 8008 ;P