Delphi 64位:发现错误的演员表?

Vil*_*nde 15 delphi 64-bit memory-management delphi-xe2

我正在努力将大型Delphi代码库调整为64位.在许多情况下,有些行指针是从32位值转换为32位值,类似于:

var
  p1,p2 : pointer;
begin
  inc(Integer(p1),10);
  p2 := Pointer(Integer(p1) + 42);
Run Code Online (Sandbox Code Playgroud)

在我可以找到这些演员表的地方,我已经用NativeInt-cast替换它们,而不是在64位模式下使它们正确.

但是我不确定我是否找到了所有这些.有时候演员表更精细,所以只需要对字符串"整数"进行文本搜索,这也是不够的.

由于"整数("转换将在64位失败,如果指针值高于整数类型的范围我有一个想法:如果我可以强制内存管理器分配4gb以上的内存(所以指针值使用更多)比32位)?然后我会得到运行时错误,并且可以更容易地找到错误的演员.这可能吗?或者任何人都可以推荐其他技术?

Dav*_*nan 21

除了您正在使用的文本搜索之外,找到这些演员表并没有神奇的技巧.如果编译器警告这样的演员,那将是非常好的.我觉得非常令人失望.

当您发现此类问题时,请勿更改为NativeInt.将指针更改为类型指针,并使用指针算法.

var
  p1, p2: PByte;
....
inc(p1, 10);
p2 := p2;
inc(p2, 42);
Run Code Online (Sandbox Code Playgroud)

那么你的代码将永远安全.

在某些情况下,您需要转换为整数.例如,将地址传递给SendMessage.但要将这些投射到任何一个WPARAMLPARAM适当的.

你强迫运行时错误的想法是合理的,谢天谢地,不是原创!您应该使用FastMM的完整版本并定义AlwaysAllocateTopDown.这会强制FastMM发出的调用VirtualAlloc来传递MEM_TOP_DOWN标志.这会将大多数错误的强制转换清除为运行时指针截断错误.

但是,这只会强制自上而下分配内存管理器分配的内存.您的流程中的其他模块将使用自下而上的默认策略.您可以设置机器范围设置以更改该默认策略.设置HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreferenceREG_DWORD有值0x100000并重新启动.

请注意,这可能会导致您的机器出现稳定性问题.许多应用程序无法应对此问题.特别是很少有能够应对这种情况的防病毒产品.MSE是我发现使用机器范围自上而下分配的那个.更重要的是,64位调试器不能在自顶向下分配下运行!所以你必须在没有调试器的情况下进行这种测试.我的QC报告仍然是开放的,即使在XE3中也没有解决这个问题.

  • 谢谢,MEM_TOP_DOWN标志非常有趣.我正在工作的项目有一个自定义的调试分配器,所以刚才我做了修改使用标志.它很慢但我已经发现了转换错误. (2认同)