2012-08-06 8 views
6

Ho un puntatore disponibile con me a una variabile C/C++. È possibile distinguere esattamente a quale segmento della memoria appartiene questa variabile? Se sì, come?Identificazione se un indirizzo appartiene all'heap o allo stack o ai registri

Nota: non mi resta che l'indirizzo di questa variabile, senza ulteriori informazioni se la variabile è locale/globale, ecc

+8

Non è possibile, almeno non in un modo portabile. – juanchopanza

+3

Quale problema stai cercando di risolvere? Avete bisogno di una soluzione runtime o in fase di compilazione? i registri non hanno indirizzi. –

+0

Abbiamo appena avuto una discussione se la variabile globale sarebbe appartenuta allo stack o all'heap, volevamo confermarci: P –

risposta

2

scoprire se il vostro architettura ha puntatori a vostra heap o pila regione. Di solito ci sono alcuni stackpointers o framepointers ..

Quindi confronta il tuo indirizzo effettivo con quegli indirizzi e decidi dove appartengono.

+0

hehe, sì hai ragione;) Ma se parli di architetture esotiche, è anche possibile inserire variabili globali nello stack o nell'heap. Anche questo dipende dall'architettura. – duedl0r

+0

Ho già detto che l'hardware di Univac non aveva uno stack? .-) –

+0

Credo solo in cose inventate dopo il 1981 hehehe: D – duedl0r

1

È possibile innanzitutto identificare quali sono l'inizio e la fine delle diverse sezioni nel file eseguibile. Per questo, è necessario aggiungere alla fine alcune variabili nello script del linker intorno ad ogni sezioni in questo modo:

SECTIONS { 
    [...] 
    .data : { 
     data_start = .; 
     *(.data) 
     data_end = .; 
    } 
    [...] 
} 

Si può quindi dichiarare queste variabili come esterno nel codice C/C++ e utilizzarli direttamente per confrontare l'indirizzo voglio identificare.

Potrebbe non essere facile modificare lo script del linker. Con gcc, è possibile scaricare con:

gcc -Wl,-verbose whatever.c 

poi cerca di trovare le variabili già definite nel uscita (disordinato).

Per ottenere i limiti della pila, è possibile creare un'istanza di una variabile fittizia all'inizio della funzione main() e salvare il suo indirizzo come la parte superiore della pila, quindi istanziarne un'altra nella posizione corrente, che darti il ​​fondo Tuttavia, si noti che il compilatore potrebbe non comportarsi esattamente come questo (l'ordine di stack delle variabili in C non è garantito, nemmeno l'uso dello stack), quindi questo dovrebbe funzionare ma non essere portabile.

Infine, per il mucchio, non ho trucco. Vorrei solo dedurre che una variabile non in data/bss/derivata e non nello stack sarebbe nell'heap (esclusi i registri, ma se riesci a ottenere l'indirizzo, scommetterei che il compilatore non userà mai una memoria di sola registrazione).

2

Se si utilizza Linux (non sicuro di altri sistemi Unix), si potrebbe essere in grado di trovare le informazioni nel file /proc/<pid>/maps

0

non so esattamente se si adatta la vostra situazione, ma si può provare objdump -t per vedere la tabella dei simboli di un file elfo. Tutto ciò di cui hai bisogno è l'indirizzo della tua variabile. Lì puoi trovare le bandiere che mostrano la sezione per ogni variabile. Fare riferimento alla pagina man per objdump per ulteriori dettagli. Uscita

Esempio:

0804a020 g  O .bss 00000004    var 

Si dice var è un bject g lobal O in indirizzo 0804a020, sezione .bss

Problemi correlati