9

VB6 の外部で開始されたプロセスをリモートでデバッグすることは可能ですか?

アプリケーションは、かなりの数の dll/ocx リソースを備えた VB6 アプリケーションです。登録不要の COM を使用して VB6 アプリの ClickOnce 展開をセットアップしようとしていますが、実行時にエラーが発生しています。

VB6がCOM登録をリダイレクトする方法についての私の理解は、おそらくこれが不可能であることを意味しますが、誰かがより良い考えを持っていると思いました.

4

3 に答える 3

9

Windbgを提案する Darryl の回答をサポートするために、Windbg を VB6 で使用することに関する Microsoftの担当者による2006 年のブログ投稿と、Windbg の簡単な紹介を含む別の Microsoft 担当者による2004 年のブログの投稿があります。

編集:完全に明確にするためだけに。Windbg は、Microsoft が提供する無料のスタンドアロン デバッガーです。VB6 EXE、DLL、および OCX をシンボルを使用してネイティブ コードにコンパイルすると (PDB ファイルを作成)、ClickOnce アプリケーションをデバッグできるようになります。

ブログからの重要な抜粋:

サーバー マシンへのアクセスが制限されている場合は、WinDbg のリモート デバッグ機能を使用できます。通常の方法で WinDbg のコピーをプロセスにアタッチし、それをデバッグ サーバーに渡します (WinDbg ヘルプで .server を確認してください)。その後、WinDbg の [ファイル] メニューからリモートで接続できます。サーバールームのファンからの騒音がないことを除けば、まるでそこにいるかのようです。リモートをデバッグする場合、WinDbg のコピーは非常にスマートな端末にすぎないため、すべての拡張機能、シンボルなどはリモート サーバー上にある必要があります。これは、DLL、VB6、または .NET とまったく同じ方法で設定します。

コンポーネントのシンボルは、コンポーネントがロードされるまでロードされないため、サーバーを少なくともその時間実行させる必要があります。その時点でデバッガーを停止したい場合は、VB コードの早い段階で中断を入れることができますが、その場合、コードを通じて毎回そこで停止することに注意してください。モジュールを実行してから侵入すると仮定しましょう。モジュールにロードされたシンボルを「x MyModule!*」でリストすると、すべての関数とそこにバンドルされている多くのシンボルが表示されます。VB はまったく恥ずかしがらずにインターフェイスとシンボルを追加しますが、通常はそれらについて心配する必要はありません。おそらく奇妙に見えることの 1 つは、わかりやすい小さなドットではなく、C++ の二重コロン規則を使用するすべてのクラス/メソッド構文です。

ここから、通常の方法 (bp など) でブレークポイントを設定し、コードをステップ実行できます。VB ファイル拡張子がソース ファイル タイプのドロップダウンにない場合でも、VB ソース コード モジュールを開いて F9 でブレークポイントを設定することもできます。コードをステップ実行すると明らかになりますが、VB が生成するコードを以前に見たことがない場合は、少し不安になるかもしれません。アセンブラをステップ実行すると、そこにはたくさんの COM グーがあります。Hresult は頻繁にチェックされます。ソースコードがどのように見えるかを知るには少し練習が必要なので、ソースコードを頻繁に参照して自分がどこにいるのかを理解する必要があります. バリアントは、VB が多くの作業を行い、単純な方程式のように見えるものが大量のコードになる可能性があるため、特に困難です。

この方法でデータを取得するのは簡単ではありません。ローカル変数 (dv はコマンド) を見ると、変数が省略されてリストされていることがわかります。これは、メモリが関数の有効期間内で他の何かにも使用されているか、このコンテキストで名前が一意ではないことを意味します。 . 列挙型は整数または長整数として表示され、オブジェクトはポインターとして表示されます。実際、それらは常にまさにその通りでしたが、VB IDE はそれを隠しています。VB 文字列は内部では COM BSTR (およびそれに応じて Unicode) であり、バイト配列は実際には char 配列です。VB は ANSI 以外をサポートしていないように見えるため、VB 文字列が Unicode であることを発見して驚くかもしれません。これは、Ruby フォーム エンジンが ANSI のみだったためです。

Err、App、または Printer オブジェクトを取得することはできません。それらを取得するには、多くの内部構造と完全に文書化されていない構造を調べる必要があるためです。そこにたどり着いたとしても、VB で使用するアクセサ関数がなければ、生データにすぎません。これらのフィールドのいずれかを確認する必要がある場合は、ソース コードにデバッグ コードを埋め込んで、それらの値を取得できる場所にコピーすることをお勧めします。

必要に応じて VB ランタイムにステップ インすることもできますが、アプリケーションをデバッグしようとしている場合は、あまり明らかにならないでしょう。そうすれば、VB の内部が非常に COM の影響を受けていることに気付くでしょう。COM のアイデアの一部はもともと VB に由来していたため、影響は実際には双方向でした。

コードを実行すると、例外が発生する場合があります。Null 参照例外 (つまり、null ポインターの逆参照) は珍しくなく、心配する必要もありません。これらは、アドレスが 0 またはほぼ 0 の初回チャンス C000005 例外として表示されます。何も設定されていないオブジェクトがある場合、ランタイムはそれを行うことがありますが、可能な値は null または有効な値だけであるため、安全です。コードがコレクション内でルックアップを行い、値がそこにない場合にも、例外が発生します。例外は現在非常に高価であるため、可能であればそれを避けたいと思うでしょう。一般的に見られる別の例外は c000008f です。数値を調べると、浮動小数点の不正確な結果の例外であることがわかります。

VB コンポーネントでのハングとクラッシュのデバッグは、他のアンマネージ コンポーネントの場合とほとんど同じ方法で行われますが、上記のコンパイルのために少し難しくなります。この方法で VB コードのデバッグを試みる必要がある場合は、「Hello world」アプリケーションから開始して、上に向かって作業することを強くお勧めします。コード化するのが簡単な言語をVBにする可能性のあるすべてのものは、デバッグするのがひどい言語になります。

于 2009-02-05T23:01:34.220 に答える
3

あなたはwindbgを試しましたか?プロジェクトの pdb ファイルがあることを確認してください。

于 2009-02-05T22:20:45.907 に答える
3

VB6 でデバッグする場合、実行中のバイナリにアタッチするのではなく、独自のプロセス内でコードを解釈すると思います。これが、タスク マネージャーと Win32 API が、デバッグ時に実行中のアプリとして VB6.exe を表示する理由です。

また、あなたが言うように、VB6 は COM ライブラリへの呼び出しを短絡することがあるため、これらの呼び出しを傍受することが常に可能であるとは限りません。

おそらく、インテリジェントなログに頼る必要があります (つまり、エラーが発生したコード行や関連する変数の状態を特定するために、エラーが発生したポイント周辺の変数の値をログに記録する必要があります)。 .)

幸運を

于 2009-02-05T22:13:53.253 に答える