デバッグ時のブレークポイントが効かない

解決


おも  2009-08-07 03:57:03  No: 35357

ソースコードの行数が多くなると、コンパイルやコンパイル後のプログラムの動作は期待した通りで正常なのですが、ブレークポイントを設定しても、デバッグモードで走らせると、赤色が、無効な行に設定しているいう深緑になり効かなくなる現象がでています。

調べてみると、過去のQ&Aにも似た現象は報告されていましたが、細かい状況は不明で結論はありませんでした。

BDS2006(DelphiWin32)でchttps://www.petitmonte.com/bbs/answers?question_id=4281

以下のテストコードを使って単純なテストを実施しました。テストはTFormにTButtonを一つおいて、押されたら、'hoge'と表示するだけの単純なものです。

試行したのは、途中に改行を入れて、強制的にUnitの行数を多くしただけです。すると、私の環境では、Win2000、XPの両方で、現象が再現しました。

ただ、現象が出る行数は少し調べただけですがあまり一定してなくて、トータル35000行ぐらいの時もあれば、40000行台の場合もあるという感じでばらついているように感じます。

もともと、この現象に気がついた実際のソースコードでは、大体、65000行台になってくると現象が現れました。

今のところ、バグなのかな?と思って、移せる部分を他のUnitへ移して、トータルの行数を抑制する方向で逃げていますが、根本的に回避可能な方法があれば、アドバイスをお願いします。

よろしくお願いします。

Delphi 6 Personal, Win2000 & XP

〜  テストコード開始  〜

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{
ここに多数の空白行を追加すると、コンパイルやプログラムとしての動作そのものは正常だが、以下のShowMessage('hoge')に対するブレークポイントが効かなくなる
}

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage('hoge');
end;

end.

〜  テストコード終わり〜


HOta  2009-08-07 18:31:49  No: 35358

再構築をしても同じですか?


おも  2009-08-08 07:50:34  No: 35359

HOtaさん、レスありがとうございます。

再構築、Delphiの再起動、PCの再起動をしても現象は変わりませんでした。

また、もともとのソースコードでも、行数の多かったUnit1でブレークポイントが効かなかっただけで、行数の少なかったUnit2以降では問題有りませんでした。

上記のテストプログラムにForm2(Unit2)を追加して同じボタン機能をつけてみたところ、こちらの現象も再現し、Unit1のShowMessage('hoge')にはブレークポイントを設定しても、無効と判断されますが、行数の少ないUnit2のShowMessage('hoge')ではブレークポイントが有効になりました。


ぽむぽむ  2009-08-09 06:42:14  No: 35360

行数ではありませんが、Constで宣言したサイズが大きくなったときに
コンパイルされた行のマークがでなくなったことがあります。
当然ブレークポイントも効きません。

nifty serve 時代の FDelphi というフォーラムで読んだことがあり、
当方でも再現したことがあります。
32768バイトくらいが限界だとか、そうじゃないとか・・・

const
  c16 = '0123456789abcdef';
  c64 = c16 + c16 + c16 + c16;
  c256 = c64 + c64 + c64 + c64;
  c1024 = c256 + c256 + c256 + c256;
  c4096 = c1024 + c1024 + c1024 + c1024;
  c16384 = c4096 + c4096 + c4096 + c4096;
  ca: array[0..65535] of Char = c16384 + c16384 + c16384 + c16384;

これくらい宣言しておけば、再現できるはず。


ぽむぽむ  2009-08-09 06:42:44  No: 35361

おっと、解決とかにまったく関係なくてすいません


とおりすがりの2  2009-08-09 20:31:25  No: 35362

Delphi7 Ent で調査してみました
const
  ca: array[0..65395] of Char = '';
だとNGで
const
  ca: array[0..65394] of Char = '';
だとOKでした
たぶんDelphiのバグですね、以前から放置してあるバグですね


おも  2009-08-09 21:36:21  No: 35363

ぽむぽむさん、とおりすがりの2さん、レスありがとうございます。

ぽむぽむさん、非常に有用な情報ありがとうございます。
とおりすがりの2さん、具体的な事例の提示ありがとうございます。

私の環境では、Delphi 6 Personal + Win2000/XPの二つの環境でともに、とおりすがりの2さんの数値とは少し違いますが現象が再現しました。

★NG
const
  ca: array[0..65135] of Char = '';

★OK
const
  ca: array[0..65134] of Char = '';

現象の原因となることが単純なバグとはいえ、原因の発見が困難な場合がありますから、非常に有用で助かります。ありがとうございました。

話題としては、結論を得たということで、とりあえず、解決としておきます。

以下は備考程度なので読み流してください。
ぽむぽむさんが、constの設定の仕方でも同じような現象になると指摘されたときに、そういえばと思い出した現象がありました。
実害はないので、これまで気にしてませんでしたが、procedure内でvar変数をたくさん設定しすぎると、そのprocedureに対するコンパイル時にでる、

[ヒント]Unit1.pas(29):変数'i'が宣言されていますが'TForm1.Button1Click'の中では使われていません

というような不要な変数に対するコメントが、そのprocedureに対するものだけでなくなります。

当然といえば、当然ですけど、色々なことについて、数的な限界があるようですね。


HOta  2009-08-10 19:19:41  No: 35364

最初のコードを2007で試しました。こちらはちゃんとブレークポイントは設定できます。


おも  2009-08-11 04:52:06  No: 35365

HOtaさん、レスありがとうございます。

2007では大丈夫でしたか、貴重な情報ありがとうございます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加