2

典型的なアクセス違反が発生しました:

access violation at 0x4ebb7456: read of address 0x4ebb7456

これは、プログラムの残りの部分がすでにシャットダウンしているときに作成されるスレッドで発生します。

System.FinalizeUnits例外発生時にメインスレッドが実行されています。

gdiplus.dllロードされたメモリ領域にアドレスが属していることがわかりました。

返されたハンドルLoadLibrary('gdiplus.dll')を呼び出さずにdprファイルに呼び出しを追加すると、問題は解決します。これにより、ファイナライズセクションの実行中にがアンロードされなくなります。FreeLibrarygdiplus.dll

プログラムのどの部分がアクセス違反につながるスレッドを作成しているのかを知るにはどうすればよいですか?

解放されたメモリスペースを呼び出すコードを識別する方法はありますか?

FastMMとmadExceptはほとんど役に立ちません。madExceptエラーレポートウィンドウが表示されますが、すぐに再び閉じられ、ログファイルは書き込まれません。

プログラムを分解することはできますが、それは簡単なアプリケーションではなく、ある種のデバッグ手法を使用してこれを解決したいと思います。

4

2 に答える 2

3

おそらく、これを追跡するための最初のステップは、コードのどの部分が実際にスレッドを作成しているかを検出することです。アプリケーションのシャットダウン中にスレッドを作成することは、作成中の悪いニュースのように聞こえるので、それが単に起こらないことを確認したいと思います。

その方法については、デバッガーブレークポイントを使用します。まず、CreateThreadWindows.pasの実装にブレークポイントを設定し、デバッグDCUで実行します。そのブレークポイントがシャットダウン中にトリガーされるかどうかを確認します。

シャットダウン中にそこに侵入しない場合、スレッドは非Delphiコードによって作成されます。次のステップは、CPUビューを開いてにステップインすることCreateThreadです。の分解CreateThreadは指示から始まりJMPます。これに足を踏み入れると、になりますkernel32.CreateThread。ここでブレークポイントを設定し、シャットダウン中にこれをトリガーしたときのコールスタックを確認します。

于 2011-08-01T14:33:05.537 に答える
2

ライブラリをロードしているユニット(おそらくそれはあなたが使用しているコンポーネントです)を見つけて、それをプロジェクトファイルの一番上(または一番上近く)に追加します。これにより、アプリケーションのシャットダウンの後半で確実にアンロードされ、AVが防止されます。

したがって、たとえば、GdiPlusを使用している場合は、次のようになります。

program MyProgram;

uses
  FastMM4,
  GdiPlus,  // <=== this line inserted
  Windows,
  Forms,
  Controls,
  Classes,

これにより、後で問題が発生する可能性のある問題がマスクされる可能性があります。アンロードされたDLLを呼び出そうとしているユニットを特定し、これを実行することは価値があります。

于 2011-08-01T14:45:11.697 に答える