web-dev-qa-db-fra.com

Vider la mémoire, enregistrer la sortie formatée dans un fichier

J'ai un logiciel buggy (fuite de mémoire) . Comme preuve, j'ai 1 Go de fichier core.dump. La taille du tas est de 900 Mo, donc évidemment, quelque chose est alloué, mais ne libérez pas la mémoire.

Donc, j'ai une région de la mémoire à examiner comme ça.

(gdb) x/50000s 0x200000000

Cependant, ceci est difficile à deviner uniquement à l'oeil nu, quel objet ou quelle structure n'est pas libéré . Mon idée de tracer est, "Enregistrer la sortie au format gdb dans un fichier, et exécuter une correspondance de motif pour voir quelle chaîne magique apparaît le plus." Voici donc ma question:

Comment puis-je sauvegarder la sortie de la commande suivante dans un fichier texte, afin de pouvoir écrire un analyseur?

(gdb) x/10000000s 0x20000000    <-- I need this output into a file
14
Raymond

Vous pouvez utiliser la fonction "dump" de gdb, voir: https://sourceware.org/gdb/onlinedocs/gdb/Dump_002fRestore-Files.html

Pour votre exemple:

dump binary memory result.bin 0x200000000 0x20000c350

Cela vous donnera un fichier binaire complet binaire int result.bin. Vous pouvez également utiliser les éléments suivants pour le vider au format hexadécimal:

dump ihex memory result.bin 0x200000000 0x20000c350

Utiliser la commande dump est beaucoup plus clair que d'utiliser le hack de journalisation gdb (qui n'a même pas fonctionné pour moi d'une manière ou d'une autre).

29
eci

Comment puis-je sauvegarder la sortie de la commande suivante dans un fichier texte, afin de pouvoir écrire un analyseur?

 (gdb) x/10000000s 0x20000000

C'est en fait assez facile:

(gdb) set height 0    # prevent GDB from stopping every screenfull
(gdb) set logging on  # GDB output is now also copied into gdb.txt
(gdb) x/10000000s 0x20000000
(gdb) quit

Voilà, profitez de votre sortie en gdb.txt.

J'ai un logiciel buggy (fuite de mémoire). ... "Enregistrez la sortie au format gdb dans un fichier et exécutez une correspondance de motif pour voir quelle chaîne magique apparaît le plus."

Il est peu probable que cette idée donne des résultats satisfaisants. Considérer:

void some_function() {
   std::vector<string> *v = new std::vector<string>();
   // code to insert and use 1000s of strings into "v".
   return;  // Oops: forgot to delete "v".
}

Même si vous pouviez effectivement "voir la chaîne magique qui monte le plus", vous découvrirez que vous perdez toutes les chaînes; mais ils sont pas le problème, la fuite "v" est le problème.

Donc, ce que vous voulez vraiment, c'est créer un graphique indiquant les régions allouées qui pointent vers d'autres régions allouées et trouver une "racine" de ce graphique. C'est presque impossible à faire à la main.

Alors, qu'est-ce que plus est susceptible de vous aider à trouver la ou les fuites de mémoire? Heureusement, il existe beaucoup d'outils qui peuvent résoudre ce problème pour vous:

12
Employed Russian

vous pouvez écrire simple lkm le fera

lkm:
#include <linux/kernel.h>
#include <linux/module.h>

int  *ptr=(int*)0Xc18251c0; //the address you want to read from kernel space
int module_i(void)
{
 printk("%d\n",*ptr);
}
module_init(module_i);

et les données apparaîtront dans le journalso écrire

enter code here
dmesg
0
Daniel Haish