Moin, Ich arbeite an einem Script, welches in einer Schleife etliche verschiedene Fonts verwendet, um per ImageMagick einen Text in ein Bild zu schreiben. Da auch mal ein Font kaputt ist oder ImageMagick einen Bug hat oder oder oder... kann es sein, daß IM dabei einen Speicherzugriffsfehler erzeugt. Den will und muß ich abfangen (Andere Lösungen wie das Entfernen des kaputten Fonts sind nciht möglich, das zu erklären würde zu weit führen) Also, Pseudocode, was ich habe: foreach $schrift (@schriften) { $bild=generiere_preview($schrift); mach_was_mit($bild); } sub generiere_preview($name) { $bild=mache_bild_aus_schrift($name); return $bild } Wenn auch nur eine Schrift kaputt ist: Bumm. Was ich bräuchte, wäre: sub generiere_preview($name) { $SEGFAULTS='egal'; $bild=mache_bild_aus_schrift($name); $SEGFAULTS='wieder beachten'; if($error) { return false; } else { return $bild; } } Ich habe mit fork() rumhantiert, aber nichts vernünftiges hinbekommen. Ich habe sowas probiert: $SIG{'SEGV'} = 'IGNORE'; $img->Annotate( x => 128, y => 128+256, pointsize => 256, font => $filename, text => $text ); } $SIG{'SEGV'} = 'DEFAULT'; Das bricht aber trotzdem ab, und zwar ziemlich chaotisch - mal geht eine Datei, mal nicht. Ein anderer Versuch: eval { local $SIG{'__DIE__'}; Annotate... }; Ebenfalls unberechenbar. Ich habe zu Testzwecken die dicke Kanone rausgeholt und alle Signale geblockt: foreach my $i (keys(%SIG)) { $SIG{$i} = 'IGNORE'; } Ne, ne, ne. Geht nicht. Das Problem ist wohl, daß ein SegFault ein ziemlicher Hammer ist und die beteiligten Prozesse reichlich verwirrt zurücklässt. Ich habe den Eindruck, daß eigentlich fork'en der richtige Weg wäre. Wenn die geforkte Version absemmelt, macht das Original weiter, ansonsten wird das Original beendet und die Kopie mit den ermittelten Daten läuft weiter. Genau das bekomme ich aber nicht hin. Ich habe eine Variante, die eine Datei schreibt und dann "so oder so" beendet, das geht aber in diesem Fall nicht, ich brauche eine "sub", die "so oder so" etwas returniert, entweder das Preview oder ein false, aber nie ganz wegbricht. Ich habe die perl-doku zu forks, Zwischenprozess-Kommunikation und pipes gelesen, nur ein bisschen begriffen und müsste jetzt mal ein bisschen in die richtige Richtung gedreht werden. :-) Gruß, Ratti -- -o) fontlinge | Font management for Linux | Schriftenverwaltung in Linux /\\ http://freshmeat.net/projects/fontlinge/ _\_V http://www.gesindel.de https://sourceforge.net/projects/fontlinge/
On Sunday 22 June 2003 21:54, Joerg Rossdeutscher wrote:
Da auch mal ein Font kaputt ist oder ImageMagick einen Bug hat oder oder oder... kann es sein, daß IM dabei einen Speicherzugriffsfehler erzeugt. Den will und muß ich abfangen (Andere Lösungen wie das Entfernen des kaputten Fonts sind nciht möglich, das zu erklären würde zu weit führen)
Äh - stehe ich auf dem Schlauch? Sehe ich das Problem eigentlich nicht?
ImageMagick mit "system" aufrufen und schlicht und einfach den Return-Code
auswerten?
Aus "perldoc -f system":
Because "system" and backticks block "SIGINT" and
"SIGQUIT", killing the program they're running
doesn't actually interrupt your program.
@args = ("command", "arg1", "arg2");
system(@args) == 0
or die "system @args failed: $?"
You can check all the failure possibilities by
inspecting $? like this:
$exit_value = $? >> 8;
$signal_num = $? & 127;
$dumped_core = $? & 128;
CU
--
Stefan Hundhammer
Moin, Am Mon, 2003-06-23 um 11.22 schrieb Stefan Hundhammer:
On Sunday 22 June 2003 21:54, Joerg Rossdeutscher wrote:
Da auch mal ein Font kaputt ist oder ImageMagick einen Bug hat oder oder oder... kann es sein, daß IM dabei einen Speicherzugriffsfehler erzeugt. Den will und muß ich abfangen (Andere Lösungen wie das Entfernen des kaputten Fonts sind nciht möglich, das zu erklären würde zu weit führen)
Äh - stehe ich auf dem Schlauch? Sehe ich das Problem eigentlich nicht? ImageMagick mit "system" aufrufen und schlicht und einfach den Return-Code auswerten?
Das ruft IM über die Shell auf. Mit der Methode wird die Kiste noch bis zur nächsten Eiszeit rechnen. :-) ImageMagick ist direkt als Per-lModul verfügbar. Etwa so: use Image::Magick; $img=Image::Magick->new( size => '512x512', background => 'white', depth => 8); $img->ReadImage("xc:white"); $img->Annotate( x=> 128, y => 128+256, pointsize => 256, font => $filename, fill => 'black', undercolor => 'white', text => $text ); $img->Quantize( colors => 2, dither => 0); $img->Set( matte => 0); $img->Trim(); $img->Resize( width => 256, height => 256, blur => 0 ); Guck dir mal den "Annotate"-Befehl da oben an. Wenn da $filename auf einen kaputten Font zeigt, dann semmelt das ganze Programm weg. Das muß ich unterbinden, weil das alles in einer Schleife geschieht und drei Tage Rechenzeit hier völlig normal sind. Ich kann nicht jedesmal das Programm neustarten, weil einer von 1000 Fonts kaputt ist. Oder wohlmöglich nicht mal kaputt, sondern IM einen Bug hat. Gruß, Ratti -- -o) fontlinge | Font management for Linux | Schriftenverwaltung in Linux /\\ http://freshmeat.net/projects/fontlinge/ _\_V http://www.gesindel.de https://sourceforge.net/projects/fontlinge/
Moin, Am Mon, 2003-06-23 um 19.34 schrieb Joerg Rossdeutscher:
Am Mon, 2003-06-23 um 11.22 schrieb Stefan Hundhammer:
On Sunday 22 June 2003 21:54, Joerg Rossdeutscher wrote:
Da auch mal ein Font kaputt ist oder ImageMagick einen Bug hat oder oder oder... kann es sein, daß IM dabei einen Speicherzugriffsfehler erzeugt. Den will und muß ich abfangen (Andere Lösungen wie das Entfernen des kaputten Fonts sind nciht möglich, das zu erklären würde zu weit führen)
So, wenn mir keiner hilft, muß ich's halt selber rausfinden. :-) Nochmal in Kurzfassung: Ich will SEGV's abfangen, das Programm soll weiterlaufen, als wäre nichts gewesen. Und zwar lediglich für die Dauer eines Annotate-Befehls für Perlmagick, weil der auf einen kaputten Font stoßen könnte. Würdet ihr das hier als einigermaßen saubere Lösung erachten? sub read_image_fnt { my $filename=shift(@_); my $text=shift(@_); my $img; $img=Image::Magick->new( size => '512x512', background => 'white', depth => 8); $img->ReadImage( "xc:white"); # Hier wird es lustig foreach my $i (keys(%SIG)) { $SIG{$i} = sub { goto SEGV;} } # Dieser Befehl kann crashen eval { $img->Annotate( x => 128, y => 128+256, pointsize => 256, font => $filename, fill => 'black', undercolor => 'white', text => $text ); }; foreach my $i (keys(%SIG)) { $SIG{$i} = 'DEFAULT'; } return $img; SEGV: return ""; } Prinzipiell habe ich ein schlechtes Gefühl, wegen GOTO. Gruß, Ratti -- -o) fontlinge | Font management for Linux | Schriftenverwaltung in Linux /\\ http://freshmeat.net/projects/fontlinge/ _\_V http://www.gesindel.de https://sourceforge.net/projects/fontlinge/
On Sunday 29 June 2003 23:21, Joerg Rossdeutscher wrote:
Nochmal in Kurzfassung: Ich will SEGV's abfangen, das Programm soll weiterlaufen, als wäre nichts gewesen. Und zwar lediglich für die Dauer eines Annotate-Befehls für Perlmagick, weil der auf einen kaputten Font stoßen könnte.
Würdet ihr das hier als einigermaßen saubere Lösung erachten?
Eigentlich nicht...
Wenn Du einen Segfault bekommst, ist ziemlich undefiniert, in welchem Zustand
die Variablen Deines Prozesses sind. Etwas völlig anderes zu machen (als das,
was Dein Programm normalerweise tut) und das Programm beenden (auch ohne
Core) ist zu verantworten. Wenn Du aber dann das gleiche nochmal startest
bzw. auch nur das Perl-Modul weiter verwendest, das den Segfault ausgelöst
hat, kann sonstwas passieren: In welchem Zustand sind dann die internen
Variablen dieses Moduls? Kann man es ggf. schaffen, daß Perl-Referenzen dann
in die Pampa zeigen - sozusagen "dangling pointers" in Perl?
OhGottOhGottOhGott...
Du kannst es ausprobieren, aber ich halte das für eine äußerst wackelige
Lösung.
CU
--
Stefan Hundhammer
Am Mon, 2003-06-30 um 13.12 schrieb Stefan Hundhammer:
On Sunday 29 June 2003 23:21, Joerg Rossdeutscher wrote:
Nochmal in Kurzfassung: Ich will SEGV's abfangen, das Programm soll weiterlaufen, als wäre nichts gewesen. Und zwar lediglich für die Dauer eines Annotate-Befehls für Perlmagick, weil der auf einen kaputten Font stoßen könnte.
Würdet ihr das hier als einigermaßen saubere Lösung erachten?
Eigentlich nicht...
Wenn Du einen Segfault bekommst, ist ziemlich undefiniert, in welchem Zustand die Variablen Deines Prozesses sind. Etwas völlig anderes zu machen (als das, was Dein Programm normalerweise tut) und das Programm beenden (auch ohne Core) ist zu verantworten. Wenn Du aber dann das gleiche nochmal startest bzw. auch nur das Perl-Modul weiter verwendest, das den Segfault ausgelöst hat, kann sonstwas passieren: In welchem Zustand sind dann die internen Variablen dieses Moduls? Kann man es ggf. schaffen, daß Perl-Referenzen dann in die Pampa zeigen - sozusagen "dangling pointers" in Perl?
OhGottOhGottOhGott...
Du kannst es ausprobieren, aber ich halte das für eine äußerst wackelige Lösung.
Hmmm... betrachten wir mal die Alternativen. Das Programm läuft mehrere Tage Nonstop, um der Datenflut Herr zu werden. Es darf nicht abgebrochen werden. Der SegFault führt dazu, daß mit der nächsten Datei weitergearbeitet wird, die Ressourcen der auslösenden Datei werden nicht weiter genutzt, der Segfault wird ja bemerkt. Diese Ressourcen werden vermutlich "angeschossen" zurückbleiben, das sollte aber von der Menge her vertretbar sein. Da sie nicht mehr genutzt werden, sollten sie nichts mehr anrichten. Natürlich wäre das beste, ImageMagick würde nicht wegbrechen, aber ehrlich gesagt halte ich für völlig unmöglich, alle Fehler bei der Interpretation einer Fontdatei abzufangen, das ist höllisch komplex. Was gäbe es denn noch für Methoden, ein Programm, das sehr viele Daten verarbeitet zu hindern, mittendrin an unverwendbaren Files wegzubrechen? Gruß, Ratti -- -o) fontlinge | Font management for Linux | Schriftenverwaltung in Linux /\\ http://freshmeat.net/projects/fontlinge/ _\_V http://www.gesindel.de https://sourceforge.net/projects/fontlinge/
Hallo, Am Montag, 30. Juni 2003 22:09 schrieb Joerg Rossdeutscher:
Hmmm... betrachten wir mal die Alternativen. Das Programm läuft mehrere Tage Nonstop, um der Datenflut Herr zu werden. Es darf nicht abgebrochen werden.
Der SegFault führt dazu, daß mit der nächsten Datei weitergearbeitet wird, die Ressourcen der auslösenden Datei werden nicht weiter genutzt, der Segfault wird ja bemerkt. Diese Ressourcen werden vermutlich "angeschossen" zurückbleiben, das sollte aber von der Menge her vertretbar sein. Da sie nicht mehr genutzt werden, sollten sie nichts mehr anrichten.
Natürlich wäre das beste, ImageMagick würde nicht wegbrechen, aber ehrlich gesagt halte ich für völlig unmöglich, alle Fehler bei der Interpretation einer Fontdatei abzufangen, das ist höllisch komplex.
Was gäbe es denn noch für Methoden, ein Programm, das sehr viele Daten verarbeitet zu hindern, mittendrin an unverwendbaren Files wegzubrechen?
Wie wär's mit einem kontrollierendem Prozess, der das eigentliche Pragramm im Auge behält und dieses erneut startet falls es an einem kaputten Font gescheitert wäre. Das eigentliche Programm müsste nur seine Ergebnisse laufend speichern und zusätzlich erkennen können, an welchem Font es zuletzt gearbeitet hat. Diesen Font darf es bei einem Neustart als kaputt ignorieren. Schöne Grüße aus Bremen hartmut
Moin, Am Die, 2003-07-01 um 08.19 schrieb Hartmut Meyer:
Wie wär's mit einem kontrollierendem Prozess, der das eigentliche Pragramm im Auge behält und dieses erneut startet falls es an einem kaputten Font gescheitert wäre.
Das eigentliche Programm müsste nur seine Ergebnisse laufend speichern und zusätzlich erkennen können, an welchem Font es zuletzt gearbeitet hat. Diesen Font darf es bei einem Neustart als kaputt ignorieren.
Wow. Elegant. Wie's scheint, funktioniert meine Brachialmethode solide. Wenn ich mich da täusche, werde ich es so angehen. Vielen Dank! Gruß, Ratti -- -o) fontlinge | Font management for Linux | Schriftenverwaltung in Linux /\\ http://freshmeat.net/projects/fontlinge/ _\_V http://www.gesindel.de https://sourceforge.net/projects/fontlinge/
participants (3)
-
Hartmut Meyer
-
Joerg Rossdeutscher
-
Stefan Hundhammer