GNU/Linux >> Tutoriels Linux >  >> Linux

Imprimer la valeur du pointeur de pile

Une astuce, qui n'est pas portable ni même garantie de fonctionner, consiste à simplement imprimer l'adresse d'un local sous forme de pointeur.

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

Cela imprimera essentiellement l'adresse de p qui est une bonne approximation du pointeur de pile actuel


Il n'existe aucun moyen portable de le faire.

Dans GNU C, cela peut fonctionner pour les ISA cibles qui ont un registre nommé SP, y compris x86 où gcc reconnaît "SP" comme l'abréviation de ESP ou RSP.

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

Cette utilisation des variables de registre locales est désormais obsolète par GCC :

La seule utilisation prise en charge pour cette fonctionnalité est de spécifier des registres pour les opérandes d'entrée et de sortie lors de l'appel d'Extended asm

La définition d'une variable de registre ne réserve pas le registre. Sauf lors de l'appel de l'asm étendu, le contenu du registre spécifié n'est pas garanti. Pour cette raison, les utilisations suivantes ne sont explicitement pas prises en charge. S'ils semblent fonctionner, ce n'est que par hasard , et peut cesser de fonctionner comme prévu en raison de changements (apparemment) sans rapport avec le code environnant, ou même de changements mineurs dans l'optimisation d'une future version de gcc. ...

C'est également cassé dans la pratique avec clang où sp est traitée comme n'importe quelle autre variable non initialisée.


En plus de la réponse de duedl0r avec spécifiquement GCC vous pouvez utiliser __builtin_frame_address(0) qui est spécifique à GCC (mais pas x86 spécifique).

Cela devrait également fonctionner sur Clang (mais il y a quelques bogues à ce sujet).

Prendre l'adresse d'un local (comme l'a répondu JaredPar) est aussi une solution.

Notez que AFAIK, la norme C ne nécessite aucune pile d'appels en théorie.

On pourrait rêver d'une autre technique. Et vous pourriez avoir des piles fractionnées (au moins sur GCC récent), auquel cas la notion même de pointeur de pile a beaucoup moins de sens (car alors la pile n'est pas contiguë et pourrait être constituée de plusieurs segments de quelques cadres d'appel chacun) .


Linux
  1. La valeur maximale de l'ID de processus ?

  2. Ny Way To Print Value Inside Variable Inside Single Quote?

  3. Comment imprimer les lignes numéro 15 et 25 sur 50 lignes ?

  4. L'exécution de 'gcc' sur le fichier source C++ sous Linux donne cc1plus :allocation de mémoire insuffisante... message d'erreur

  5. Pouvez-vous faire en sorte que n'importe quel programme sous Linux imprime une trace de pile en cas d'erreur de segmentation ?

imprimer la pile d'appels en C ou C++

Comment obtenir une trace de pile pour C++ en utilisant gcc avec des informations de numéro de ligne ?

Curl écrit la valeur d'un en-tête spécifique

Empêcher le débordement d'entier C

Valeur de retour de x =os.system(..)

Qu'est-ce qui définit fs:[0x28] (stack canary) ?