3 <= 2 ? Computer says yes

Wenn man Programmierfehler sucht, dann natürlich zuerst im eigenem Quellcode. Releativ selten ist man jedoch nicht schuld. Davon geht man erst einmal nicht aus und dadurch dauert die Fehlersuche besonders lange.

Bei einem Bluetooth Low Energy Device mit einem 8051 Prozessor (von Ti) kam die IAR Workbench zum Einsatz. Version 9.30.1 ! Ein simpler Vergleich in einer Switch-Case gelang jedoch nicht in den eingestellten Grenzen.

uint8 tx_value = *(uint8*)pValue;
if(tx_value <= 0x02) {

Dieser Vergleich war für tx_value = 3 wahr.  Mit 2 (wahr) und 4 (falsch) hat der Vergleich jedoch das erwartete Ergebnis gebracht.

Also Fehlersuche:

  1. sehr wahrscheinlich: mit dem Pointer vertan und mit der Adresse verglichen, statt dem Wert und/oder Klammerfehler
  2. wahrscheinlich: ein Cast von int zu char, signed oder unsigned Problem
  3. unwahrscheinlich: der Codepfad wurde wegoptimiert, der Debugger springt gar nicht in den Wahr-Zweig und die Variable wird irgendwo anders „unbemerkt“ im Quellcode gesetzt
  4. sehr unwahrscheinlich: der Compiler übersetzt das C-Programm nicht korrekt

Nachdem ich von eins bis drei alles ausschließen konnte, bat ich einen Kollegen sich den Quellcode noch einmal mit einem frischen Blick anzusehen. Nachdem er ebenfalls die drei Punkte ausschließen konnte, wurde es interessant.

Ich mach es kurz. Der Compiler hat einen schweren Bug. In einer Switch-Case wir in der Optimierungsstufe „medium“ und „fast/high“ das Löschen des Carry Bits vergessen. Bei einer Subtraktion mit dem Befehl SUBB wird das Carry Bit immer als LSB verwendet. Also ist der Vergleich mit einem Zähler mehr noch wahr, obwohl er falsch sein müsste.

Wenn man nun etwas Dummy-Code vor dem Vergleich einarbeitet, der natürlich nichts mit der Problemstelle zu tun hat, wird der erwartete Clear Carry Flag eingearbeitet oder natürlich auch mit etwas Inline-ASM.

Natürlich haben wir das Problem IAR gemeldet, nach verständlichem anfänglichen misstraun des Supports, hieß es: okay, im Februar kommt ein neuer bugfreier Compiler/IDE heraus. Wir hatten November! Ich seh noch kein Update auf der Seite. Fehler passsieren, das ist klar, aber eine schnellere Reaktion hätte man sich schon erhoffen können. Wenn der Compiler 3.000 € kostet, möchte man nicht evtl. fehlerhafte Low Energy Produkte ausliefern. Gerade da bei BLE hohe Stückzahlen zu erwarten sind.

Hier ein Screenshot aus dem Quellcode. Den Produktnamen habe ich unkenntlich gemacht (kam an vielen Stellen vor):

blank

IAR 8051 Compiler Bug

Man sieht schön was im Accu (A) steht und dass das Carry Flag (CY) gesetzt ist. Der Vergleich kann also nur wahr werden. Wird die Optimierung ausgeschalten gibt es ein „CLR C“ im ASM-Listing.

Da ich nur kurzzeitig eine IAR Lizenz besessen habe, konnte ich keine Listing mehr auf Anfrage nachliefern. Das möchte ich nun hiermit nachholen. Der Beispielquellcode und das entsprechende .lst-File in low- und medium-Optimierung sind hier zu finden:

https://drive.google.com/open?id=0BwGPvdv-6Pq3QXgyRTJWNThhVm8

 

Advertisements
Dieser Beitrag wurde unter Allgemein veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s