Exception

Werbung
Feb. 2006
Fehlerbehandlung
in Programmiersystemen
Christoph Kessler
Universität Linköping, Schweden
 Fehler-Klassifikation
 Behandlung statischer Fehler
 Behandlung von Laufzeitfehlern

Exception-Konzept

Debugging
Christoph Kessler, IDA,
Linköpings universitet, 2006.
Programmierfehler…
 Ein erheblicher Teil der Gesamtkosten eines Softwareprojektes
entfällt auf Testen, Fehlersuche und -behebung.
 Welche Fehlertypen können auftreten?

Klassifikation
 Prävention, Diagnose, Behandlung

Programmiersprachliche Konzepte

Compiler, IDE

Sonstige Werkzeuge: Debugger, Verifizierer, ...
C. Kessler, IDA, Linköpings universitet.
2
Feb. 2006
Programmierfehler – Klassifikation (1)
 Syntaktische Fehler

Syntaxfehler
z.B. vergessenes Semikolon
 Semantische Fehler

Statische semantische Fehler
 Statische Typfehler
Falscher Parametertyp;
Downcast ohne Laufzeit-Überprüfung
 Nicht

deklarierte Variable
Laufzeitfehler 
 Logische Fehler

Algorithmische Fehler
vergessener Spezialfall,
Nichtterminierung
Akkumulation von Rundungsfehlern
Verletzung geforderter Invarianten
 Numerische

Fehler
Kontraktverletzung
C. Kessler, IDA, Linköpings universitet.
3
Feb. 2006
Programmierfehler – 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.
C. Kessler, IDA, Linköpings universitet.
4
Feb. 2006
Gegenmittel:
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 [Fagan’76]  Alle Fehlertypen
 Testen und Debuggen
 Laufzeitfehler
 Laufzeit-Schutzmonitor
 Zugriffsfehler
 Visualisierer
 Kommunikationsfehler,
Synchronisationsfehler
C. Kessler, IDA, Linköpings universitet.
5
Feb. 2006
Exception-Konzept
 PL/I (IBM) ca. 1965: ON condition …
 J. B. Goodenough, POPL’1975 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
C. Kessler, IDA, Linköpings universitet.
6
Feb. 2006
Exception-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

Laufzeitobjekt, das eine ungewöhnliche oder Fehlersituation definiert
 hat

an das Programm
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
C. Kessler, IDA, Linköpings universitet.
7
Feb. 2006
Exception – Beispiel (in Java)
public class class1 {
public static void main ( String[] args ) {
try {
System.out.println("Hallo, " + args[0] );
}
catch (ArrayIndexOutOfBoundsException e ) {
System.out.println("Bitte ein Argument angeben! " + e);
}
System.out.println("Tschuess");
}
}
%
% java
java class1
class1 Christoph
%
javaChristoph
class1
Hallo,
Exception
in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
Bitte
ein Argument angeben! java.lang.ArrayIndexOutOfBoundsException: 0
Tschuess
at class1.main(class1.java:4)
Tschuess
C. Kessler, IDA, Linköpings universitet.
8
Feb. 2006
Propagation 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?
C. Kessler, IDA, Linköpings universitet.
9
Feb. 2006
Wann ”passt” ein Handler?
Object
 Exception-Klassenhierarchie
 Benutzerdefinierte
Exceptions durch Ableiten
Throwable
Error
Exception
RunTimeException
ThreadDeath
VirtualMachineError
ArithmeticException
…
ArrayIndexOutOfBoundsE
NullPointerException
 Handler catch( XYException e ) {…}
passt, falls XYException vom
gleichen Typ oder Supertyp der
ausgelösten Exception ist.
C. Kessler, IDA, Linköpings universitet.
IllegalAccessException
NoSuchMethodException
10
…
Feb. 2006
Geprü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
C. Kessler, IDA, Linköpings universitet.
11
Feb. 2006
void bar(…) {
try { … }
catch(E1 e) {…}
catch(E2 e) {…}
Einfache Lösung:
-> catch(E1)
…
 Stack von Handlern
bar: -> catch(E2)
}
 Bei Eintritt in geschützten Block (try {…}):
-> catch(…)
 Pushe alle seine Handler (catch(…) {…})
foo: -> catch(…)
 Bei Auftreten einer Exception:
main: -> catch(…)
 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.)
 Bei normalem Verlassen des try-Blocks: poppe seine Handler
+ einfach
– Overhead (push/pop) auch bei Nichtauftreten einer Exception
Implementierung
Effizientere Lösung:
 Compiler erzeugt Tabelle aus Paaren (try-Block, passende Handler)
Auftreten
finde try-Block durch Binärsuche (PC)
Feb. 2006
C. Kessler, 
IDA, Bei
Linköpings
universitet. einer Exception: 12
Exceptions in CORBA
 CORBA IDL (Interface Definition Language)
erlaubt benutzerdefinierte Exceptions

Sprachunabhängig

Propagation über Fernaufrufe hinweg
// IDL
module 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 );
};
};
C. Kessler, IDA, Linköpings universitet.
13
Feb. 2006
Exceptions und AOP
 Nachteil von Exception-Behandlung:

catch()-Blöcke stören Programmübersicht

Code-Länge
 Idee für Java:
Exception-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.
C. Kessler, IDA, Linköpings universitet.
14
Feb. 2006
Zusammenfassung, 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
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
 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:

Iterativer Prozess

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)
 Manuelle Methoden

Statisch: Code-Inspektion

Dynamisch: print-Anweisungen,
Validierung von Zusicherungen (assert() )
 Werkzeuge für die manuelle Fehlersuche:

 z.B.

dbx, gdb, jdb, ddd
Debug-Problem-Dokumentation
 z.B.


Symbolischer Debugger
BUGZILLA (Fehler-Datenbank + Web-Interface)
Laufzeit-Schutz-Monitorsystem ibs. für Zugriffsfehler
 ElectricFence,
C. Kessler, IDA, Linköpings universitet.
VALGRIND, Java VM, INSURE++, PURIFY, …
18
Feb. 2006
Debugging-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 [Weiser’82] [Lyle, Weiser’87]
 Program Dicing (Differenz zweier Slices) [Lyle, Weiser’87]
 z.B. UNRAVEL slicer [Lyle’95]
 Braucht gute statische Analyse (DFA, points-to-Analyse)
 Konservative statische Approximation – Slices werden schnell gross
Delta-Debugging
 Automatisches Eingrenzen durch Binärpartitionierung
(Eingabedaten, Code)
C. Kessler, IDA, Linköpings universitet.
19
Feb. 2006
Symbolischer 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 Programmoptimierungen
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)
C. Kessler, IDA, Linköpings universitet.
20
Feb. 2006
Symbolischer 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
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

Thread 2
Thread 1
Thread 1
Thread 2
t
Thread 2 Thread 1
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
C. Kessler, IDA, Linköpings universitet.
23
Feb. 2006
Zusammenfassung 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.
C. Kessler, IDA, Linköpings universitet.
24
Feb. 2006
Herunterladen