おはようございます。
delphixe3を使っています。
×ボタンクリックで、自作ソフトウェアの終了時にアドレス違反のメッセージが出てしまいます。
ソフトウェアの終了時は何もしていません。
なのにアドレス違反のメッセージが出ます。
ソース位置を特定しようとして、メッセージが出ている状態でIDE上で「検索」‐「指定アドレスに移動」をしてみたんですが、アドレスが表示されるだけでソース位置を特定できませんでした。
メッセージが出ている状態で、dcc32をコマンドから使ったのですが、offsetに何を指定すればよいのか分からず、エラーの特定位置を検索できませんでした。
offsetには何を指定すればよいのでしょうか?
ヘルプを見ると、dcc32 -f<offset> hogehoge.dprと書いてあります。
offsetにメッセージに出ているアドレスを書いてもダメでした。
ご存知の方教えてください。
dcc32でなくても、IDEでアドレス違反のソース位置を特定できる方法をご存知の方いらっしゃれば、そちらの方でも助かります。
よろしくお願いします。
私はそういう経験ないですし、どうすれば良いかもまったく分かりませんが、いくつかアドバイスさせてください。
>ご存知の方教えてください。
「ご存知の方」と限定して呼びかけると、答えるのをためらってしまう方がいるかも知れませんよ?
むしろ、「少しでも心当たりのある方、いらっしゃいましたら…」の方が良いのでは。
>×ボタンクリックで、自作ソフトウェアの終了時にアドレス違反のメッセージが出てしまいます。
アドレス違反とは、Access Violation のことでしょうか。
いずれにせよ、Ctrl+C でメッセージの内容をコピーした上で、それをここに提示するのが原則だと思います。
>offsetにメッセージに出ているアドレスを書いてもダメでした。
どのように記述して、どのようにダメだったのでしょうか。
以下はご覧になりましたか?
[delphi-users:2266] アドレス違反でエラーのソース位置を知る方法
https://groups.google.com/forum/#!topic/delphi-users/tZIhbeWox4c
「アドレス????????でエラーが発生」からエラー位置を知る - Delphi Tips
http://www2.big.or.jp/~osamu/Delphi/Tips/key.cgi?key=36#0184.txt
あと、何か特別なコンポーネント、オブジェクト、ライブラリを使用してはいませんか?
ボタンとかTMemoのような一般的でおとなしいものでなくもっと能動的なものや、ActiveX、DB関係とか。
すみませんでした。
おっしゃられる通り、質問の仕方と情報の書き方が良くなかったです。
申し訳ございませんでした。
アドレス違反は、お話の通りAccessViolationのことです。
メッセージは以下の通りです。
「EAccessViolationがモジュールDoProc.exeのE8C77BD2で発生しました。アドレスE8C78BD2でアドレスE8C78BD2に対する読み取り違反がおきました。」
offsetにはE8C77BD2やE8C78BD2を書いたり、サイトの「アドレス????????でエラーが発生」からエラー位置を知る - Delphi Tipsを参考に4文字目から77BD2や78BD2を書きましたが、サイトのようにソース位置が出なくて、バージョン番号だけが出ました。
お話しいただいたサイトは調べていました。お話していなくて申し訳ございませんでした。
あと特別なコンポーネント、オブジェクト、ライブラリは使用していません。
ActiveXもDBも使用していません。
お騒がせしました。
アドレス違反の解除になるかどうか分かりませんが、AllocMemを使って動的にメモリを設定していたんですが、もちろんメモリ解放もやっていたんですが、変数を固定の配列にして実行して×ボタンクリックで終了したら、アドレス違反のメッセージが出なくなりました。
ひとまず様子を見たいと思います。
本当にお騒がせしまして申し訳ございませんでした。
とりあえず直って良かったです。恐縮させてしまってこちらこそすみません。
「要領不十分でもったいない質問者さん」には、なるべく早い段階で指摘させてもらおうと思ってます。
もうほぼ解決した模様なので周回遅れではありますが、いくつか。
>AllocMemを使って動的にメモリを設定していたんですが、もちろんメモリ解放もやっていたんですが
AllocMem & FreeMem でなく、GetMem+FillChar & FreeMem だとどうでしょうね。変わるわけないか?
dcc32 について。おそらくやまださんは dcc32 -f<offset> hogehoge.dpr に従って、
dcc32 -f77BD2 hogehoge.dpr とか記述したと思うのですが…。
>4文字目から77BD2や78BD2を書きましたが、サイトのようにソース位置が出なくて、バージョン番号だけが出ました
私もいろいろ試してみました。で、↑この状態は、hogehoge.dpr にアクセスできてない際のレスポンスです。(dcc32、無口すぎて困る。)アクセスできてればとりあえず Target address not found. とか出ます。
この下に、「間違いのない、確実な使い方」を載せておきます。
(なお、D6の dcc32 は、対象のパス名が長いとレスポンスの表示がおかしくなることもありました。)
※ただし、今回のやまださんの問題解決に役立ちはしなかったと推測しています。それは、アドレスが
E8C77BD2 などという高い値だからです。これはDelphiのコードがある範囲ではないと思ってますので。
それと関連することなんですが、示されたアドレスが0045E1D9のような時にオフセットを5E1D9とするのは、
「4文字目から」というより、$00400000(量にして4MB分)を減じるからです。結果として下5桁になると。
詳しくは以下を参照してください。(実は私もよく分かってません \(^o^)/)
☆Delphiリファレンス - Delphiコンパイラ指令のリスト - イメージのベースアドレス $IMAGEBASE
http://docwiki.embarcadero.com/RADStudio/XE4/ja/%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E3%83%99%E3%83%BC%E3%82%B9%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9
☆意図的に Access Violation を起こすコード
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ShowMessage(TObject(nil).ClassName);
end;
☆これをデバッグでなくexe単体で実行。すると、このようなエラーダイアログが。
>Access violation at address 0045A089 in module 'Project1.exe'. Read of address 00000000.
☆エラーのソース位置を調べる
-------------------------------------------------------------------------------
1. コマンドプロンプトを起動する。
2. 「cd コマンド」等でターゲットとなるプロジェクトの .dpr のあるディレクトリへ移動する。
cd "C:\Program Files\Borland\Delphi6\Projects\Access Violation Test"
3. dcc32で "Find error" を実行する。
dcc32.exe -f5A089 Project1.dpr
4. その結果。
C:\Program Files\Borland\Delphi6\Projects\Access Violation Test>dcc32.exe -f5A089 Project1.dpr
Borland Delphi Version 14.0
Copyright (c) 1983,2002 Borland Software Corporation
Project1.dpr(14)
Unit1.pas(27) Target address found.
ShowMessage(TObject(nil).ClassName);
^
-------------------------------------------------------------------------------
・ Delphi/RAD Studioのbinディレクトリへのパスが通っていることが前提。(システム環境変数 Pathを確認)
・ 上記内容はDelphi6 Personalのものなので、最近のバージョンとはディレクトリ等が違います。ご注意。
・ 標準以外のライブラリを使用している場合は、-uオプションでライブラリパスを追加指定する模様。
(標準のライブラリは dcc32.cfg に記述されているため、指定不要。)
ツイート | ![]() |