CPU Window は見たくない

ずっと、そう思っていました。・・・ってか、新しい Delphi は玄人向け仕様に進化して、エラーが起きたら、デフォルト CPU Window が表示されるんだなー みたいな。うわー すごいなー!! みたいな。

(僕がそう思い込んでいただけで、上の記述は完全な誤りです)

いつか、この画面の意味がわかるようになりたいなー!


だから、エラーが発生すると僕みたいなド素人はもぉたいへん・・・。>_<

OutPutDebugString(デバッガが受信できるデバッグストリームに文字列を出力する API )を随所に入れて、どこまで無事に動いたか? みたいな方法で、膨大な手間暇をかけてエラーが起きた行を特定するしかなく・・・

s := 'Step1 Passed';
OutPutDebugString(PChar(s));

Hoge Hoge

s := 'Step2 Passed';
OutPutDebugString(PChar(s));

Hoge Hoge Hoge

s := 'Step3 Passed';
OutPutDebugString(PChar(s));

プログラム書いてるんだか、OutPutDebugString経を唱えてるんだか、わからない状態に・・・

もちろん、悩み相談できる人もなく・・・普通に考えて、Delphi 使って開発しているヒトが僕の周囲数十(ひょっとすると数百・・・)km以内にいるとは思えないし・・・、で、Object Pascal のことなら何でも答えてくれる AI に訊いても、Delphi の IDE の具体的な操作方法になると全然ダメで、ありもしない『オリジナル』メニュー項目を創作したり? それってもしかして Delphi 7 の時代のメニューじゃない? みたいな、僕の12.3 にはない操作方法をまことしやかに案内されたり・・・

だから、CPU ウィンドウは、なるべくなら見たくないものの代表でした。
Delphi 12.3 のエラー発生時のデフォルト設定は「 CPU ウィンドウの表示 」。
今、考えると、それは僕の悲しい思い込みだったようです。

【もくじ】

1.ある日 AI が言いました
2.CPU ウィンドウが消えた!
3.デフォルト CPU ウィンドウの表示じゃなかったの?
4.まとめ
5.お願いとお断り

1.ある日 AI が言いました

午前2時、太陽が出ている間は陽の当たらない場所を歩くことが多い僕にとって、いちばん輝いた時間です。ほんと、心安らかに Delphi との会話を楽しめる、他にたとえようもないくらい、大好きで大切なひと時です。

ふと思い立って AI に訊いてみました。

Q:Delphiで、エラーが発生した行を突き止めたいのですが CPU という Window が出てしまいます。エラーが発生した行を示すように設定を変更したいです。Delphi のバージョンは 12.3 です。このバージョンに合わせて正しい設定方法を出来る限り、わかりやすく、教えてください。

AI の回答を要約。

1. ビルド構成を「Debug」にする
画面右側の「プロジェクト マネージャ」で [ビルド構成] のツリーを展開し、[Debug] が太字(アクティブ)になっていることを確認。もし [Release] が太字になっていたら、[Debug] をダブルクリックして切り替える。

2. 「デバッグ用の .dcu を使用する」をオンにする
※ これは 12.3 では「デバッグ版 DCU の使用」という名称でした。
IDE上部のメニューから [プロジェクト] > [オプション] をクリックして、プロジェクトオプション画面を開き、左側のツリーメニューから、[ビルド] > [Delphi コンパイラ] > [コンパイル] を選択。画面一番上の「ターゲット」というドロップダウンが [Debug 構成] になっていることを確認。右側の設定リストの中から [デバッグ] というグループを探し、[デバッグ用の .dcu を使用する] という項目を [True] に変更する。

3. 「最適化」をオフにし、「デバッグ情報」をオンにする
[コンパイル] の画面で、[コード生成] グループの中にある [最適化] を [False] にする。続けて、左側のツリーメニューから、[ビルド] > [Delphi コンパイラ] > [リンク] を選択し、[デバッグ情報] という項目を [True] に設定。

設定が終わったら、画面右下の [保存] ボタンを押してオプション画面を閉じる。

4. プロジェクトの「クリーン」と「ビルド」を実行する
設定を変更した後は、古いコンパイル結果が残らないように全体を再構築する必要がある。この手順を忘れると設定が反映されない。方法は、メニューから [プロジェクト] > [(プロジェクト名)クリーン] をクリックする。続いて、メニューから [プロジェクト] > [(プロジェクト名)をビルド] をクリックして実行する。

おかしな部分も多少ありましたが、いつもより、かなりまともな回答をいただけました。
(実は今まで何度もこのような質問をして、そのたびにガッカリしてきた記憶が・・・)

【おかしな部分】

① 誤:「デバッグ用の .dcu を使用する」 → 正:「デバッグ版 DCU の使用」


② 完全な誤り:メニューから [プロジェクト] > [(プロジェクト名)クリーン] をクリックする。

そんなメニュー項目は Delphi 12.3 にはありません。でも、すぐにピンときました。キーワードは「クリーン」です。そう、IDE の画面右上にあるツールウィンドウの「プロジェクト」に表示されている exe を右クリックすると出るサブメニューの「クリーンアップ」のこと? みたいな・・・

exe を右クリックするとサブメニュー(下)が表示される
きっとコレだ!

ダメもとで上記設定1~4を早速 設定 & 実行 してみました☆ すると・・・

2.CPU ウィンドウが消えた!

長い間、見たことのない懐かしい画面が出現したのです。CPU ウィンドウは表示されず、画面に薄い赤い線引きで(あぁ、御懐かしい)表示されたのは System.SysUtils の内部エラーが発生している行☆

こんな感じ(画像はイメージで、実際の画面とは異なります)

今思えば、僕が書いたプログラムのコードじゃなくて、「 System.SysUtils の内部エラーが発生している行 」が表示されているところにも重大な意味があったのですが、もちろん、この時の僕はそんなことは露知らず・・・、もぉうれしくて!!!

CPU Window が消えたー☆☆☆

ヒトはなんて可笑しな生き物なのでしょう。(何にもわかってない僕は)さらに欲を出して・・・

Q:Delphiで、Debug実行時にエラーが発生した場合、System.SysUtils などのエラー発生行が示されますが、自分の書いたコードのエラーが発生する原因になった記述のある位置を表示する方法を教えてください。

AI の回答の要約

常にVCLのソースコードの中まで入ってしまうのが煩わしい場合は、設定を変更すれば「自分のコードに近い場所」で止まりやすくできます。

で、その方法は・・・

1. メニューの プロジェクト(P) > オプション(O) を開く。
2. ビルド > Delphi コンパイラ > コンパイル を選択。
3. 「デバッグ用 DCU を使用」 を False にする。

はぁ?

「デバッグ用 DCU を使用」 を False に?

さっきと逆じゃん☆

どーゆーコト?

みたいな・・・

3.デフォルト CPU ウィンドウの表示じゃなかったの?

この時点で、まだ僕は Debug 実行時に表示される画面を「デバッグ用 DCU を使用」の True / False が左右していることに気がついていません。

つまり・・・(わかってしまえばカンタンなのですが)

設定表示される画面メリット
TrueVCL(ライブラリ)のエラー発生個所VCLの内部の動きがわかる
False自分のコードのエラー発生個所自分のコードの誤りがわかる

最初、僕は「デバッグ用 DCU を使用」を True に設定していたので、エラー発生時に表示された画面は System.SysUtils のエラー発生行だったのです。

僕はどちらかと言えば、「自分で書いたコードのエラー発生位置(行)を知りたかった」ので素直に AI にそう訊ねたのですが、AI は僕がくるくるぱーで、実はなんにもわかってないことなんて知りませんから、ごく普通に、至極当たり前の表現で、

常にVCLのソースコードの中まで入ってしまうのが煩わしい場合は設定を Falseにした方がいいよ!

・・・と教えてくれたわけです。つまりこれは、False に設定すれば VCL 内部のエラーを引き起こす原因を作った僕の書いたコードの位置を表示して実行が中断されることを意味します。

なぜ、そのことに気がついたかと言うと、嘘をついても始まりませんから正直に言いますが・・・

Q:エラーの原因になった行を特定するためには、「デバッグ用 DCU を使用」 はTrueにしておくのが正しいのですか? それとも False にする方が正しいのですか? あなたに訊いたら、ある時はTrueにせよ、ある時はFalseにせよ、と一貫性がない答えをいただいて混乱しています。True/Falseどちらが良いのか、わかりやすく解説してください。

この問いに対し AI は『 状況によって正解が変わるんですよ 』と、まるで人間みたいな前置きをした上で、「デバッグ用 DCU を使用」の True / False による挙動の違いを説明してくれました(その極めて簡単にしすぎた感もある要約が上記の表です)。

そぉ だったのかー と、素直に感動☆

もちろん、僕の今後の「デバッグ用 DCU を使用」の設定は False の一択に決定です。僕の書いたコードが VCL にどんな迷惑をかけたかなんてことよりも、その迷惑をかける「きっかけ」となった記述(コード)のある行の方がド素人には重要なのです。

そこを直せば VCL に迷惑をかけずに済むのですから・・・

Delphi 作ったヒト、ほんとにすごいなー☆☆☆

湧き上がる新たな感動に心を震わせたまま、思ったことは(これは My Blog に残しておかなきゃ!)・・・みたいな・・・邪(よこしま)な思い。なんで邪と思うのか、その理由は言葉にできませんが。

Blogに残すにはナニはともあれ、エラー発生時に表示されていた CPU ウィンドウを記録しておかねば・・・と、まともな方向でプログラム書いてる時には思ったこともない「エラーの発生を心から願う」という理解し難い気持ちを抱えつつ、Debug 関連の設定を初期状態(?)に戻してエラーを再現・・・

(エラーが起きるのを、こんな楽しみにしたことも、なかったなー☆)

そう思いつつ、エラーを起こすプログラムを実行(F9)・・・

あ・れ?

CPU Window が出てこない!

どーゆーこと? みたいな・・・

これはもう AI に責任をとってもらうしかありません。

【こんなプロンプトでも AI は言いたいことを理解してくれました!】

Q:今までずっとCPUウィンドウしか出なかったのですが、設定を元に戻しても今度はCPUウィンドウが出なくなりました。なぜですか? 

【驚きの回答の要約】

結論:「一度デバッグ環境をクリーンにしてビルドし直した」ことによって、Delphiの内部管理(デバッグ情報の紐付け)が正常化された。今までCPUウィンドウしか出なかったのは「異常な状態」で、今ソースコードが出るようになったのが「正常な状態」。

そうなった理由は主に3つ。

1.「クリーンアップ」の効果
「プロジェクトをクリーンアップ」したことにより、古い設定(デバッグ情報が壊れていた、あるいはパスが通っていなかった時期)の残骸(.dcu や .exe)が完全に消去された。

2.デバッガが「ソースの場所」を学習(一度「デバッグ用DCU」をオンにしてビルドした際、Delphiのデバッガは「VCLのソースコードはここにある」というパスを正確に認識した。そのため、設定をオフに戻しても、デバッガが「前回の情報を手がかりにソースを見つけ出せる」ようになった。

3.エラー発生元 が「自分のコード」から呼ばれている
あるメソッドを実行してエラーが起きた際、デバッガはまずエラー地点(DLL内)を見るが、「そこはソースがないから、一歩手前の呼び出し元を表示しよう」と判断する。呼び出し元は僕の書いた Unit1.pas。今の環境は「自分のソースコードがどこにあるか」をデバッガが完璧に把握している状態なので、ソースコードを優先して表示し、CPUウィンドウを隠してしまう。

よーするに、今までの僕の環境が異常だったってコト?

つまり、僕の「エラー発生時にまず表示されるのは CPU Window である」というこれまでの認識は完全な誤りでした。

4.まとめ

(1)デバッグ情報不足(含むPath)だと、IDEは「ソースなし」と判断、CPUウィンドウを表示。
(2)デバッグ情報を設定し直すと、ソースコードが優先的に表示されるようになるカモ。
(3)デバッグ用DCUのTrue/Falseの使い分け
 ・自分のミスを探すなら False
 ・VCL 内部でのエラー発生の仕組み・位置を知りたいなら True
(4)今回の出来事を Blog に書いてもイイ?って AI に尋ねたら「全然いいよー」ってお返事でした。
(5)エラーが発生した際に CPU Window が表示されるのはデフォルト設定ではありません。

5.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容(プログラムを含む)を利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。