Problém s C kompilátorem nebo mezi klávesnicí a židlí?

Jakub Ladman ladmanj na volny.cz
Neděle Červenec 7 19:57:28 CEST 2019


Ahoj

Moc často sem dotazy nekladu, ale teď si oravdu nevím rady a jsou tu 
odborníci, z nichž někteří znají normu téměř z paměti :-)

Mějme funkci, která předává příkazy hardwaru přes sériový port a za 
odměnu od něj dostane 1-256 bytů dat.

Nadřazený kus sw ale požaduje 0-65535 bytů (ano jeden chybí, ale to není 
část aktuálního problému)

Problém je proměnná "biboch", která se jmenuje tak blbě jen proto, že už 
jsem měl podezření, že původní název "actual_len" s něčím koliduje. 
Ovšem asi ne, ani prohledání celého kódu neodhalí žádnou takovou 
proměnnou a už vůbec ne globální.

Proměnná může nabývat jen zmíněných 1-256

Ale její obsah nepřežije vstup do while smyčky.

Uvnitř proměnná existuje, ale její obsah je vynulován.

Absolutně nechápu co je to za ptákovinu.

Když si to v debuggeru krokuju a tu původní hodnotu si ručně obnovím, 
tak to funguje jak má.

Díky za tip.


Jakub Ladman

static uint8_t membuf[0xffff];    //whole 64kB memory image
static uint8_t page = 0;
uint8_t *doMemRead(uint16_t addr, uint16_t length)
{
     uint8_t data[4];
     uint8_t *output = membuf+addr;
     uint16_t biboch;
     uint16_t bytes_avail;
     uint8_t *temp;
     uint8_t len;

     while(length > 0)
     {    // set address
         data[0] = (addr >> 8) & 0xff;
         data[1] = addr & 0xff;
         data[2] = page;

         if(length/0x100)
             biboch = 0x100;
         else
             biboch = length%0x100;

         data[3] = (biboch & 0xff);

         if(ADR != send_hw_command(ADR, data, 4))
             return NULL;
         // read the data
         if(RDM != send_hw_command(RDM, data, 1)) // data byte is 
necessary but unread by hw
             return NULL;

         usleep(1000);

         printf("actual len %d\n", biboch);
         ioctl(sfd, FIONREAD, &bytes_avail);

         while(bytes_avail && !global_server_quit)
         {
             printf("actual len %d\n", biboch);
             if(bytes_avail>=(biboch+4))
             {
                 if((biboch+4)==read(sfd,inbuf,(biboch+4)))
                 {
                     if(biboch == 
packet_decode(&len,&temp,inbuf,(biboch+4)))
                     {
                         memcpy(membuf+addr,temp,biboch);
                         length -= biboch;
                         addr   += biboch;
                     }
                     else return NULL;
                 }
             }
             ioctl(sfd, FIONREAD, &bytes_avail);
         }
     }
     return output;
}


Target: x86_64-linux-gnu

gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1)

defaultně -std=gnu18, ale zkoušel jsem i 17 a 99



Další informace o konferenci Hw-list