【问题标题】:Delphi 64-bit: finding incorrect casts?Delphi 64 位:找到不正确的转换?
【发布时间】:2013-01-09 08:26:45
【问题描述】:

我正在努力使大型 Delphi 代码库适应 64 位。在许多情况下,有几行指针被转换为/从 32 位值转换,类似于:

var
  p1,p2 : pointer;
begin
  inc(Integer(p1),10);
  p2 := Pointer(Integer(p1) + 42);

在哪里可以找到这些转换,我已将它们替换为 NativeInt-casts,以使它们在 64 位模式下正确。

但是我不确定我是否已经找到了所有这些。有时演员阵容更加微妙,因此仅对字符串“integer(”进行文本搜索也是不够的。

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

【问题讨论】:

    标签: delphi memory-management 64-bit delphi-xe2


    【解决方案1】:

    除了您正在使用的文本搜索之外,没有什么神奇的技巧可以找到这些演员表。如果编译器警告这样的演员表,那就太好了。我觉得很失望,它没有。

    当您确实发现此类问题时,请不要更改为NativeInt。将指针更改为类型化指针,并使用指针算法。

    var
      p1, p2: PByte;
    ....
    inc(p1, 10);
    p2 := p2;
    inc(p2, 42);
    

    那么您的代码将永远安全。

    仍有一些情况需要转换为整数。例如,将地址传递给SendMessage 时。但酌情将它们转换为WPARAMLPARAM

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

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

    请注意,这可能会导致您的机器出现稳定性问题。许多应用程序无法应对这种情况。特别是很少有防病毒产品可以应对这种设置。 MSE 是我发现适用于机器范围自上而下分配的一种。更何况 64 位调试器不能在自顶向下分配下运行!所以你必须在没有调试器的情况下进行这种测试。我的QC report 仍处于打开状态,这个问题还没有得到解决,即使在 XE3 中也是如此。

    【讨论】:

    • 谢谢,MEM_TOP_DOWN 标志很有趣。我正在工作的项目有一个自定义调试分配器,所以刚才我进行了修改以使用该标志。它很慢,但我已经发现了转换错误。
    猜你喜欢
    • 2011-11-22
    • 2012-02-27
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 2012-09-22
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多