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