2009-09-24 7 views
4

Quelles sont les techniques de détection/débogage de fuite de mémoire si vous n'avez pas d'outils de trace?débogage de fuite de mémoire

+0

Besoin d'un peu d'aide - quelle langue, plate-forme, marque-o-bière? – n8wrl

+0

sur quelle plateforme êtes-vous? Windows/Linux? Quelle langue utilisez-vous? –

+0

en utilisant C sur la plate-forme intégrée – Boodr

Répondre

6

Intercept toutes les fonctions qui allouent et désallouer la mémoire (en fonction de la plate-forme, la liste peut ressembler à: malloc, calloc, realloc, strdup, getcwd, gratuit), et en plus d'exécuter ce que ces fonctions font l'origine, enregistrer des informations sur les appels quelque part, dans un tableau global en croissance dynamique probablement, protégé par des primitives de synchronisation pour les programmes multithread.

Ces informations peuvent inclure le nom de la fonction, la quantité de mémoire demandée, l'adresse du bloc alloué avec succès, la trace de la pile qui vous permet de déterminer le nom de l'appelant, etc. Dans free(), supprimez l'élément correspondant du tableau (s'il n'y en a aucun, un mauvais pointeur est passé gratuitement, ce qui est également une erreur qui peut être détectée rapidement). Lorsque le programme se termine, vider les éléments restants du tableau - ils seront les blocs qui ont fui. Ne pas oublier les objets globaux qui allouent et libèrent des ressources respectivement avant et après main(). Pour compter correctement ces ressources, vous devez vider les ressources restantes après le dernier objet global est détruit, donc une petite bidouille de votre exécution du compilateur peut être nécessaire

+0

Sur une appliance de production utilisant une libc de stock (qui doit être mise à jour à partir du fournisseur de système d'exploitation). Comment est-ce utile? J'admire votre réflexion ici, mais la solution que vous proposez n'est pas pratique. De plus, malloc() et free() sont très pointilleux d'une plateforme à l'autre. Je n'ai pas voté, mais je ne peux pas voter quelque chose de hacky et de non portable. –

+0

Sur une appliance de production utilisant une librairie stock ... vous pouvez intercepter les fonctions d'allocation mémoire avec cette approche: http://www.gnu.org/software/libtool/manual/libc/Hooks-for-Malloc.html. Déjà discuté à SO, en passant: http://stackoverflow.com/questions/269659/using-malloc-hooks – dmityugov

3
  1. Vérifiez vos boucles
  2. Regardez où vous allouez des variables - vous jamais les désallouer? Essayez de reproduire la fuite avec un petit sous-ensemble de code suspecté.
  3. Créez des outils de trace - vous pouvez toujours vous connecter à un fichier.
+0

Absolument, vérifiez les boucles. Presque tout ce qui compte pour une fuite doit être dans un code qui boucle beaucoup. Un grand nombre de programmes ont des fuites dans le code qui s'exécute seulement une fois de temps en temps et personne ne remarque ou s'en soucie. –

+0

Une fuite peut être aussi simple que si (i == 1); str = strdup ("foo"); Ce ne sont pas seulement des boucles, mais aussi des conditionnels. En l'absence d'outils comme valgrind, la meilleure méthode est plus de globes oculaires sur le code à mesure qu'il évolue. Vous ne pouvez pas faire confiance à votre compilateur pour vous avertir de tout :) –

2

Diviser et conquérir est la meilleure approche. Si vous avez écrit votre code de manière systématique, il devrait être assez facile d'appeler des sous-ensembles de votre code. Votre meilleur pari est d'exécuter chaque section de code encore et encore et voir si votre utilisation de la mémoire grimpe régulièrement, sinon passer à la section suivante du code.

En outre, le wikipedia article sur les fuites de mémoire a plusieurs grands liens dans la section des références sur la détection des fuites de mémoire pour différents systèmes (fenêtre, macos, linux, etc)

4

Une possibilité pourrait être de compiler le code et l'exécuter sur un système où vous pouvez profiter de construire des outils (par exemple libumem sur Solaris, ou libc capability sous Linux)

+0

+1, mcheck() et mprobe() sont de très bons amis à moi sur les appareils où valgrind ne rentre tout simplement pas :) –

1

des questions similaires sur SO:

En plus des techniques d'inspection manuelles mentionnées par d'autres, vous devriez envisager un outil d'analyse de code tel que valgrind.

Présentation de leur site:

Valgrind est un cadre d'instrumentation primé pour la construction outils d'analyse dynamique. Il ya Les outils Valgrind qui peuvent automatiquement détecter de nombreux bugs de gestion de la mémoire et , et de profiler vos programmes en détail. Vous pouvez également utiliser Valgrind pour créer de nouveaux outils.

La distribution Valgrind actuellement comprend six outils de qualité de production: un détecteur d'erreur de mémoire, deux fils détecteurs d'erreur, un cache et profileur branche de prédiction, un cache de génération subséquente graphique profileurs, et un tas profileur. Il comprend également deux outils expérimentaux: un détecteur de dépassement heap/stack/global array , et un générateur de vecteur SimPoint basic block . Il fonctionne sur les plates-formes suivantes: X86/Linux, AMD64/Linux, PPC32/Linux, PPC64/Linux, et X86/Darwin (Mac OS X).

+0

Je suppose que le PO essaie de dire il ne peut pas utiliser des outils d'analyse dynamique comme Valgrind lorsqu'il dit «sans trace d'outils». Je ne connais aucune plate-forme embarquée sur laquelle Valgrind puisse fonctionner. Il pourrait essayer Splint (http://splint.org/) qui est un outil d'analyse statique. – Falaina

0

Je l'ai utilisé memtrace http://www.fpx.de/fp/Software/MemTrace/ http://sourceforge.net/projects/memtrace/

Vous peut avoir besoin d'appeler la fonction de statistiques pour imprimer s'il y a des fuites. Le mieux est d'appeler cette fonction de statistiques avant et après l'exécution d'un module ou d'un morceau de code. * Attention * Memtrace est assez aimable pour permettre l'écrasement/le double libre de la mémoire. Il détecte ces anomalies et évite gracieusement tout crash.