2009-08-05 7 views
2

Je vais implémenter un profileur interne pour la mémoire sous Linux. Je veux sauvegarder la pile pour chaque malloc/free/realloc. J'essaie d'utiliser "pstack" pour obtenir la trace de la pile à chaque fois. Mais les frais généraux sont trop élevés. Y at-il une approche lightweigt pour obtenir la pile d'appels en code C?Obtenez la pile d'appels dans le code avec moins de frais généraux?

Je sais qu'il y a des outils comme "valgrind, google profiler", mais je ne sais pas comment ils réapprovisionnent les piles pour chaque action.

Un commentaire est apprécié.

Merci.

+1

Que diriez-vous de reformuler votre « question » dans une vraie question? – Bombe

+2

Vous pouvez toujours juste jeter un oeil à [http://valgrind.org/downloads/] – GManNickG

+0

edited Désolé pour la description peu claire .. – limi

Répondre

2

Vous pouvez faire votre propre fonction pour obtenir l'appelant:

static inline void *get_caller(void) { 
    unsigned long *ebp; 

    /* WARNING: This is working only with frame pointers */ 
    asm ("movl %%ebp, %0" : "=r" (ebp) :); 
    ebp = (unsigned long*)*ebp; 
    ebp = (unsigned long*)*(ebp+1); 
    return ebp; 
} 

void *malloc(void) { 
    void *caller = get_caller(); 
    ...  
} 

« ebp = (unsigned long*)*ebp; » vous fera passer par la pile (si vous avez besoin de plus de cette trace de la pile).

+0

merci beaucoup.C'est ce que j'aime – limi

4

Il existe une fonction GNU backtrace() qui est relativement rapide - elle renvoie simplement un tableau d'adresses.

Pour résoudre ces adresses en noms de fonctions, vous devez utiliser backtrace_symbols(), ce qui est beaucoup plus lourd mais, espérons-le, vous n'avez pas besoin de l'exécuter trop souvent.

Pour obtenir backtrace_symbols() réellement résoudre les noms, vous devez utiliser les options de l'éditeur de liens -rdynamic.

Voir man backtrace pour plus de détails.

0

Attention aux récursions avec backtrace_symbols(), qui appelle lui-même malloc.

Notez également que lors de la première utilisation de backtrace() et des amis, l'éditeur de liens dynamiques essaiera de charger libgcc, qui appellera encore une fois malloc.

Gilad

0

Maintenant, je rencontre un problème sur 64 bits.

Sur 64 bits, RBP n'est pas strictement maintenu. Par exemple, gcc -O3 utilisera RBP comme registre enregistré par l'appelant normal. Donc dans ce cas, pour obtenir appeler des piles de pointeurs de cadre ne fonctionne pas. :(

Tous les commentaires?

+0

sur 64bit, maintenant j'utilise backtrace() – limi

Questions connexes