Michael Schröpl: perl -w *und* use CGI::Carp - geht das irgendwie sinnvoll?

Liebe Leser,

ich habe ein Problem mit dem Perl-Interpreter. (Es tritt sowohl in meiner PC-Entwicklungsumgebung als auch auf dem Teamone-Server auf, scheint also irgendwie universeller Natur zu sein.)

Ich möchte gerne meine Perl-Skripts mit der Option "-w" laufen lassen, um Warnungen bei der Verwendung illegaler Konstrukte zu erhalten.
Ich möchte auch gerne meine CGI-Skripte unter Verwendung von
   use CGI::Carp qw(fatalsToBrowser);
laufen lassen, um Fehlermeldungen im Browser zu sehen (und nicht in irgend einer Protokolldatei auf dem Server, die für Normalsterbliche kaum zugreifbar ist).

Beides einzeln funktioniert prima. Beides zusammen führt dazu, daß sich der Perl-Interpreter anscheinend aufhängt - jedenfalls braucht der Prozeß dann länger, als der CGI-Timeout meines Servers. (*Das* ist der Effekt, der bei der Betatest-Version der Suchmaschine auftritt, wenn eine nicht-case-sensitive Suche durchgeführt wird - hallo, Uschi ...)

Konkret habe ich einen Hash mit Markierungen, in welchem Feld eines Indexeintrags gesucht wird. Werte in diesem Hash sind entweder "+" oder undefiniert.
Später greife ich auf diesen Hash zu, um zu prüfen, ob ich die zu durchsuchenden Daten in Kleinbuchstaben konvertieren muß:
  if ($Search_Areas {0} eq '+') { $IndexLine      = lc ($IndexLine);      }
  if ($Search_Areas {1} eq '+') { $DieseKategorie = lc ($DieseKategorie); }
  if ($Search_Areas {2} eq '+') { $DieserTitel    = lc ($DieserTitel);    }
  if ($Search_Areas {3} eq '+') { $DieserName     = lc ($DieserName);     }
  if ($Search_Areas {4} eq '+') { $DieserText     = lc ($DieserText);     }

Lasse ich das Skript ohne "-w" *oder* ohne CGI::Carp laufen, dann funktioniert das tadellos.

Schalte ich "perl -w" ein, dann stellt der Perl-Interpreter fest, daß einige der $Search_Area-Werte undefiniert sind und deshalb besser nicht mit '+' verglichen werden sollten.
Da es aber variabel viele sind, möchte ich sie ungern explizit initialisieren (das sind wieder fünf Zeilen mehr im Skript und eine Stelle mehr, die man beim nächsten Mal anzupassen vergessen kann).
Perl gibt eine entsprechende Warnung aus, die ich in der CGI-Fehlerdatei des Apache finde - so weit, so gut.
"perl -cw" liefert an dieser Stelle *keine* Fehlermeldung, weil dieser Effekt offenbar nur zur Laufzeit mit realen Daten festgestellt werden kann.

Schalte ich simultan "perl -w" *und* CGI::Carp ein, dann hängt sich der Prozeß auf. Er verbraucht sichtlich keine CPU-Zeit, kommt aber nicht in angemessener Zeit zu einem Ergebnis.

Dazu meine Fragen:

  • Kennt jemand von Euch diesen Effekt (und kann ihn ggf. umgehen)?
  • Was tut ihr, um für CGI-Skripte in Perl möglichst gute Diagnoseinformationen zu bekommen?

Für die Suchmaschine werde ich mir erst einmal damit behelfen, "perl -w" auszubauen ... :-(

Viele Grüße - Michael

  1. Hallo Michael,

    [...]

    Ich möchte gerne meine Perl-Skripts mit der Option "-w" laufen lassen, um Warnungen bei der Verwendung illegaler Konstrukte zu erhalten.
    Ich möchte auch gerne meine CGI-Skripte unter Verwendung von
       use CGI::Carp qw(fatalsToBrowser);
    laufen lassen, um Fehlermeldungen im Browser zu sehen (und nicht in irgend einer Protokolldatei auf dem Server, die für Normalsterbliche kaum zugreifbar ist).

    Beides einzeln funktioniert prima. Beides zusammen führt dazu, daß sich der Perl-Interpreter anscheinend aufhängt - jedenfalls braucht der Prozeß dann länger, als der CGI-Timeout meines Servers. (*Das* ist der Effekt, der bei der Betatest-Version der Suchmaschine auftritt, wenn eine nicht-case-sensitive Suche durchgeführt wird - hallo, Uschi ...)

    [...]

    Ich hab mal in die entsprechenden Module reingeschaut, aber leider nicht gleich verstanden, was dort so alles abgeht ;-) Allerdings sind mir sofort einige Zeilen aufgefallen, in denen der Autor Code kommentiert, den er nur dazu verwendet, Warnings zu vermeiden.
    Also wäre ein "Workaround" zur Vermeidung von Warnings in guter Gesellschaft zu der Vorgehensweise in Standardmodulen :-)

    Ein Möglichkeit, evtl. Komplikationen zu vermeiden, wäre sukkzessive an den kritischen Stellen (wo sicher Warnings entstehen) local $^W in einem Block auf 0 zu setzen. Vielleicht kannst Du so den "Bösewicht" ausmachen, der Dir Performance "klaut". :-)
    Mehr kann ich leider dazu nicht sagen.

    Gruß AlexBausW

    Please visit my SELFvisitingcard @ http://www.atomic-eggs.com/selfspezial/daten/150.html

    1. Hallo Michael,

      Noch eine Ergänzung.
      Nachdem ich nochmal in CGI::Carp reingeschaut habe, kam mir die Idee, wenn es Dir nur darauf ankommt die Fehlermeldungen an den Browser zu schicken, statt auf STDERR zu schreiben, könntes Du ja selbst __WARN__ und __DIE__ abfangen:

      $SIG{__WARN__} = sub { print "warn: ", $_[0]; };
        $SIG{__DIE__} = sub { print "die: ", $_[0]; exit(1); };

      Vielleicht hilft das, die Performance wieder zu steigern. Zumindes hast Du dann unter Kontrolle, was bei __WARN__ bzw. __DIE__ passiert.

      Gruß AlexBausW

      Please visit my SELFvisitingcard @ http://www.atomic-eggs.com/selfspezial/daten/150.html

      1. Nachdem ich nochmal in CGI::Carp reingeschaut habe, kam mir die Idee, wenn es Dir nur darauf ankommt die Fehlermeldungen an den Browser zu schicken, statt auf STDERR zu schreiben, könntes Du ja selbst __WARN__ und __DIE__ abfangen:

        $SIG{__WARN__} = sub { print "warn: ", $_[0]; };

        Besser ist es, einen Header mit ausgeben:
        $SIG{__WARN__} = sub { print header, [...], "warn: ", $_[0]; };

        Peter

  2. Ich möchte gerne meine Perl-Skripts mit der Option "-w" laufen lassen, um Warnungen bei der Verwendung illegaler Konstrukte zu erhalten.
    Ich möchte auch gerne meine CGI-Skripte unter Verwendung von

    »»    use CGI::Carp qw(fatalsToBrowser);

    laufen lassen, um Fehlermeldungen im Browser zu sehen (und nicht in irgend einer Protokolldatei auf dem Server, die für Normalsterbliche kaum zugreifbar ist).

    Beides ist sehr sinnvoll.

    Beides einzeln funktioniert prima. Beides zusammen führt dazu, daß sich der Perl-Interpreter anscheinend aufhängt - jedenfalls braucht der Prozeß dann länger, als der CGI-Timeout meines Servers. (*Das* ist der Effekt, der bei der Betatest-Version der Suchmaschine auftritt, wenn eine nicht-case-sensitive Suche durchgeführt wird - hallo, Uschi ...)

    Bei mir gibt's in Kombination keine Probleme. Welche Versionen benuntzt Du?

    Konkret habe ich einen Hash mit Markierungen, in welchem Feld eines Indexeintrags gesucht wird. Werte in diesem Hash sind entweder "+" oder undefiniert.
    Später greife ich auf diesen Hash zu, um zu prüfen, ob ich die zu durchsuchenden Daten in Kleinbuchstaben konvertieren muß:

    »»   if ($Search_Areas {0} eq '+') { $IndexLine      = lc ($IndexLine);      }
    »»   if ($Search_Areas {1} eq '+') { $DieseKategorie = lc ($DieseKategorie); }
    »»   if ($Search_Areas {2} eq '+') { $DieserTitel    = lc ($DieserTitel);    }
    »»   if ($Search_Areas {3} eq '+') { $DieserName     = lc ($DieserName);     }
    »»   if ($Search_Areas {4} eq '+') { $DieserText     = lc ($DieserText);     }

    Tip am Rande: Bei ausschliesslich numerischen Indexes kannst Du auch ein Array verwenden.

    Ein Lesezugriff auf ein undefiniertes Element ist schlecht und fuehrt bei Verwendung des -w-Switches zu einer Warnung. Wenn Du nur die Zustaende + oder undefiniert hast, pruefe lieber so:

    if (defined $Search_Aeras{4}) {...}

    Peter

    1. Hallo Peter,

      Beides einzeln funktioniert prima. Beides zusammen führt dazu, daß sich der Perl-Interpreter anscheinend aufhängt - jedenfalls braucht der Prozeß dann länger, als der CGI-Timeout meines Servers. (*Das* ist der Effekt, der bei der Betatest-Version der Suchmaschine auftritt, wenn eine nicht-case-sensitive Suche durchgeführt wird - hallo, Uschi ...)
      Bei mir gibt's in Kombination keine Probleme. Welche Versionen benuntzt Du?

      Perl 5.004 auf dem Server, ActivePerl Build 522 auf dem PC.

      Tip am Rande: Bei ausschliesslich numerischen Indexes kannst Du auch ein Array verwenden.

      Yep. Ich bin mir aber noch nicht sicher, ob ich nicht noch auf aussagefähigere Strings umsteige (wenn es in Perl schon keine Aufzählungstypen a la PASCAL gibt).

      Ein Lesezugriff auf ein undefiniertes Element ist schlecht und fuehrt bei Verwendung des -w-Switches zu einer Warnung.

      Eben - diese Warnung finde ich im Apache-Logfile, wenn ich CGI::Carp ausbaue.

      Wenn Du nur die Zustaende + oder undefiniert hast, pruefe lieber so:
      if (defined $Search_Aeras{4}) {...}

      Danke - das ist eine Verbesserung, die ich verwenden werde.

      mfG - Michael