Delphi XE2:调试器关闭7-20行,编译器错误行号也相同

问题描述 投票:12回答:3

我有一个大型Delphi代码库的问题,我在那里工作,从Delphi 2007移植到XE2的副作用,我们现在遇到以下奇怪的相关问题:

  • 即使在调试版本中,也无法设置断点或单步执行代码,因为行编号全部搞乱,仅在某些单元中。
  • 故意在2010行引入语法错误将导致光标聚焦在第2020行,给出或取3或4行,如下所示:

.

 procedure Correct;
 begin
    DoSomething; // syntax error reported HERE but the real error is below.
    // more stuff here.
 end;

 procedure OllKorrect;  
 begin
        ThisLineIsFine();
        __VARIABLE_NOT_DEFINED__ := 1; // intentional error
 end

我希望有人见过这个。问题的要素可能包括:

该代码包含许多奇怪的编译器指令,如{$ REALCOMPATIBILITY ON}和{$ H - } / {$ H +}指令,代码中有数千个{$ H +} / {$ H-}指令。

其次,代码使用了很多{$ I INCLUDE}指令,我怀疑包含文件可能会直接搞乱编译器的行编号。

我无法肯定地说,但我怀疑所有这些旧的“让它像turbo pascal for DOS”编译器开关是背后的原因。我想知道是否有人肯定知道这件事。它只发生在代码中的某些地方,并且项目有500多个单元,其中一些达到10K / 20KLOC,这绝对令人沮丧。我可以说的是,不仅有{$ I include.inc}指令的单位搞砸了,而且包含大量{$ H - } / {$ H +}或{$ REALCOMPATIBILITY}指令的许多单位都做了没有这个问题。如果我能看出行为不端的单位有什么共同之处,我可以想出来。

更新:线路终止问题是有道理的。我运行此代码检测到问题。修复代码已注释掉,因为如果您取消注释并删除所有源代码,那就是您的问题。它正在将一个非unicode文件加载到unicode TStringList中并将其保存回来。这在我的世界中没问题,因为它的所有版本都受到控制和备份。你的旅费可能会改变。

program linefeedsProject1;

{$APPTYPE CONSOLE}

uses
  IOUtils,
  Classes,
  Types,
  SysUtils;


  var
    broken,notBroken:Integer;

  function fix(filename:String):Boolean;
  var
    sl:TStringList;
  begin
    sl := TStringList.Create;
    try
    sl.LoadFromFile(filename);
    //TODO:Change file extensions.
    sl.SaveToFile(filename);
    finally
      sl.Free;
    end;
  end;

  function scan(filename:String):Boolean;
  var
  crFlag:Boolean;
  lfFlag:Boolean;
  missingCr:Integer;
  missingLf:Integer;
   f:TFileStream;
   buf:Array[0..1024] of AnsiChar;
   n:Integer;
   procedure scanChars;
   var
    i:Integer;
   begin
     for i := 0 to n-1 do
     begin
       if buf[i]=#13 then
       begin
          crFlag := true;
          lfFlag := false;
       end
       else if buf[i]=#10 then
       begin
           if not crFlag then
            inc(missingCr);
          lfFlag := true;
          crFlag := false;
       end
       else begin
         if (crFlag) then
          inc(missingLf);
         crFlag := false;
         lfFlag := false;
       end;
     end;
   end;
  begin
   result := false;
   crFlag := false;
   lfFlag := false;
   missingCr := 0;
   missingLf := 0;
    f := TFileStream.Create(filename, fmOpenRead);
    try
      while f.Position< f.Size do
      begin
        n := f.Read(buf[0],1024);
        scanChars;
      end;

     if (missingCr>0) or (missingLf>0) then
     begin
          WriteLn('  ', filename);
          Inc(broken);
          result := true;
     end
     else
     begin
        Inc(notBroken);
     end
    finally
      f.Free;
    end;

  end;
var
 files:TStringDynArray;
 afile:String;
 begin
  try
  broken := 0;
  notBroken := 0;
    files := TDirectory.GetFiles('C:\dev\abackupcopyofyoursourcecode',  '*.pas',
    TSearchOption.soTopDirectoryOnly );
    // tried TSearchOption.soAllDirectories and it exploded. not recommended.

    for afile in files do
    begin
       if scan(afile) then
       begin
           // fix(afile); // uncomment at your own risk and only on a backup copy of your code.
       end;

    end;


    WriteLn('Broken ', broken);
    WriteLn('not broken ',notBroken);

   // readln;

     except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Update 2: If you want a scanner/fixer for this issue you can download mine (with source) here. Link是Google Drive。您可以从链接查看源代码,但单击“文件”下拉菜单(谷歌驱动器Web用户界面的一部分),然后单击“下载”进行下载。

delphi delphi-xe2
3个回答
22
投票

我以前见过这样的东西,而IME通常是由于计算行数时的编译器错误。如果你在某些点上有非标准的换行符(不是CRLF) - 这可能发生 - IDE会做正确的换行符,但编译器不会将它们计为新行,所以之后的所有内容都会被一个抛出。

当我遇到这样的文件时,我在EditPad中打开它,将所有换行符转换为其他样式(Unix或Mac样式),然后将所有换行符转换为Windows样式并保存。这样可以确保文件中的每一行都以CRLF结尾,并且在重建之后,没有正确排列的蓝点的问题就会消失。


9
投票

这是由不匹配的线路终端字符引起的常见问题。 (行末尾缺少CR或LF的代码。)也可能是因为.dcu与编辑器中打开的源文件不匹配。

首先,最简单的解决方法是在常规文本编辑器(如记事本)中打开源文件。进行一些小改动(插入一个空行然后删除它),然后保存文件。记事本将修复行结尾。

如果这不是问题,请在IDE的搜索路径中查找可能位于驱动器上的.dcu(或.pas)文件的额外副本。有时,编译器会看到与编辑器中打开的版本不同的版本。


0
投票

它肯定与前面的帖子中解释的行结尾相关联。尝试编辑它是非常困难的,因为Embarcadero编辑试图自己做魔术并保留当前部分的行结尾(或者看起来如此),

解决方案:右键单击IDE编辑器窗口,选择“格式化源”(Ctrl-D)并接受。

这将修复所有行结尾并消除问题(对我来说无论如何)。作为副产品,您将获得正确格式化的源代码:-)

© www.soinside.com 2019 - 2024. All rights reserved.