User since
2005-04-06
3
Artikel
BenutzerIn
Ich habe einige Perl-Programme, die Daten in der Gigabyte-Größenordnung bearbeiten und daher ziemlich lange laufen - so mehrere Stunden lang. Dummerweise brechen manche Programme dabei ab, ohne eine Fehlermeldung, etwa auf STDERR, zu hinterlassen. Die Programme sind dabei als Filter realisiert, d.h. die zu bearbeitenden Textdaten werden mittels while(<>) von STDIN eingelesen.
Mein erster Gedanke war natürlich ein Memory Leak, aber wenn ich das Programm mit >>ps o vsz,args<< überwache, kann ich kein Leak entdecken. Ich benutze Perl 5.8.4 auf einem Debian Linux mit einem 2.6.8er Kernel.
Meine Frage ist nun nicht, was konkret an meinen Programmen schief läuft, sondern welche Möglichkeiten es gibt, solche lang laufenden Programme zu debuggen. Das normale Debugging (Einzelschrittabarbeitung) mit dem Perl-Debugger macht hier ja wohl wenig Sinn, da ein Fehler, wenn überhaupt, erst nach hundertausenden von Durchläufen (=Zeilen von STDIN) auftritt.
Gibt's es womöglich eine Debuggingfunktion, die mir sagt, in welcher Zeile sich ein Programm verabschiedet hat?
Danke und viele Grüße!
Stefan
User since
2004-01-29
828
Artikel
BenutzerIn
Wie ist denn der return value?
User since
2005-04-06
3
Artikel
BenutzerIn
Hallo z80crew,
das Problem habe ich auch täglich ;-))
Die Lösung, die ich gewählt habe sind Logfiles in beliebieger Zusammenstellung. Da soll heißen, daß ich einen Flag habe, mit dem ich auch meinen "Debug"-Mode einschalten kann und mir noch mehr Infos ins Logfile ausgeben kann. Die Logfiles kannst du dann nach belieben auswerten ...
Hoffe ich konnte eine Idee geben.
Grüße,
skycat
User since
2003-08-04
14371
Artikel
ModeratorIn
Wie man debugging-Meldungen machen kann:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#! /usr/bin/perl
use strict;
use warnings;
unless(open(FILE,"<$ARGV[0]")){
print_debug("Kann Datei $ARGV[0] nicht öffnen!");
}
else{
while(my $line = <FILE>){
print $line;
}
close FILE;
}
print_debug("Ein anderer Fehler");
#------------------------------------------------------#
# Subroutines #
#------------------------------------------------------#
sub print_debug{
my ($msg) = @_;
my ($package,$filename,$line) = caller();
my $logfile = "./skript.log";
if(open(LOG,">>$logfile")){
print LOG $filename," ",$line,": ",$msg,"\n";
close LOG;
}
}# end print_debug
User since
2005-04-06
3
Artikel
BenutzerIn
Wow, das ging ja fix wie nix. Danke erstmal!
Logging bzw. eigene Debugging-Meldungen:
Mach ich bereits recht ausführlich, vermutlich aber noch nicht ausführlich genug. Ich werde also versuchen, das noch auszuweiten.
return-Value:
Ups, daran hab ich natürlich noch nicht gedacht. Werde ich auch gleich mal ausprobieren.
Nochmals danke bis hierher.
Stefan
User since
2005-04-06
3
Artikel
BenutzerIn
Zeilenausgaben kannst du mit dem Token für Line direkt ins Logfile mit aufnehmen.
siehe hierzu auch:
http://de.selfhtml.org/perl/sprache/tokens.htm
Grüße,
skycat\n\n
<!--EDIT|skycat|1112785745-->
User since
2005-04-06
3
Artikel
BenutzerIn
So, bin inzwischen ein gutes Stück weitergekommen. Meine Debuggingidee:
Ich hab für so ziemlich alle denkbaren Signale einen Handler eingerichtet.
$SIG{'INT'} = \&got_sig;
$SIG{'HUP'} = \&got_sig;
$SIG{'KILL'} = \&got_sig;
...
In got_sig() steht lediglich:
my $sig = shift;
syswrite STDERR, "ERROR: $sig - $!\n";
Damit hab ich nun folgende Fehlermeldung gefunden:
ERROR: HUP - Ungültiger Dateideskriptor
D.h. das Skript bekam nach etwa einer halben Mio. Durchläufen ein SIGHUP verpasst aus dem angegebenen Grund. Warum das aber ohne diesen Handler nicht nach STDERR geschrieben wurde, weiß ich auch nicht ...