2013-01-09 10 views
15

私は大規模なDelphiコードベースを64ビットに適合させることに取り組んでいます。多くの場合、ポインタがこれに似た32ビット値から/にキャストされている行があります。私は彼らが正しい作る代わりに、nativeint型が-キャストと私はそれらを交換してきたこれらのキャストを見つけることができますDelphi 64-bit:間違ったキャストを見つけましたか?

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

は64ビットモード。

しかし、私はそれらをすべて見つけたとは思いません。時にはキャストがより微妙なので、文字列 "integer("は十分ではありません)の文字列検索だけです。

ポインタ値が整数の範囲を超えていると "integer私はアイデアを持っています:メモリマネージャに4GB以上のメモリを割り当てさせることができれば(ポインタ値が32ビット以上を使用しているため)、実行時エラーが発生し、誤ったキャストを見つけやすくなります。これは可能ですか他の誰かが他のテクニックをお勧めしますか?

答えて

21

あなたが使っているテキスト検索の範囲を超えて、これらのキャストを見つけるのに魔法のトリックはありません。それがそうでないことを非常に失望させる。

このような問題が発生した場合は、NativeIntに変更しないでください。ポインタを型付きポインタに変更し、ポインタ算術を使用します。

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

あなたのコードは永遠に安全です。

整数にキャストする必要がある状況がいくつかあります。たとえば、アドレスをSendMessageに渡す場合。しかし、適切な場合は、WPARAMまたはLPARAMにキャストしてください。

ランタイムエラーを強制するあなたの考えは健全であり、ありがたいことにオリジナルではありません!フルバージョンのFastMMを使用し、AlwaysAllocateTopDownを定義する必要があります。これにより、FastMMがVirtualAllocにするコールがMEM_TOP_DOWNフラグを渡すよう強制されます。これにより、誤ったキャストの大部分がランタイムポインタの切り捨てエラーとしてフラッシュされます。

ただし、メモリマネージャによって割り当てられたメモリのトップダウン割り当てのみが強制されます。プロセスの他のモジュールは、ボトムアップのデフォルトポリシーを使用します。マシン全体の設定を変更して、そのデフォルトポリシーを変更することができます。 HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreferenceREG_DWORDを値0x100000に設定して再起動してください。

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

+2

ありがとう、MEM_TOP_DOWNフラグは非常に興味深いです。私が働いているプロジェクトはカスタムデバッグアロケータを持っているので、今度はフラグを使用するように変更しました。非常に遅いですが、私はすでに変換バグを見つけています。 –

関連する問題