2012-10-26 140 views
1

我正在將一些cgi腳本轉換爲mod_perl。在CGI下,我使用sig DIE來捕獲堆棧跟蹤,並在每次發生未捕獲的異常時對其進行記錄。這很有效:每當腳本中有東西死掉,我就會在應用程序日誌中獲得一個很好的堆棧跟蹤。代碼是:捕獲與mod_perl異常的堆棧跟蹤

BEGIN { 
    $SIG{__DIE__} = \&sigDie; 
} 

sub sigDie { 
    return 1 if $^S; # we are in an eval block 

    my ($error) = @_; 
    cluck("Caught fatal error: $error"); # put a stack trace in the logs via warn 
    local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1; 
    FATAL @_; # call log4perl's fatal 

    return 1; 
} 

在Apache2 :: Registry,然而,我的代碼不再調用,它只是停止,當它死亡記錄。我認爲這是因爲我的代碼正在被mod_perl評估,但我把上面的例程取消了eval check,而且我還沒有被調用。

有什麼辦法可以在mod_perl下得到我想要的嗎?我發現這些堆棧痕跡的自動記錄非常有用,如果我不得不放棄它們,會錯過它們。到目前爲止,我已經對如何得到它空了。

+1

FWIW信號處理程序的返回值無效。不妨''回來;'以避免讀者認爲它確實如此。 – Schwern

+0

謝謝,會更新它。不記得我爲什麼這麼做了。 – mvsjes2

回答

1

我不知道答案,但可以想到一些可能性和方法來檢查。

  • log4perl有問題。

撥打FATAL是否仍在__DIE__處理程序之外工作?

  • 根本沒有記錄錯誤。

刪除死處理程序,做異常記錄?

  • 東西正在取代您的$SIG{__DIE__}處理程序。

由於您將其設置爲BEGIN時間,因此可能是Apache2 :: Registry或其他程序中的某個內容替換了它。通過在發現錯誤之前驗證$SIG{__DIE__}中的內容,我會發現它。也許傾銷與Data::Dump::Streamer,它可以處理代碼參考,你可能會弄清楚是什麼設置它。

一個更安全,更有禮貌,方式,註冊一個模處理程序...

local $SIG{__DIE__} = ...; 

...the rest of your program... 

這將重新註冊的每個請求處理程序,而不是吹在全球處理的範圍之外。

希望能幫助我們弄清楚發生了什麼。