Sunday, August 09, 2015

use B; - to the rescue

Wo bleiben die Fehlermeldungen? Das war die Frage, die es galt bei einem Kunden zu beantworten.
Ich möchte hier kurz zeigen, wie wir auf die Lösung gekommen sind. Dazu erst einmal ein paar
grobe Informationen zu der Umgebung:

*  Bei dem Kunden läuft ein selbstgeschriebener Webserver
*  Der Webserver "require"d die einzelnen Seiten

Das sieht dann ungefähr so aus:



Alles wird in den Namensraum "main" importiert und einmal geladene Seiten bleiben natürlich geladen,
so dass im Laufe der Zeit etliche Seiten "required" wurden. Ob die Lösung optimal ist, spielt hier
jetzt keine Rolle.

Um Fehler sauber mitzuloggen gibt es einen Signalhandler:

  $SIG{"__DIE__"} = sub{ log(...) };

Das funktioniert soweit gut. Nur in manchen Situationen - die reproduzierbar waren - blieben die
Fehlermeldungen aus. Die Seite machte aber nichts...

Nach etwas Fehleranalyse haben wir herausgefunden, dass der Signalhandler wohl an irgendeiner Stelle
überschrieben wurde. Festgestellt haben wir das mit zwei einfachen "print"-Statements:

  print "" . $SIG{"__DIE__"};

Einmal im Webserverskript und einmal in der Seite, die nicht mehr funktionierte. Die Subroutine war
in unterschiedlichen Speicherbereichen abgelegt.

Das Modul "B" hat uns dann geholfen. In dem Seitenskript habe ich dann folgendes eingefügt:


In dem SIG-Hash werden Subroutinenreferenzen gespeichert. Mit der Funktion "svref_2object" aus dem Modul
"B" kommt man an das Objekt zu der Referenz. Über dessen Methode "GV" kommt man an das Objekt des "Globs"
und darüber kommt man an den Dateinamen in dem die Sub zu finden ist.

Durch die Ausgabe sind wir darauf gestoßen, dass irgend ein Seitenskript wohl "CGI::Carp" lädt. "CGI::Carp"
überschreibt den Signalhandler, so dass unser eigener Signalhandler nicht greift.

Nachdem das rausgeschmissen war, griff unser Signalhandler wieder und alles war gut...

No comments: