eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › Dziwny problem z kodem w C (gcc mips/pic32)
Ilość wypowiedzi w tym wątku: 171

  • 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

strony : [ 1 ] . 2 ... 10 ... 18


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: