06.10.2013 Aufrufe

Eine Einführung in die Programmiersprache C und ... - C /C++ Ecke

Eine Einführung in die Programmiersprache C und ... - C /C++ Ecke

Eine Einführung in die Programmiersprache C und ... - C /C++ Ecke

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

<strong>E<strong>in</strong>e</strong> <strong>E<strong>in</strong>führung</strong> <strong>in</strong> <strong>die</strong> Informatik <strong>und</strong> <strong>die</strong> <strong>Programmiersprache</strong> C<br />

36 Anhang B, Debugg<strong>in</strong>g Tips <strong>und</strong> Tricks<br />

Compilerwarnungen beachten.<br />

E<strong>in</strong> Modul sollte sich möglichst ohne Warnungen compilieren lassen, jede verbleibende Warnung überprüfen, nicht<br />

e<strong>in</strong>fach ignorieren. Bei den Compileroptionen möglichst alle Warnungen e<strong>in</strong>schalten.<br />

Auf nicht <strong>in</strong>itialisierte Variablen achten.<br />

Probleme mit Programmteilen, <strong>die</strong> e<strong>in</strong>mal laufen <strong>und</strong> anschliessend nie mehr, oder e<strong>in</strong>malig unkorrekt <strong>und</strong> anschliessend<br />

fehlerfrei laufen, lassen sich oft auf un<strong>in</strong>itialisierte Variablen (Insbesondere Po<strong>in</strong>ter) zurückführen.<br />

Auf Überschreiten von Arraygrenzen achten<br />

In C kann problemlos über Arraygrenzen h<strong>in</strong>aus geschrieben werden (oben <strong>und</strong> unten), was oft zu Totalabstürzen,<br />

manchmal aber nur zur Veränderung von benachbarten Variablen führt (Schwer lokalisierbarer Fehler !!!). Möglicherweise<br />

<strong>in</strong> Debugversion vor jedem Arrayzugriff Index auf Bereich überprüfen (Achtung, <strong>in</strong>effizienter Code!)<br />

Selbstüberprüfenden Code schreiben.<br />

Zu Beg<strong>in</strong>n jeder Funktion <strong>die</strong> Argumente auf Plausibilität prüfen, <strong>in</strong>sbesondere NULL-Po<strong>in</strong>ter. Testfunktionen schreiben,<br />

<strong>die</strong> Datenstrukturen (Listen, Bäume, ...) auf ihre Integrität h<strong>in</strong> untersuchen. Diese Testrout<strong>in</strong>en beim Debuggen an<br />

strategisch wichtigen Punkten aufrufen.<br />

Fehler e<strong>in</strong>grenzen.<br />

Durch Ausgaben, Statusanzeigen oder grobschrittiges Debuggen Fehler e<strong>in</strong>grenzen, bis fehlererzeugende Funktion oder<br />

Codezeile lokalisiert ist. Eventuell Hilfscode schreiben um Fehler weiter e<strong>in</strong>zugrenzen.<br />

Fehler isolieren.<br />

Funktionen, <strong>die</strong> als Fehlerquelle <strong>in</strong> Frage kommen durch vere<strong>in</strong>fachte Versionen ersetzen <strong>und</strong> prüfen ob Fehler verschw<strong>in</strong>det,<br />

so kann fehlerhafte Funktion gef<strong>und</strong>en werden.<br />

Funktionen separat testen.<br />

Verdächtige Funktionen aus der Applikation entfernen <strong>und</strong> <strong>in</strong> e<strong>in</strong> e<strong>in</strong>faches Testprogramm e<strong>in</strong>bauen, das <strong>die</strong> Funktion<br />

während längerer Zeit mit Testdaten oder Zufallsdaten aufruft <strong>und</strong> das Ergebnis jeweils überprüft, <strong>die</strong>ser Test kann mit<br />

e<strong>in</strong>er Integritätskontrolle komb<strong>in</strong>iert werden.<br />

Status<strong>in</strong>formationen ausgeben<br />

Systemzustand ausgeben, ev. auf LED oder freie Portbits, wenn ke<strong>in</strong>e andere Ausgabemöglichkeit vorhanden ist. So<br />

kann der Lauf des Programms verfolgt <strong>und</strong> unerwünschtes Verhalten erkannt werden. Auch Tim<strong>in</strong>gprobleme können so<br />

analysiert werden; <strong>die</strong>s ist meist sogar <strong>die</strong> e<strong>in</strong>fachste Möglichkeit, Tim<strong>in</strong>gprobleme zu erkennen.<br />

Bei Sporadischen Fehlern<br />

E<strong>in</strong> Logfile oder e<strong>in</strong>en Tracebuffer (Grosses Array mit ausreichend Platz für E<strong>in</strong>träge, als R<strong>in</strong>gbuffer aufgebaut der<br />

immer <strong>die</strong> n letzten Ereignisse bereit hält) e<strong>in</strong>fügen, wor<strong>in</strong> ständig Systemzustände oder wichtige Ereignisse (Funktionsaufrufe,<br />

Argumente, Interrupts, Benutzere<strong>in</strong>gaben, Systemzeit <strong>in</strong> ms/us) abspeichert werden. Im Fehlerfall den Inhalt<br />

von Logfile oder Tracebuffer sichern. Die Analyse <strong>die</strong>ser Daten kann helfen, den Fehler zu lokalisieren.<br />

Fehler <strong>in</strong> Speicherverwaltung<br />

Bei Verdacht auf Fehler <strong>in</strong> Speicherverwaltung, oder auch als Vorsichtsmassnahme kann e<strong>in</strong>e eigene Speicherverwaltung<br />

benutzt werden, <strong>die</strong> auf typische Fehler <strong>in</strong> der Speicherbenutzung achtet: Rückgabe nicht allozierten Speichers,<br />

doppelte Rückgabe desselben Speicherblocks, Allozieren aber nie Freigeben e<strong>in</strong>es Speicherblockes, beschränkt auch<br />

das Überschreiten der Speicherblockgrenzen (Block am Anfang <strong>und</strong> am Ende grösser machen <strong>und</strong> <strong>die</strong>se Schutzbereiche<br />

mit Testmuster füllen, bei Rückgabe prüfen ob <strong>die</strong>se Testmuster unversehrt s<strong>in</strong>d).<br />

Spezialcode für Fehlerfall schreiben<br />

Extracode schreiben, der beim Erkennen e<strong>in</strong>es Fehlers aufgerufen wird <strong>und</strong> möglichst viele Informationen des aktuellen<br />

Systemzustandes ausgibt oder <strong>in</strong> e<strong>in</strong> File schreibt, oder e<strong>in</strong>en Breakpo<strong>in</strong>t auf <strong>die</strong>sen Extracode setzen, so dass im Fehlerfall<br />

der Debugger zum Zuge kommt.<br />

Bei HW-naher Programmierung auf volatile <strong>und</strong> Stacküberlauf achten<br />

Variablen <strong>die</strong> von der HW oder Interrupts verändert werden, müssen als volatile deklariert werden. Lokale Variablen<br />

von Funktionen werden auf dem Stack abgelegt, lokale Arrays können bei Mikrokontrollern schnell zu Stacküberlauf<br />

führen. Unerklärliches Fehlverhalten oder Abstürze können auch auf e<strong>in</strong>en Stacküberlauf zurückzuführen se<strong>in</strong>.<br />

Gedruckt am 11.09.2008 13:04:00 Letzte Änderung am: 11. September 2008 Version 2.4, I. Oesch 145/147

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!