Goto page 1, 2, 3 ... 10, 11, 12 Next
Marek
Guest
Wed May 17, 2023 9:23 pm
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 >>

;
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
Jacek Radzikowski
Guest
Wed May 17, 2023 9:43 pm
On 5/17/23 15:23, Marek wrote:
Quote:
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 >>

;
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/creating-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
Zbych
Guest
Wed May 17, 2023 10:02 pm
Marek wrote on 17.05.2023 21:23:
Quote:
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[] = {
}
Marek
Guest
Wed May 17, 2023 10:05 pm
On Wed, 17 May 2023 15:43:10 -0400, Jacek Radzikowski
<jacek@spamer.die.die.die.piranet.org> wrote:
Quote:
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
Marek
Guest
Wed May 17, 2023 10:16 pm
On Wed, 17 May 2023 22:02:05 +0200, Zbych <zbych@none.org> wrote:
Quote:
Trzeba było napisać:
const char * const connectionFailureStrings[] = {
Okok faktycznie. Dobra, szukam dalej co po tej tablicy jeździ..
--
Marek
Janusz
Guest
Thu May 18, 2023 8:55 am
W dniu 17.05.2023 o 21:23, Marek pisze:
Quote:
status = (UINT8)(eventInfo >>

;
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
Marek
Guest
Thu May 18, 2023 12:18 pm
On Thu, 18 May 2023 08:55:51 +0200, Janusz <janusz_k@o2.pl> wrote:
Quote:
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
Janusz
Guest
Thu May 18, 2023 12:44 pm
W dniu 18.05.2023 o 12:18, Marek pisze:
Quote:
On Thu, 18 May 2023 08:55:51 +0200, Janusz <janusz_k@o2.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?
Quote:
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
Marek
Guest
Thu May 18, 2023 1:05 pm
On Thu, 18 May 2023 12:44:11 +0200, Janusz <janusz_k@o2.pl> wrote:
Quote:
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
Dawid Rutkowski
Guest
Thu May 18, 2023 1:08 pm
czwartek, 18 maja 2023 o 12:44:14 UTC+2 Janusz napisał(a):
Quote:
W dniu 18.05.2023 o 12:18, Marek pisze:
On Thu, 18 May 2023 08:55:51 +0200, Janusz <janu...@o2.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
J.F
Guest
Thu May 18, 2023 1:22 pm
On Wed, 17 May 2023 22:16:05 +0200, Marek wrote:
Quote:
On Wed, 17 May 2023 22:02:05 +0200, Zbych <zbych@none.org> wrote:
Trzeba było napisać:
const char * const connectionFailureStrings[] = {
Okok faktycznie. Dobra, szukam dalej co po tej tablicy jeździ..
No wlasnie - const to jedno, ale cos jezdzi.
Przekompiluj jak wyzej - moze wyrzuci błąd i znajdziesz,
ale jesli nie, to moze być bardziej skomplikowane szukanie.
J.
Grzegorz Niemirowski
Guest
Thu May 18, 2023 1:29 pm
Janusz <janusz_k@o2.pl> napisał(a):
Quote:
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?
Niby osobno adresowane ale nie do końca, bo są w jednej pamięci. Jak
wyjedziesz poza zakres jednej, to wpadniesz na drugą. To nie jest błąd
kompilatora ani linkera ale uroki C. Błąd w kodzie polega na zapomnieniu, że
sizeof() nie służy do zwracania liczby elementów tablicy. Można go użyć w
tej roli tylko dla tablic o typie jednobajtowym (char, uint8_t itp) a nie
short.
--
Grzegorz Niemirowski
https://www.grzegorz.net/
heby
Guest
Thu May 18, 2023 1:49 pm
On 18/05/2023 13:29, Grzegorz Niemirowski wrote:
Quote:
Błąd w kodzie polega na
zapomnieniu, że sizeof() nie służy do zwracania liczby elementów
tablicy.
Słusznie. Pozwólcie, że wsadzę kij w mrowisko i pokażę co należy używać
od kilku lat:
https://en.cppreference.com/w/cpp/iterator/size
A bodaj od 20 lat jest w boost.
Grzegorz Niemirowski
Guest
Thu May 18, 2023 1:54 pm
heby <heby@poczta.onet.pl> napisał(a):
Quote:
Ale to trzeba zacząć C++ używać :)
--
Grzegorz Niemirowski
https://www.grzegorz.net/
Marek
Guest
Thu May 18, 2023 2:01 pm
On Thu, 18 May 2023 04:08:13 -0700 (PDT), Dawid Rutkowski
<drutkow1@wp.pl> wrote:
Quote:
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 jaki
mś unixem.
Błagam, przecież pic32 to pełen mips dlaczego nie ma mieć wyjątków??
Ma nawet wsparcie częściowe do VM user/kernel space. A MZy nawet
TBLe do translacji adresów wirtualnych. Na ATmega8 świat się nie
kończy...
--
Marek
Goto page 1, 2, 3 ... 10, 11, 12 Next