2013-01-09 7 views
15

Sto lavorando per adattare una grande base di codice Delphi a 64-bit. In molti casi ci sono linee in cui i puntatori sono pressofuso da/per valori a 32 bit simile a questo:Delphi 64-bit: trovare cast errati?

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

Dove posso trovare questi calchi li ho sostituiti con nativeint-getta, invece di farli corretta 64- modalità bit.

Tuttavia non sono sicuro di averli trovati tutti. A volte i cast sono più sottili, quindi solo la ricerca del testo per la stringa "intero" non è sufficiente

Poiché il "numero intero" ("casts" non riuscirà a 64-bit se il valore del puntatore è sopra l'intervallo dell'intero tipo I ho un'idea: cosa succede se potrei forzare il gestore della memoria ad allocare memoria superiore a 4gb (quindi i valori del puntatore utilizzano più di 32-bit)? Allora otterrei errori di runtime e posso trovare più facilmente i cast che sono sbagliati. È possibile o qualcuno può raccomandare qualche altra tecnica?

risposta

21

Non c'è alcun trucco magico per trovare questi modelli oltre il tipo di ricerca di testo che si sta utilizzando. Sarebbe davvero bello se il compilatore avvisasse di un simile cast. lo trovo molto deludente che non lo sia.

Quando si riscontra tale problema, non passare a NativeInt. Modificare i puntatori per essere puntatori digitati e utilizzare l'aritmetica del puntatore.

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

Quindi il codice sarà sicuro per sempre.

Ci sono ancora alcune situazioni in cui è necessario eseguire il cast in numeri interi. Ad esempio quando si passano gli indirizzi a SendMessage. Ma trasferiscili su WPARAM o su LPARAM come appropriato.

L'idea di forzare gli errori di runtime è buona e, per fortuna, non originale! È necessario utilizzare la versione completa di FastMM e definire AlwaysAllocateTopDown. Ciò impone le chiamate che FastMM effettua a VirtualAlloc per passare il flag MEM_TOP_DOWN. Ciò eliminerà la maggior parte dei tuoi cast errati come errori di troncamento del puntatore del runtime.

Tuttavia, ciò imporrà solo l'allocazione dall'alto in basso per la memoria allocata dal gestore di memoria. Altri moduli nel tuo processo useranno la politica predefinita di bottom up. È possibile impostare una macchina ampia per modificare quella politica predefinita. Impostare HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference su REG_DWORD con il valore 0x100000 e riavviare.

Si noti che questo potrebbe causare problemi di stabilità alla macchina. Molte applicazioni non riescono a far fronte a questo. In particolare ci sono pochissimi prodotti anti-virus che possono far fronte a questa impostazione. MSE è quello che ho trovato funziona con l'assegnazione top down della macchina. Inoltre, il debugger a 64 bit non funziona con l'allocazione dall'alto in basso! Quindi devi fare questo tipo di test senza il debugger. Il mio QC report è ancora aperto e questo problema non è stato risolto, anche in XE3.

+2

Grazie, il flag MEM_TOP_DOWN è molto interessante. Il progetto su cui sto lavorando ha un allocatore di debug personalizzato, quindi ora ho fatto la modifica per usare la bandiera. È molto lento ma sto già trovando bug di conversione. –