Open Source im professionellen Einsatz

Newsletter abonnieren
Seite durchsuchen

HEFTARCHIV | NEWS | E-BIBLIOTHEK | VIDEO | BLOGS | WHITEPAPER | EVENTS | ACADEMY | ABO | SHOP

user friendly

  Home  »  Heft & Abo  »  Heftarchiv  »  2007  »  01  »  Getriebeschaden  

RSS-Feed der aktuellen News von Linux-Magazin Online Folgen Sie Linux-Magazin Online auf Twitter
Diesen Artikel druckenDiesen Artikel weiterempfehlen Diesen Artikel kommentieren Newsletter abonnieren
Share/Bookmark

© pixelquelle.de

Mit dem Gnu-Debugger auf Inspektion in Perls Mechanik

Getriebeschaden

von Michael Schilli
Erschienen im Linux-Magazin 2007/01

Dreht sich das Perl-Rad nur noch knirschend, sind vielleicht Fehler im Perl-Interpreter oder in Erweiterungsmodulen schuld. Der gute alte GDB inspiziert das Getriebe und kommt Problemstellen auf die Schliche.

Wer in Perl statt in C oder C++ programmiert, nimmt es oft als selbstverständlich hin, dass ihm viel unnütze Arbeit erspart bleibt: Speicher reservieren und freigeben, Referenzen zählen, auf wild gewordene Pointer aufpassen - derlei Sisyphusarbeit hält Perls virtuelle Maschine vom Programmierer fern, damit der sich auf das Implementieren konzentrieren kann.

Doch auch tief unten im Maschinenraum können Fehler auftreten. Es kommt zwar sehr selten vor, dass ein Bug in einer Perl-Release die in C implementierte virtuelle Maschine zum Absturz bringt. Häufiger aber können handgeschriebene Perl-Erweiterungen eines unachtsamen C/C++-Entwicklers dafür eine mögliche Ursache sein.

Nur in Ausnahmefällen stürzt der Perl-Interpreter »perl« so richtig ab, wenn es aber doch passiert, hilft auch der Perl-Debugger [2] nicht mehr weiter. Das Skript in Listing 1 führt zum Beispiel mit Hilfe einer C-Erweiterung bewusst einen Absturz des Interpreters mit einem Segmentation Fault herbei.

Listing 1:
»crash«

01 #!/usr/bin/perl -w
02 use strict;
03 use Inline "C";
04 use Inline Config =>
05    CLEAN_AFTER_BUILD => 0;
06 
07 c_crash(43);
08 
09 __END__
10 __C__
11 int c_crash( int num ) {
12  char *cp = 0xcba00000;
13  strcpy(cp, "Ouch!");
14 }

Linux zieht den Teppich weg

Das Beispiel bedient sich hierzu des CPAN-Moduls Inline, das angehängten C-Code kompiliert und dynamisch in das Skript einbindet. Der C-Code nach der »__END__«-Markierung setzt einen Pointer auf die Adresse »0xcba00000« und lässt dann die C-Funktion »strcpy« rücksichtslos an dieser, zumindest in der 32-Bit-x86-Architektur geschützten Kerneladresse schreiben. Der Prozessor merkt das, löst einen Interrupt aus und der Linux-Kernel zieht daraufhin dem schuldigen Programm den Teppich unter den Füßen weg.

Abbildung 1 zeigt, wie das Perl-Skript für die Reproduktion des Fehlers im Gnu-Debugger »gdb« aufzurufen ist. Das ausführende Binärprogramm ist der Perl-Interpreter, also startet der Debugger mit »gdb perl«. Um dann das Perl-Skript »crash« vom Interpreter abarbeiten zu lassen, ruft man im Debugger das Kommando »run crash« auf. Nach dem Absturz liefert »gdb« nicht nur den C-Code jener Zeile, die den Crash auslöste. Das Debugger-Kommando »bt« (für Backtrace, alternativ funktioniert auch »where«) zeigt zusätzlich die aufrufende C-Funktionshierarchie im so genannten Stacktrace an.


Abbildung 1: Eine »gdb«-Session analysiert den Stacktrace des Perl-Skripts.

Damit der Debugger ausgeführte Funktionen den Zeilennummern im C-Sourcecode zuordnen kann, muss der Fehlersucher sein Perl zuvor mit dem Compiler-Flag »-g« kompiliert haben. Auf die Frage des Konfigurationsskripts: »What optimizer/debugger flag should be used?« sollte er dazu »-g« antworten oder das Skript gleich mit »./Configure -D optimize=-g -d« aufrufen.

Versäumt er dies, ist die Analyse mangels Referenzen zum C-Sourcecode schwieriger, und wenn das Executable auch noch gestrippt ist, sieht es ganz düster aus, denn disassemblierten Assemblercode verstehen bleibt langbärtigen Gurus vorbehalten. Aber auch aus einem normal kompilierten »perl« lassen sich Informationen herausholen. Die Autopsie gestaltet sich dann zwar schwieriger, doch ein Trick, dessen Erklärung weiter unten folgt, hilft dabei, exzessives Jonglieren mit Hex-Zahlen zu vermeiden.

Obduktion der Skriptleiche

Kommt es in einem laufenden Programm zum Crash, erzeugt der Linux-Kernel normalerweise eine Core-Datei. Ist dies nicht der Fall, unterdrückt die Bash wahrscheinlich die Core-Produktion mit der Standardeinstellung »ulimit -c 0«. Lautet die Einstellung hingegen »ulimit -c unlimited«, dann entsteht eine Core-Datei (»core« oder auch »core.PID« mit angehängter Prozess-ID):

$ ./crash
Segmentation fault (core dumped)
$ ls -l core.*
-rw------- 1 mschilli mschilli 1658880 Nov 3 21:30 core.1234

Der so genannte Core-Dump liegt normalerweise in dem aufrufenden Verzeichnis, es sei denn, in »/proc/sys/kernel/core_pattern« ist etwas anderes definiert. Wer herausfinden will, was den Crash ausgelöst hat, ruft den Debugger post mortem mit dem ausführenden Programm und dem Core-File auf (beispielsweise »gdb perl core.1234«). Er erhält eine ähnliche Debugger-Session, wie sie in Abbildung 1 zu sehen ist. Aus ihr lässt sich ebenfalls der Stacktrace kurz vor dem Absturz ermitteln. Zu starten ist ein solcher Speicher-Schnappschuss allerdings nicht mehr.

Diesen Artikel druckenDiesen Artikel weiterempfehlen Diesen Artikel kommentieren Newsletter abonnieren
Share/Bookmark
Ähnliche Artikel
Prozess-Spion Perl-Skript nutzt Ptrace zur Prozessüberwachung
Zum Angriff auf die Bugs OpenGL-Anwendungen debuggen mit Bugle
Compiler-Rallye Intels C-Compiler 9.0
Tierische Kurssprünge Börsenkurs-Alerting im Eigenbau
Babylon zu fünft Populäre Programmiersprachen treten gegeneinander an
Rechenleistung für alle Gigaflops, bezahlbare Hardware, GPU-Computing, Compilerfarmen
Whitepaper
The Role of Open Source in Data Integration

Obwohl in den letzten Jahren viele technische Fortschritte erzielt werden konnten, verfügen die meisten Datenintegrationsprozesse nach wie vor nur über eine sehr begrenzte Automatisierung. Das vorliegende White Paper von dem Industry Analyst Mark Madson wird zunächst ein grundlegendes Verständnis von Daten Integration vermitteln, die Vorzüge von Open Source Lösungen für Daten Integration erläutern und Ihnen professionelle Empfehlungen geben, damit Sie Ihre Integrationsjobs noch einfacher und produktiver gestalten können.

Download PDF (Registrierung erforderlich)
Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele (Folge 2)

Der zweite Teil des Open Source Datenintegration in der Praxis: Fallstudien und Anwendungsbeispiele White Papers beleuchtet anhand weiterer ausgewählter Case Studies die Implementierung von Open Source Datenintegration in der Praxis und benennt die daraus resultierenden Vorteile.

Download PDF (Registrierung erforderlich)
Kommentare (0)