Feb 2006 Fehlerbehandlung in Programmiersystemen Christoph Kessler Universitt
Feb. 2006 Fehlerbehandlung in Programmiersystemen Christoph Kessler Universität Linköping, Schweden n Fehler-Klassifikation n Behandlung statischer Fehler n Behandlung von Laufzeitfehlern l Exception-Konzept l Debugging Christoph Kessler, IDA, Linköpings universitet, 2006.
Programmierfehler… n Ein erheblicher Teil der Gesamtkosten eines Softwareprojektes entfällt auf Testen, Fehlersuche und -behebung. n Welche Fehlertypen können auftreten? l Klassifikation n Prävention, Diagnose, Behandlung l Programmiersprachliche Konzepte l Compiler, IDE l Sonstige Werkzeuge: Debugger, Verifizierer, . . . C. Kessler, IDA, Linköpings universitet. 2 Feb. 2006
Programmierfehler – Klassifikation (1) n Syntaktische Fehler l Syntaxfehler z. B. vergessenes Semikolon n Semantische Fehler l Statische semantische Fehler 4 Statische Typfehler Falscher Parametertyp; Downcast ohne Laufzeit-Überprüfung 4 Nicht deklarierte Variable l Laufzeitfehler n Logische Fehler l Algorithmische Fehler vergessener Spezialfall, Nichtterminierung Akkumulation von Rundungsfehlern Verletzung geforderter Invarianten 4 Numerische Fehler l Kontraktverletzung C. Kessler, IDA, Linköpings universitet. 3 Feb. 2006
Programmierfehler – Klassifikation (2) n Laufzeitfehler – in der Regel nicht statisch prüfbar l Zugriffsfehler z. B. : 4 Arrayindex-Fehler Index out of bounds 4 Pointerfehler Dereferenziere NULL-Pointer l Arithmetische Fehler Division durch 0, Überlauf l I/O – Fehler unerwartetes Dateiende l Kommunikationsfehler Falscher Empfänger, falscher Typ l Synchronisationsfehler Daten-”race”, deadlock l Ressourcen-Erschöpfung Speicher, Zeitkonto l . . . n Bemerkung: Es gibt weitere Fehlertypen, und Kombinationen. C. Kessler, IDA, Linköpings universitet. 4 Feb. 2006
Gegenmittel: Prävention, Diagnose, Behandlung n Programmiersprache / Laufzeitsystem l Typsicherheit statische Typfehler l Exception-Konzept Laufzeitfehler l Automatische Speicherverwaltung Speicherlecks, Pointerfehler n Compiler-Frontend, IDE Syntaxfehler, statische semant. Fehler n Programmverifizierer Kontraktverletzung n Code-Inspektion [Fagan’ 76] Alle Fehlertypen n Testen und Debuggen Laufzeitfehler n Laufzeit-Schutzmonitor Zugriffsfehler n Visualisierer Kommunikationsfehler, Synchronisationsfehler C. Kessler, IDA, Linköpings universitet. 5 Feb. 2006
Exception-Konzept n PL/I (IBM) ca. 1965: ON condition … n J. B. Goodenough, POPL’ 1975 und Comm. ACM Dez. 1975 n In vielen modernen Programmiersprachen unterstützt l CLU, Ada, Modula-3, ML, C++, Java, C# n Überblick: l Fehler vs. Exception l Exception-Propagation l Geprüfte vs. ungeprüfte Exceptions l Implementierung l Exceptions in CORBA l Exceptions und Aspekt-orientierte Programmierung l Zusammenfassung und Literatur C. Kessler, IDA, Linköpings universitet. 6 Feb. 2006
Exception-Konzept 2 Arten von Laufzeitfehlern: n Fehler (error): im Programm nicht behandelbar, Programmabbruch n Ausnahme (exception): im Programm (teilweise) behandelbar l Ausgelöst (thrown) durch Laufzeitsystem bei erkanntem Laufzeitfehler oder durch das Programm selbst 4 Nachricht l Laufzeitobjekt, das eine ungewöhnliche oder Fehlersituation definiert 4 hat l an das Programm einen Typ (Exception-Klasse) 4 kann Parameter haben, z. B. String mit Klartextmeldung 4 Auch benutzerdefinierte Exceptions z. B. für Randfälle Exception-Handler: 4 enthält Code-Block zur Behandlung 4 ist statisch assoziiert mit geschütztem Code-Block, den er im Ausnahmefall ersetzt C. Kessler, IDA, Linköpings universitet. 7 Feb. 2006
Exception – Beispiel (in Java) public class 1 { public static void main ( String[] args ) { try { System. out. println("Hallo, " + args[0] ); } catch (Array. Index. Out. Of. Bounds. Exception e ) { System. out. println("Bitte ein Argument angeben! " + e); } System. out. println("Tschuess"); } } % % java class 1 Christoph % java. Christoph class 1 Hallo, Exception in thread "main" java. lang. Array. Index. Out. Of. Bounds. Exception: 0 Bitte ein Argument angeben! java. lang. Array. Index. Out. Of. Bounds. Exception: 0 Tschuess at class 1. main(class 1. java: 4) Tschuess C. Kessler, IDA, Linköpings universitet. 8 Feb. 2006
Propagation von Exceptions n Falls eine Exception nicht in der betroffenen Methode behandelt wird, wird die Methode verlassen und dieselbe Exception beim Aufrufer ausgelöst, bis entweder l ein passender Handler gefunden wird, oder l main() verlassen wird (dann Fehlermeldung und Abbruch). n Optionaler finally-Block wird jedoch immer ausgeführt l z. B. zur Rückgabe von Ressourcen n Zu klären: l Wann passt ein Handler? l Wie kann man statisch sicherstellen, dass eine bestimmte Exception irgendwann behandelt wird? l Implementierung? C. Kessler, IDA, Linköpings universitet. 9 Feb. 2006
Wann ”passt” ein Handler? Object n Exception-Klassenhierarchie n Benutzerdefinierte Exceptions durch Ableiten Throwable Error Exception Run. Time. Exception Thread. Death Virtual. Machine. Error Arithmetic. Exception … Array. Index. Out. Of. Bounds. E. Null. Pointer. Exception n Handler catch( XYException e ) {…} passt, falls XYException vom gleichen Typ oder Supertyp der ausgelösten Exception ist. C. Kessler, IDA, Linköpings universitet. Illegal. Access. Exception No. Such. Method. Exception 10 … Feb. 2006
Geprüfte und ungeprüfte Exceptions n Geprüfte (checked) Exception: muss l in einer Methode behandelt, oder l in Methodendeklaration explizit als propagiert gekennzeichnet werden: void write. Entry( … ) throws IOException { … } n Ungeprüfte (unchecked) Exception: wird implizit propagiert n In Java: Alle Exceptions sind geprüft, ausser Run. Time. Exception und deren Subtypen. n Geprüfte Exceptions: + Kapselung + statische Prüfbarkeit + wird Teil des Kontrakts einer Methode + geeignet für Komponentensysteme, z. B. CORBA – Erweiterbarkeit C. Kessler, IDA, Linköpings universitet. 11 Feb. 2006
void bar(…) { try { … } catch(E 1 e) {…} catch(E 2 e) {…} -> catch(E 1) Einfache Lösung: … n Stack von Handlern bar: -> catch(E 2) } n Bei Eintritt in geschützten Block (try {…}): -> catch(…) l Pushe alle seine Handler (catch(…) {…}) foo: -> catch(…) n Bei Auftreten einer Exception: main: -> catch(…) l Poppe obersten Handler und beginne (Test auf Exceptiontyp). Falls der nicht passt, löse wieder aus und iteriere. (Falls letzter Handler in aktueller Methode auch nicht passte, poppe auch deren Activation record => verlasse Methode. ) n Bei normalem Verlassen des try-Blocks: poppe seine Handler + einfach – Overhead (push/pop) auch bei Nichtauftreten einer Exception Implementierung Effizientere Lösung: n Compiler erzeugt Tabelle aus Paaren (try-Block, passende Handler) l Bei Auftreten einer Exception: 12 finde try-Block durch Binärsuche (PC) Feb. 2006 C. Kessler, IDA, Linköpings universitet.
Exceptions in CORBA IDL (Interface Definition Language) erlaubt benutzerdefinierte Exceptions l Sprachunabhängig l Propagation über Fernaufrufe hinweg // IDL module Book. Repository { … interface Borrowable. Collection : Collection { exception Unavailable { Date when_available; } void borrow_book ( in ISBN book_id, in Person. Name borrower, out Date return_date ) raises ( Unavailable ); }; }; C. Kessler, IDA, Linköpings universitet. 13 Feb. 2006
Exceptions und AOP n Nachteil von Exception-Behandlung: l catch()-Blöcke stören Programmübersicht l Code-Länge n Idee für Java: Exception-Behandlung als Aspekt ausfaktorisieren, mit Aspect-J einweben l Systematischer durch generische Exceptionbehandlung l Kompression des Exception-Behandlungscode um ca. 75% M. Lippert, C. Lopes: A Study on Exception Detection and Handling using Aspect-Oriented Programming. Proc. ICSE-2000, ACM. C. Kessler, IDA, Linköpings universitet. 14 Feb. 2006
Zusammenfassung, Literatur n Exceptions l Bewährtes Konzept zur Behandlung von Laufzeitfehlern l Effizient implementierbar l Geeignet für komponentenbasierte Softwareentwicklung M. Scott: Programming Language Pragmatics. Morgan Kaufmann, 2000. Abschnitt 8. 5 über Exception Handling. J. Goodenough: Structured Exception Handling. ACM POPL, Jan. 1975 J. Goodenough: Exception Handling: Issues and a proposed notation. Communications of the ACM, Dec. 1975 B. Ryder, M. Soffa: Influences on the Design of Exception Handling, 2003 Konferenzen ACM POPL und OOPSLA C. Kessler, IDA, Linköpings universitet. 15 Feb. 2006
Feb. 2006 Debugging Debuggen vs. Testen Debugging-Methoden und Werkzeuge Debugger-Technologie Debuggen nebenläufiger Programme Zusammenfassung, Literatur Christoph Kessler, IDA, Linköpings universitet, 2006.
Debugging n Testen: kann Existenz eines Fehlers feststellen (ohne Garantie auf Vollständigkeit!) l Vergleiche Ausgabe des Testkandidaten mit Referenzausgabe (z. B. älterer, korrekter Version – Regressionstesten, z. B. DEJAGNU) n Debuggen: lokalisiere Fehler: l Iterativer Prozess l Systematisches Eingrenzen Fehler entdeckt Initiale Hypothesenmenge Ursache Modifiziere Hypothesenmenge Wähle Hypothese Effekt Verifiziere Hypothese nein Fehler beseitigt? ja C. Kessler, IDA, Linköpings universitet. 17 Feb. 2006
Debugging-Techniken und Werkzeuge (1) n Manuelle Methoden l Statisch: Code-Inspektion l Dynamisch: print-Anweisungen, Validierung von Zusicherungen (assert() ) n Werkzeuge für die manuelle Fehlersuche: l Symbolischer Debugger 4 z. B. l dbx, gdb, jdb, ddd Debug-Problem-Dokumentation 4 z. B. l BUGZILLA (Fehler-Datenbank + Web-Interface) Laufzeit-Schutz-Monitorsystem ibs. für Zugriffsfehler 4 Electric. Fence, C. Kessler, IDA, Linköpings universitet. VALGRIND, Java VM, INSURE++, PURIFY, … 18 Feb. 2006
Debugging-Techniken und Werkzeuge (2) n Automatisches Debugging: Formale Verifikation gegen formale Spezifikation des Programms 4 Oft keine oder unvollständige formale Spezifikation verfügbar 4 Ggf. Spezifikation herleitbar, aber dann selbst fehleranfällig l Durchsuche Quellprogramm nach sprachspezifischen Fehler-Idiomen 4 z. B. lint, splint, jlint 4 unvollständig l Fehlersuchbereich eingrenzen durch statische Analyse: 4 Program Slicing [Weiser’ 82] [Lyle, Weiser’ 87] 4 Program Dicing (Differenz zweier Slices) [Lyle, Weiser’ 87] 4 z. B. UNRAVEL slicer [Lyle’ 95] 4 Braucht gute statische Analyse (DFA, points-to-Analyse) 4 Konservative statische Approximation – Slices werden schnell gross l Delta-Debugging 4 Automatisches Eingrenzen durch Binärpartitionierung (Eingabedaten, Code) l C. Kessler, IDA, Linköpings universitet. 19 Feb. 2006
Symbolischer Debugger (1) n Braucht Information über Namen und Typ von Speicherstellen auf Quellcode-Niveau l d. h. , die Symboltabelle und Typtabelle des Compilers l Wird bei Bedarf eingefügt (cc –g … ) n Braucht Koordinaten der Programmpunkte im Quellcode (z. B. Zeilennr. ) n Braucht enge Kontrollfluss-Übereinstimmung zwischen Quellcode und Maschinencode l Unverträglich mit aggressiven Programmoptimierungen z. B. Prefetching, Loop-invariant code hoisting, Schleifentransformationen, Scheduling l Trade-Off Code-Effizienz Debugger-Transparenz Kann unter gewissen Umständen dazu führen, dass der Fehler mit Debugger nicht auftritt (gilt auch für print-debugging) n Graphische Oberfläche (z. B. ddd, Eclipse Debug-View) über Kommandozeilen-Debugger (z. B. dbx, gdb, jdb) l C. Kessler, IDA, Linköpings universitet. 20 Feb. 2006
Symbolischer Debugger (2) n Post-Mortem-Debugging l Nach Absturz: Lies core-file; inspiziere Speicherinhalt, Variablenwerte n Interaktives Debuggen l Berechnung anhalten l Breakpoints (Haltepunkte) setzen, löschen l Schritt-für-Schritt-Ausführung l Ausgabe von Werten, Ausdrucksauswertung (Interpreter) l Variablenwerte ändern l Aufrufkeller inspizieren l Aufrufkette entlangwandern C. Kessler, IDA, Linköpings universitet. 21 Feb. 2006
Debugger-Technik mit OS/HW-Support Debugger-Prozess Zu debuggender Prozess OS OS-IRC fork() (via OS) ptrace() (via OS): ”trace me” signal() (via OS): ”stop” wait() (via OS) ptrace() (via OS) Lese, schreibe Werte im Adressraum; füge breakpoints (Spezialinstruktionen) in Code ein … signal() (via OS): ”resume” signal(): ”Breakpoint” … Finde Breakpunkt: trap signal(): ”continue” C. Kessler, IDA, Linköpings universitet. 22 Feb. 2006
Debuggen nebenläufiger Programme Problem: Auftreten des Fehlers kann vom Schedule abhängen Lauf 1: CPU Thread 1 Lauf 2: CPU Thread 2 l Thread 2 Thread 1 Thread 2 t Thread 2 Thread 1 Nichtdeterminismus schwer, Fehler zu reproduzieren n Lösung 1: Deterministic replay Eingaben und Schedule aufzeichnen, l z. B. DEJAVU für Java l n Lösung 2: Statische Analyse (möglicher Parallelismus, ”Data-races”) n Lösung 3: Dynamische Analyse l identifiziert shared-memory-Zugriffe zur Laufzeit n Lösung 4: Test-basierter Ansatz mit Delta-Debugging [Choi, Zeller ’ 02] l In Kombination mit DEJAVU C. Kessler, IDA, Linköpings universitet. 23 Feb. 2006
Zusammenfassung und Literatur n Testen vs. Debuggen n Debugging-Methoden n Debugger-Technologie n Debuggen nebenläufiger Programme n M. Scott: Programming Language Pragmatics, Morgan Kaufmann 2000. Abschnitt über Debugging n Srikant, Shankar: Compiler Design Handbook, CRC press 2003, Kap. 9 über Debugger-Technologie (von Aggarwal und Kumar) n J. Rosenberg: How Debuggers Work. Wiley, 1996. n A. Zeller: Why Programs Fail. A Guide to Systematic Debugging. Morgan Kaufmann, 2005. n A. Zeller, J. Krinke: Open-Source Programmierwerkzeuge. Dpunkt, 2003. C. Kessler, IDA, Linköpings universitet. 24 Feb. 2006
- Slides: 24