15

私は大規模なDelphiコードベースを64ビットに適応させることに取り組んでいます。多くの場合、次のような32ビット値との間でポインタがキャストされる行があります。

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

これらのキャストを見つけることができる場合は、64ビットモードで正しくするために、代わりにNativeInt-castに置き換えました。

しかし、私はそれらすべてを見つけたかどうかはわかりません。キャストがより微妙な場合もあるため、文字列「integer(」をテキスト検索するだけでは不十分です。

ポインタ値が整数型の範囲を超えると、「integer(」キャストは64ビットで失敗するため、メモリマネージャに4GBを超えるメモリを割り当てるように強制できるとしたらどうなるでしょうか(ポインタ値がより多くを使用しているため)。 32ビットよりも)?そうすると、ランタイムエラーが発生し、間違ったキャストをより簡単に見つけることができます。これは可能ですか?または、他の手法を推奨できる人はいますか?

4

1 に答える 1

21

使用している種類のテキスト検索を超えて、これらのキャストを見つけるための魔法のトリックはありません。コンパイラがそのようなキャストについて警告した場合、それは本当に素晴らしいことです。そうでないのはとても残念だと思います。

そのような問題を見つけた場合は、変更しないでください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_DWORD0x100000

これにより、マシンに安定性の問題が発生する可能性があることに注意してください。多くのアプリケーションはこれに対応できません。特に、この設定に対応できるウイルス対策製品はほとんどありません。MSE は、マシン全体のトップダウン割り当てで動作することがわかったものです。さらに、64 ビット デバッガーはトップダウン割り当てでは実行されません! したがって、デバッガーなしでこの種のテストを行う必要があります。私のQC レポートはまだ開いていて、この問題は XE3 でも対処されていません。

于 2013-01-09T09:07:37.340 に答える