tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルVB6 に UnhandledException Event は無い?
記事No15914
投稿日: 2014/06/24(Tue) 21:49
投稿者茶々丸
VisualBasic 6.0 には、.Net Framework の「Application.ThreadException」
や「AppDomain.UnhandledException」に相当するものは、無いのでしょうか?

どなたか実現方法や、ソースを公開しているサイトなどをご存じの方はいませんか。

宜しくお願いします。

----------------------------------------------------------------------
一応、以下のWin32API の 調べて、挫折中です・・。
RaiseException, SetUnhandlEdexceptionFilter
SetWindowLong, SetWindowsHookEx

以下のような挫折を経験しました。
(1) SPY++ や 自前プログラムで Runtime エラーを通知するような、メッ
    セージは見つけられず、メッセージフックでは、捕まえられそうになか
    った。
(2) RaseException と SetUnhandlEdexceptionFilter で、通知するサンプルを
    作ったが、Runtime エラーは拾う事が出来なかった。どうやら、Runtime
    エラーは、例外コードにシステムで予約されたコードを使用しており、
    SetUnhandlEdexceptionFilter では、拾えないようようだ。
    (試しに RaiseException に 同じコードを指定して実行したら、
     UnhandlEdexceptionFilter は、呼ばれなかった。)
(3) 最後の望みは、API Hook で、まだ試していない。
    (Delpehi の JEDI Project の JclHookExcept.pas を参考にする予定。
    MiniDumpWriteDump と *.pdb ファイルを組み合わせて、関数名でコー
    ルスタックが表示できないかな・・。)
----------------------------------------------------------------------

[ツリー表示へ]
タイトルRe: VB6 に UnhandledException Event は無い?
記事No15915
投稿日: 2014/06/25(Wed) 09:02
投稿者茶々丸
すみません。そもそも、なぜ、こんな事を知りたいのか書いていませんでし
た。発端は、「開発環境のインストールされていないPCで、実行ファイル
を実行した時。ランタイムエラーが出ると、エラー箇所がさっぱり、わから
ない。」からでした。

ここらへんのデバッグ方法の情報を、お持ちの方、教えてもらえますでしょ
うか。

■補足
問題プログラムの既存ロジックは、「既存の動きを変えることになる」
と「既存のコード量が多い。」の理由で、手を付ける事が出来ません。
---
例外を拾えるか試した中で、以下を試した事を書くのを忘れていました。
・Sub Main で、自前、メッセージポンプを実装し、Sub Main 関数の頭で
  On Error Goto を定義、したが、エラーは拾えなかった。
---
一応、自分で調べた結果、「UnhandledException に相当するものは無い」
と、結論を経て 思考錯誤を繰り替えしているのですが、まだ、「実は何か
簡単な方法があるのじゃないか?」と半信半疑です。長年、VB6.0 に携わ
った方に、「そんなものは無い」と断言してもらえますと嬉しいです。
---
ゼロ除算エラーの時に、RaiseException に渡されている例外コードは、
&HC000008F でした。(Windbg で、"bp kernel32!RaiseException" で止
めて確認しました。)

[ツリー表示へ]
タイトルRe^2: VB6 に UnhandledException Event は無い?
記事No15916
投稿日: 2014/06/26(Thu) 14:48
投稿者魔界の仮面弁士
> ここらへんのデバッグ方法の情報

コンパイルする際に、[ネイティブ コード コンパイル] と [シンボリック デバッグ情報を作成] を
選択していますか? シンボル情報には、関数名、変数名、ソースコード上の位置情報などが含まれるため、
これらを設定しておくと、exe からのデバッグがやりやすくなるかも知れません。

Visual Studio が導入されていない環境の場合は、ご存じのように
windbg を使うことができますね。

http://support.microsoft.com/kb/166275/ja
http://msdn.microsoft.com/ja-jp/library/ee274755.aspx
http://msdn.microsoft.com/ja-jp/library/dd313977.aspx



> 一応、自分で調べた結果、「UnhandledException に相当するものは無い」
無いですね。SetUnhandledExceptionFilter API で例外ハンドラを登録しておくことぐらいは
できるかも知れませんが、試したことはありません。

[ツリー表示へ]
タイトルRe^3: VB6 に UnhandledException Event は無い?
記事No15917
投稿日: 2014/06/29(Sun) 14:37
投稿者茶々丸
返信、ありがとうございます。
「質問の仕方が悪くて、誰も返信してくれないのかな。」と不安に思ってました。

> コンパイルする際に、[ネイティブ コード コンパイル] と [シンボリック デバッグ情報を作成] を
> 選択していますか? シンボル情報には、関数名、変数名、ソースコード上の位置情報などが含まれるため、
> これらを設定しておくと、exe からのデバッグがやりやすくなるかも知れません。
>
> Visual Studio が導入されていない環境の場合は、ご存じのように
> windbg を使うことができますね。
大体、こうのような手順でエラー箇所を特定すればいいんだと考えました。
(1) 開発環境で、コンパイルする時、[ネイティブ コード コンパイル] と [シンボリック デバッグ情報を作
    成] を選択しコンパイル。
(2) 実行環境に windbg をインストール。
(3) 実行環境に *.exe と、 *.pdb をコピー。
(4) 実行環境でプログラムを実行する。
(5) エラーダイアログが表示される。
    -> ここで、[OK]ボタンを押すと、どこでエラーが起きたのかわからない。
(6) windbg を起動し、プログラムのプロセスにデバッグ・アタッチ。
(7) windbg でコールスタックを表示する。
    -> エラー箇所と、そのエラー箇所に至る関数を特定。
(8) windbg で、デバッグ・デタッチ
(9) エラーダイアログの[OK]ボタンをクリックしプログラム終了。

> > 一応、自分で調べた結果、「UnhandledException に相当するものは無い」
> 無いですね。SetUnhandledExceptionFilter API で例外ハンドラを登録しておくことぐらいは
> できるかも知れませんが、試したことはありません。
ありがございます。「魔界の仮面弁士」様からの返信なら絶対です。

実験結果で、ゼロ除算エラーなどのシステムエラーに相当する例外コードは、SetUnhandledExceptionFilter
では、拾えないことが、わかっています。前回の投稿のあと、以下の実験が成功しました。
(1) APIフック(RaizeException 関数の実行コードの書き換えて、自前RaiseException 関数に飛ばす。)
(2) SetUnhandledExceptionFilter を設定、RaizeException を例外コード 0x1 でコールし、
    UnhandledExceptionFilter 内で、MiniDumpWriteDump により、ユーザーダンプファイル作成。

それぞれは、以下の問題を抱えています。
1番は、元のRaiseExceptionコードを呼び出す方法。
2番は、MiniDumpWriteDump は、EXCEPTION_POINTERS を必要とするので、SetUnhandledExceptionFilter
の中でしか実行できない。なので、自前RaiseException関数の中では、MiniDumpWriteDump を実行できない。

それと、dbgHelp.dll に、StackWalk, SymLoadModule などの有用そうな関数があることに気づきました。
http://msdn.microsoft.com/ja-jp/library/cc428915.aspx

ここらへんを利用したコードを書くと、実行時のエラー箇所を特定するスピードが上がりそうですが、そこは
時間がかかりそうなので、前述のデバッグ手法で当分、しのごうと思います。

ありがとうございました。

# StackTrace を表示するような、コードを起こすような機会があったら、このスレの続きに投稿したいと思います。

[ツリー表示へ]