6

開発中のキット用に小さなデバッグ アプリを作成しています。それを数人のユーザーに展開して、クラッシュを引き起こすことができるかどうかを確認したいと考えています。wxPython アプリを効果的にラップして、アプリがクラッシュする原因となる未処理の例外をすべてキャッチする方法を知っている人はいますか?

理想的には、すべての出力 (エラーだけでなく) をキャプチャして、ファイルに記録したいと考えています。未処理の例外はすべて現在のファイルにログを記録し、通常どおりに例外を渡す必要があります (つまり、ログ プロセスは透過的である必要があります)。

誰かが以前にこれらの行に沿って何かをしたにちがいないと確信していますが、グーグルで役に立ちそうなものを見つけることができませんでした.

4

4 に答える 4

10

例外処理については、ログ ファイルがログとして開かれていると仮定します。

import sys
import traceback

def excepthook(type, value, tb):
    message = 'Uncaught exception:\n'
    message += ''.join(traceback.format_exception(type, value, tb))
    log.write(message)

sys.excepthook = excepthook
于 2008-10-10T05:30:47.487 に答える
6

標準出力のロギングには、次のような stdout ラッパーを使用できます。

from __future__ import with_statement

class OutWrapper(object):
    def __init__(self, realOutput, logFileName):
        self._realOutput = realOutput
        self._logFileName = logFileName

    def _log(self, text):
        with open(self._logFileName, 'a') as logFile:
            logFile.write(text)

    def write(self, text):
        self._log(text)
        self._realOutput.write(text)

次に、メインの Python ファイル (すべてを実行するファイル) で初期化する必要があります。

import sys    
sys.stdout = OutWrapper(sys.stdout, r'c:\temp\log.txt')

例外のログ記録に関してはMainLoop、wx.App のメソッドを try..except でラップし、例外情報を抽出して何らかの方法で保存し、次にraise例を介して例外を再発生させるのが最も簡単な方法です。

try:
    app.MainLoop()
except:
    exc_info = sys.exc_info()
    saveExcInfo(exc_info) # this method you have to write yourself
    raise
于 2008-10-03T10:30:07.440 に答える
3

使用できます

sys.excepthook

( Python ドキュメントを参照)

コードで以前にキャッチされなかったすべての例外をキャッチするカスタムオブジェクトをそれに割り当てます。次に、任意のメッセージを任意のファイルにトレースバックと共に記録し、例外を使用して好きなことを行うことができます (再発生させ、エラー メッセージを表示し、ユーザーがアプリの使用を継続できるようにするなど)。

stdout のロギングについては、DzinX の OutWrapper に似たものを作成するのが最善の方法でした。

デバッグ段階にある場合は、各エントリの後にログ ファイルをフラッシュすることを検討してください。これはパフォーマンスに大きな悪影響を及ぼしますが、基礎となる C コードで segfault を引き起こすことができたとしても、ログが誤解を招くことはありません。

于 2008-12-16T21:33:00.687 に答える
1

さまざまな方法があります。wxApplication::OnInit に try..catch ブロックを配置できますが、Gtk では常に機能するとは限りません。

別の方法としては、wxApplication 派生クラスで Application::HandleEvent をオーバーライドし、次のようなコードを記述することもできます。

void Application::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& event) const
{
    try
    {
        wxAppConsole::HandleEvent(handler, func, event);
    }
    catch (const std::exception& e)
    {
        wxMessageBox(std2wx(e.what()), _("Unhandled Error"),
            wxOK | wxICON_ERROR, wxGetTopLevelParent(wxGetActiveWindow()));
    }
}

これは C++ の例ですが、確かに簡単に Python に変換できます。

于 2008-10-03T10:17:48.840 に答える