Enkla men fatala buggar

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
guckrum
Inlägg: 1669
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Enkla men fatala buggar

Inlägg av guckrum »

Varför kod som skiftar 258 steg? Det motsvarar ju ungefär 10 upphöjt till 77, vilket närmar sig mängden atomer i universum, typ. Känns lite underligt.
Användarvisningsbild
Icecap
Inlägg: 26105
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Enkla men fatala buggar

Inlägg av Icecap »

Morten: Shift med mer än 8 positioner behövs helt klart om det är en mer-än-8-bit CPU.
Det behövs upp till processorns databredd faktisk.

Men ja, 258 är ganska orealistisk och tyder på att programmörn inte har helt koll på variabler osv.

Är man i behov för att shifta en sammansatt variabel, t.ex. 64 bit i en 32-bit CPU får man fixa lite i programmet för att lösa detta.
Användarvisningsbild
bit96
Inlägg: 2492
Blev medlem: 3 september 2007, 10:04:29
Ort: Säffle

Re: Enkla men fatala buggar

Inlägg av bit96 »

Vänster-skift-operatorn i C (<<) är faktiskt exakt definerad hur den skall funka.

Ex. a << b

Den andra operanden, b i exemplet ovan får ej vara negativ och ej större än eller lika med första operandens längd.
Vad som i så fall händer är odefinerat.

Det är alltså definerat som att vara odefinerat, eller i praktiken är det den som tillverkar kompilatorn som bestämmer vad som skall hända.

Man SKALL alltså se till att andra operanden (b i exemplet ovan) ligger inom korrekta gränser.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Enkla men fatala buggar

Inlägg av Mr Andersson »

Icecap skrev: 12 oktober 2021, 18:16:05 Morten: Shift med mer än 8 positioner behövs helt klart om det är en mer-än-8-bit CPU.
Det behövs upp till processorns databredd faktisk.
Det Morten menar är att det behövs inte mer än 8 bitars värde för att shifta 256 bitpositioner.
Tekniskt sett räcker det med 5 bitars värde för att täcka en 32 bitars cpu.
guckrum
Inlägg: 1669
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Enkla men fatala buggar

Inlägg av guckrum »

Precis, och barrel shiftern inne i CPUn har inte större shift-range än vad som behövs. Då skulle shiften ta flera klockcykler. Sedan är ju många CPUer RISC, och då kan man ju få in shiftvärdet som en del av instruktionen också. Annars blir det segt:-)
Användarvisningsbild
jesse
Inlägg: 9233
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Enkla men fatala buggar

Inlägg av jesse »

Shiftvärdet (hur många steg som ska shiftas) kan ju bara läggas in som en del av instruktionen om det är ett fast värde. Är det en variabel så krävs ju ändå att värdet laddas först i något register.
Användarvisningsbild
kimmen
Inlägg: 2042
Blev medlem: 25 augusti 2007, 16:53:51
Ort: Stockholm (Kista)

Re: Enkla men fatala buggar

Inlägg av kimmen »

Jag hjälpte en kollega med felsökning av kod ungefär enligt nedan som skulle skicka 24 bitar över bitbangad SPI till en DAC.
Efter byte av kompilator fungerade den inte längre.
Någon aning om varför det inte funkade?

Kod: Markera allt

void send_to_dac(uint32_t val)
{
  for (uint32_t bit = 1 << 23; bit != 0; bit >>= 1)
  {
    set_mosi((val & bit) != 0);
    pulse_clk();
  }
}
Svar:
[VISA]
Felet var att
uint32_t bit = 1 << 23;
har undefined behavior om int är 16 bitar, vilket det var på den här kompilatorn/processorn.

1 << 23 räknas ut som int eftersom vänstra operanden 1 är int.
Att värdet senare lagras i en uint32_t ändrar inte betydelsen av skiftoperationen.
I den gamla kompilatorn så råkade de höga 16 bitarna av 32 bitars mellanresultatet behållas och felet märktes aldrig.
Det är väl en av de lurigaste bitarna med C/C++ undefined behavior -- att det ofta "fungerar" precis som man tänkte sig men att det senare slutar fungera i en annan kompilator, nyare version av samma kompilator, när man ändrar optimeringsinställningar eller kanske bara när man ändrar annan kod i programmet.

Koden rättades till
uint32_t bit = 1UL << 23;

men

uint32_t bit = (uint32_t)1 << 23;

är ju ett annat alternativ.
Användarvisningsbild
Klas-Kenny
Inlägg: 11291
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Enkla men fatala buggar

Inlägg av Klas-Kenny »

Om man använder MPLAB X för att programmera en Microchip-processor, och väljer in FreeRTOS mha. Harmony, så är default minneshantering "heap_1".

Problemet med "heap_1" är att denne saknar möjlighet att frigöra minne (Beskrivning av de olika alternativen).
Och när märker man detta? Jo, när programmet kraschar pga. slut på minne. :doh:

Så ska man göra någonting dynamiskt i FreeRTOS, tex. skapa och ta bort tasker dynamiskt, så måste man ändra detta.



Skulle inte bli förvånad om det är samma sak i fler liknande verktyg än just MPLAB också.
Skriv svar