GNU/Linux >> Linux Esercitazione >  >> Linux

Stampa il valore del puntatore dello stack

Un trucco, che non è portatile e nemmeno garantito per funzionare, è semplicemente stampare l'indirizzo di un locale come puntatore.

void print_stack_pointer() {
  void* p = NULL;
  printf("%p", (void*)&p);
}

Questo essenzialmente stamperà l'indirizzo di p che è una buona approssimazione del puntatore dello stack corrente


Non esiste un modo portatile per farlo.

In GNU C, questo può funzionare per gli ISA target che hanno un registro denominato SP, incluso x86 dove gcc riconosce "SP" come abbreviazione di ESP o RSP.

// broken with clang, but usually works with GCC
register void *sp asm ("sp");
printf("%p", sp);

Questo utilizzo delle variabili di registro locali è ora deprecato da GCC:

L'unico utilizzo supportato per questa funzione è specificare i registri per gli operandi di input e output quando si chiama Extended asm

La definizione di una variabile di registro non riserva il registro. A parte quando si invoca l'asm esteso, il contenuto del registro specificato non è garantito. Per questo motivo, i seguenti usi non sono esplicitamente supportati. Se sembrano funzionare, è solo un caso , e potrebbe smettere di funzionare come previsto a causa di modifiche (apparentemente) non correlate nel codice circostante, o anche di modifiche minori nell'ottimizzazione di una versione futura di gcc. ...

In pratica è anche rotto con clang where sp viene trattata come qualsiasi altra variabile non inizializzata.


Oltre alla risposta di duedl0r specificatamente GCC potresti usare __builtin_frame_address(0) che è specifico di GCC (ma non x86 specifico).

Questo dovrebbe funzionare anche su Clang (ma ci sono alcuni bug a riguardo).

Prendere l'indirizzo di un locale (come ha risposto JaredPar) è anche una soluzione.

Si noti che AFAIK lo standard C non richiede alcuno stack di chiamate in teoria.

Si potrebbe sognare un'altra tecnica. E potresti avere stack divisi (almeno nel recente GCC), nel qual caso la nozione stessa di puntatore dello stack ha molto meno senso (perché allora lo stack non è contiguo e potrebbe essere composto da molti segmenti di pochi frame di chiamata ciascuno) .


Linux
  1. Timeout in uno script di shell?

  2. Qual è il modo per stampare il valore all'interno della variabile all'interno del preventivo singolo?

  3. Come eseguire il mmap dello stack per la chiamata di sistema clone() su Linux?

  4. Curl scrive il valore di un'intestazione specifica

  5. Valore di ritorno di x =os.system(..)

Cercando di capire il complicato allineamento dello stack di gcc nella parte superiore di main che copia l'indirizzo di ritorno

Come stampare pthread_t

stampa stack di chiamate in C o C++

Come ottenere una traccia dello stack per C++ usando gcc con le informazioni sul numero di riga?

Prevenire l'overflow di numeri interi C

Cosa imposta fs:[0x28] (stack canary)?