web-dev-qa-db-fra.com

Débogage léger des fuites de mémoire sous Linux

J’ai d’abord cherché les réponses existantes et constaté que Valgrind était l’outil de prédilection de tous pour le débogage des fuites de mémoire sous Linux. Malheureusement, Valgrind ne semble pas fonctionner pour moi. Je vais essayer d'expliquer pourquoi.

Contraintes:

  • La fuite ne se reproduit que dans l’environnement du client. En raison de certaines restrictions légales, nous devons travailler avec les fichiers binaires existants. Pas de reconstruction.
  • Dans un environnement normal, notre application consomme environ 10% de la CPU. Disons que nous pouvons tolérer jusqu’à 10 fois l’utilisation du processeur. Valgrind avec les paramètres par défaut memcheck Rend bien pire notre application, rendant notre application inactive pendant de longues périodes de temps.

Il me faut un équivalent de la UMDH de Microsoft: activer le traçage de pile pour chaque allocation de segment de mémoire, puis, à un moment donné, vider toutes les allocations regroupées par piles et ordonnées par ordre décroissant. Notre application est livrée sur les plates-formes Windows et Linux. Je sais donc que les performances sous Windows sous UMDH sont toujours acceptables.

Voici les outils/méthodes que j'ai considérés

  • Outils _ {Valgrind-memcheck et –massif _ Ils font beaucoup plus que nécessaire (comme l'analyse de la mémoire de processus complète pour chaque affectation Pointeur), ils sont trop lents , et ils ne font toujours pas exactement ce que je
    need (dump callstacks triés par nombre), je vais donc devoir écrire quelques scripts en analysant le résultat
  • dmalloc librairie (dmalloc.com) nécessite un nouveau fichier binaire
  • LeakTracer ( http://www.andreasen.org/LeakTracer/ ) Fonctionne uniquement avec C++ nouveau/supprimer (j'ai besoin de malloc/free également) , n'a pas de fonctionnalité group-by-stack and sort
  • Implémenter moi-même l'outil en tant que bibliothèque .so à l'aide du mécanisme LD_PRELOAD ( Remplacement de 'malloc' à l'aide du mécanisme LD_PRELOAD ) Cela prendra au moins une semaine compte tenu de mes compétences en codage pour Linux et c'est comme si on inventait un vélo.

Est-ce que j'ai manqué quelque chose? Existe-t-il des options légères Valgrind ou un outil LD_PRELOAD existant?

16
glagolig

De manière surprenante, je n’ai rien trouvé de comparable à l’UMDH de Microsoft dans un domaine open-source ni à un téléchargement immédiat. (J'ai aussi regardé Google Heap Leak Checker mais cela ressemble plus à Valgrind qu'à UMDH). J'ai donc fini par écrire l'outil moi-même en utilisant Malloc Instrumentation Project comme point de référence: 

https://github.com/glagolig/heapwatch

L'outil a un certain nombre de limitations, mais il a très bien fonctionné pour mes besoins.

1
glagolig

GNU libc a un débogage malloc intégré:

http://www.gnu.org/software/libc/manual/html_node/Allocation-Debugging.html

Utilisez LD_PRELOAD pour appeler mtrace() à partir de votre propre fichier .so:

#include <mcheck.h>
static void prepare(void) __attribute__((constructor));
static void prepare(void)
{
    mtrace();
}

Compilez-le avec:

gcc -shared -fPIC dbg.c -o dbg.so

Exécutez-le avec:

export MALLOC_TRACE=out.txt
LD_PRELOAD=./dbg.so ./my-leaky-program

Plus tard, inspectez le fichier de sortie:

mtrace ./my-leaky-program out.txt

Et vous obtiendrez quelque chose comme:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000001bda460     0x96  at /tmp/test/src/test.c:7

Bien sûr, n'hésitez pas à écrire vos propres crochets malloc qui vident toute la pile (appelez backtrace () si vous pensez que cela va vous aider).

Les numéros de lignes et/ou les noms de fonction pourront être obtenus si vous conservez les informations de débogage pour le binaire (par exemple, le binaire contient des informations de débogage intégrées ou si vous avez objcopy --only-keep-debug my-leaky-program my-leaky-program.debug).


Vous pouvez aussi essayer le GC de Boehm, qui fonctionne également comme détecteur de fuite:

http://www.hpl.hp.com/personal/Hans_Boehm/gc/leak.html

14
DanielKO

Je voudrais annoncer mon utilitaire heaptrack qui vient d’être annoncé, qui devrait être exactement ce que vous cherchiez à l’époque. Vous pouvez trouver plus d'informations ici: http://milianw.de/blog/heaptrack-a-heap-memory-profiler-for-linux

Comparativement à votre outil heapwatch, les performances devraient être bien meilleures, car j’utilise libunwind, puis libbacktrace, pour retarder l’annotation de la trace de retour avec les informations de débogage DWARF.

J'aimerais avoir plus de commentaires à ce sujet, alors essayez-le!

3
milianw

memleax devrait fonctionner pour vous.

Il débogue une fuite de mémoire d'un processus en cours en le connectant, sans programme de recompilation ni redémarrage du processus cible. C'est très pratique et adapté à l'environnement de production.

Il TRAPs uniquement pour les appels malloc/free (), il devrait donc avoir moins d’impact sur les performances que Vagrild.

Cela fonctionne sur GNU/Linux-x86_64 et FreeBSD-AMD64.

NOTE: je suis l'auteur, toute suggestion est la bienvenue

2
Bingzheng Wu

MemoryScape répondrait à vos besoins. Il s'agit de l'outil de débogage dynamique de la mémoire fourni avec le débogueur TotalView

http://www.roguewave.com/products/memoryscape.aspx

2
SebGR

@glagolig, 

Oui, MemoryScape peut regrouper les allocations par emplacement de pile.

Avez-vous pu obtenir la version d'évaluation? En supposant que vous utilisiez une adresse e-mail qui ne ressemble pas à un bot, vous auriez dû nous répondre assez rapidement. Sinon, ou si vous rencontrez des problèmes techniques, contactez-moi ou contactez notre équipe d'assistance technique. 

Chris Gottbrath

Chef de produit principal pour TotalView chez Rogue Wave Software

email: Prénom. Nom de famille (à) roguewave. com

1
Chris Gottbrath

Il existe un outil gratuit et open source appelé chap qui fera presque tout ce que vous voulez. En particulier, il ne vous donnera pas de traces de pile, mais c’est un outil extrêmement léger car il ne nécessite aucune instrumentation. Tout ce dont vous avez besoin est de pouvoir capturer un noyau réel du processus en question, à un moment où vous pensez que le processus a déjà présenté le bogue (donc vous croyez qu'il a fui ou est trop volumineux).

Pour plus de détails, voir https://github.com/vmware/chap

0
Tim Boddy