Outil de débogage malloc
Le débogage des applications qui ne gèrent pas correctement la mémoire allouée par le sous-système malloc peut être difficile et fastidieux. En effet, il n'y a généralement pas de synchronicité entre l'insertion d'une erreur et l'exposition de son symptôme résultant.
S'ajoute à la difficulté la complexité inhérente à l'allocation de mémoire, avec des milliers d'allocations effectuées, annulées et accédées (peut-être) de manière asynchrone et simultanée, le tout dans un contexte multitâche qui nécessite une synchronisation robuste et efficace.
C'est pour ces raisons que l'objectif de nos outils de débogage est principalement de rapprocher le moment de la détection des symptômes du moment de l'insertion de l'erreur. Cela aide le développeur d'applications à identifier plus précisément quelle section de code est responsable de la validation de l'erreur.
De nombreux outils de débogage différents ont été développés pour une utilisation avec malloc. Certaines peuvent être utilisées en combinaison avec d'autres outils de débogage et avec toutes les règles d'allocation ; d'autres sont plus limitées dans leur utilisation. De nombreux outils de débogage consomment des ressources supplémentaires à celles requises par le processus. Il appartient au développeur d'applications de fournir des ressources adéquates lorsque cela est nécessaire.
Performance Considerations
Les outils de débogage malloc ne sont pas appropriés pour une utilisation à temps plein, constante ou à l'échelle du système. Bien qu'ils soient conçus pour un impact minimal sur les performances de l'application en cours de débogage, un impact négatif significatif sur le débit global du système peut se produire s'ils sont largement utilisés dans un système. En particulier, la définition de MALLOCDEBUG=catch_overflow dans le fichier /etc/environment n'est pas recommandée et risque de provoquer des problèmes système importants, tels qu'une utilisation excessive de l'espace de pagination. Les outils de débogage malloc ne doivent être utilisés que pour déboguer des applications uniques ou de petits groupes d'applications en même temps.
En raison du travail supplémentaire impliqué dans l'exécution de diverses vérifications d'exécution, les performances du sous-système malloc se dégradent de manière variable avec les outils de débogage malloc activés (en fonction de l'outil utilisé), mais pas au point que les applications deviennent inutilisables. Une fois le problème résolu, les outils de débogage malloc doivent être désactivés pour restaurer les performances du sous-système malloc .
Considérations relatives aux disques et à la mémoire
Lorsque les outils catch_overflow ou Malloc Log sont activés, le sous-système malloc consomme beaucoup plus de mémoire.
Pour catch_overflow, chaque demande malloc est augmentée de 4096 + 2 fois la taille de la longueur non signée, puis arrondie au multiple suivant de la macro PAGESIZE. catch_overflow peut s'avérer trop gourmande en mémoire à utiliser pour les applications de très grande taille, mais pour la majorité des applications nécessitant un débogage de la mémoire, l'utilisation supplémentaire de la mémoire ne doit pas poser de problème. Pour les applications de grande taille, l'utilisation des options debug_range et functionset sur catch_overflow peut réduire considérablement l'utilisation de la mémoire, ce qui permet de déboguer le programme au coup par coup.
Pour le journal malloc, un enregistrement d'allocation est stocké pour chaque allocation active du processus. Cette surcharge de la mémoire peut être réduite en spécifiant un faible nombre de pointeurs de pile sauvegardés.
Si l'application en cours de débogage appelle fréquemment des routines d'allocation de sous-système malloc , elle peut rencontrer des problèmes d'utilisation de la mémoire avec les outils de débogage malloc activés qui pourraient empêcher l'application de s'exécuter correctement dans un seul segment. Dans ce cas, il peut être utile de permettre à l'application d'accéder à de la mémoire supplémentaire à l'aide de la commande ulimit et de l'option -bmaxdata de la commande ld .
ulimit -d unlimited
ulimit -s unlimited Pour réserver le maximum de 8 segments pour un processus 32 bits, l'option -bmaxdata doit être définie sur -bmaxdata:0x80000000.
Lorsque les outils de débogage malloc sont désactivés, les valeurs par défaut pour ulimit et -bmaxdata peuvent être restaurées.
Pour plus d'informations sur la commande ulimit et l'option -bmaxdata , voir Large Program Support.
Les outils de débogage malloc ne sont pas appropriés pour une utilisation dans certaines situations de débogage. Etant donné que certains outils malloc de débogage nécessitent la surcharge d'une page ou plus par allocation, les programmes qui émettent de nombreuses demandes d'allocation de petite taille verront leur utilisation de la mémoire augmenter considérablement. Ces programmes peuvent rencontrer de nouveaux échecs car les demandes d'allocation de mémoire sont refusées en raison d'un manque de mémoire ou d'espace de pagination. Ces échecs ne sont pas nécessairement des erreurs dans le programme en cours de débogage, et ils ne sont pas des erreurs dans l'outil malloc de débogage.
- Démarrez le serveur X avec catch_overflow désactivé.
- Démarrez une fenêtre de terminal (par exemple, dtterm, xterm, aixterm).
- Définissez les variables d'environnement appropriées dans la session de la fenêtre de terminal pour activer catch_overflow.
- Appelez le programme client X à déboguer à partir de la même fenêtre.
Activation du débogage malloc
Debug Malloc n'est pas activé par défaut, mais il est activé et configuré en définissant la variable d'environnement MALLOCDEBUG sur l'option appropriée. Si plusieurs options sont requises, elles peuvent être séparées par une virgule (,). Les options demandées en tandem doivent être compatibles entre elles.
Outils de débogage Malloc
Détection de dépassement de mémoire tampon
Les erreurs de gestion de la mémoire sont parfois causées par l'écriture du programme d'application après la fin d'une mémoire tampon allouée. Comme cela n'a souvent pas de conséquence immédiate, les symptômes ne se manifestent que beaucoup plus tard lorsque la mémoire qui a été écrasée (appartenant généralement à une autre allocation) est référencée et ne contient plus les données qui y étaient initialement stockées.
L'option de débogage catch_overflow permet aux utilisateurs d'identifier les écrasements de mémoire, les surcharges, les doublons libérés et la réutilisation de la mémoire libérée allouée par la sous-routine malloc . Les problèmes de mémoire détectés par l'outil catch_overflow entraînent un appel d'abandon ou une violation de segmentation (SIGSEGV). Dans la plupart des cas, lorsqu'une erreur est détectée, l'application s'arrête immédiatement et un fichier core est généré.
catch_overflow affecte les allocations des stratégies et options d'allocation suivantes:- Règle d'allocation par défaut
- Règle d'allocation Watson
- Option multisegment de mémoire Malloc
- Option de cache d'unités d'exécution Malloc
- Option Disclaim Malloc
L'option de débogage catch_overflow est activée en définissant MALLOCDEBUG=catch_overflow. Cela active l'identification des écrasements et des écrasements de mémoire.
- aligner
Par défaut, la sous-routine malloc renvoie un pointeur aligné sur une limite de 2 mots. Cela est nécessaire pour la conformité aux normes et pour les programmes qui ne peuvent pas accepter les accès non alignés à la mémoire (par exemple, les programmes utilisant des composants DCE). Toutefois, en raison d'un problème dans l'implémentation de l'option
catch_overflow, il est possible qu'un programme écrase une mémoire tampon d'une quantité inférieure à la valeur d'alignement sans être détecté parcatch_overflow. L'optionalignpeut être utilisée pour indiquer au sous-système malloc de ne pas tenir compte de cet alignement par défaut afin de réduire ou d'éliminer le nombre d'octets par lesquels une mémoire tampon peut être écrasée sans détection. Un alignement personnalisé peut être spécifié pour toute puissance de deux entre 0 et 4096 inclus (par exemple 0,1,2,4, ...). Les valeurs 0 et 1 sont traitées de la même manière, c'est-à-dire qu'il n'y a pas d'alignement de la mémoire ; par conséquent, tout accès à la mémoire au-delà de la zone allouée provoquera un SEGFAULT.L'optionalignfait partie de l'optioncatch_overflowet n'est significative que lorsquecatch_overflowest activé. Pour activer un alignement autre que celui par défaut, définissez la variable d'environnement MALLOCDEBUG comme suit:
où n est l'alignement souhaité.MALLOCDEBUG=catch_overflow,align:nPour calculer le nombre d'octets de surcharges ou de surcharges que l'optioncatch_overflowautorise pour une demande d'allocation donnée lorsque n est l'alignement demandé et que la taille est le nombre d'octets à allouer, utilisez la formule suivante:((((size / n) + 1) * n) - size) % nL'exemple suivant illustre l'effet de l'option align sur la capacité de l'application à effectuer des écrasements ou des écrasements avec l'option catch_overflow activée. Dans cet exemple, l'option align est spécifiée avec la valeur 2:MALLOCDEBUG=align:2,catch_overflowL'optioncatch_overflowgère les dépassements et les écrasements comme suit:- Lorsqu'un nombre pair d'octets est alloué, malloc alloue exactement le nombre d'octets demandé, ce qui autorise 0 octet de surcharges ou de surcharges.
- Lorsqu'un nombre impair d'octets est alloué, malloc alloue le nombre d'octets demandé, plus un octet supplémentaire pour satisfaire l'alignement requis. Cela permet d'obtenir 1 octet de surcharges ou de surcharges possibles.
- override_signal_handling
- L'option
catch_overflowsignale les erreurs de l'une des manières suivantes:- Les erreurs d'accès à la mémoire (telles que la tentative de lecture ou d'écriture après la fin de la mémoire allouée) provoquent une violation de segmentation (SIGSEGV), entraînant un vidage système.
- Pour les autres types d'erreur (par exemple, la tentative de libération d'espace déjà libéré), l'option
catch_overflowgénère un message d'erreur, puis appelle la fonction d'abandon, qui envoie un signal SIGIOT pour mettre fin au processus en cours.
Si le programme appelant bloque ou intercepte les signaux SIGSEGV et SIGIOT, l'option
catch_overflowne peut pas signaler d'erreurs. L'optionoverride_signal_handlingpermet de contourner cette situation sans recodage et régénération de l'application.Si l'optionoverride_signal_handlingest spécifiée, l'optioncatch_overfloweffectue les actions suivantes à chaque appel à une routine de sous-système malloc :- Désactivez les gestionnaires de signaux existants définis par l'application pour SIGSEGV ou SIGIOT.
- Définissez l'action pour SIGIOT et SIGSEGV sur la valeur par défaut (SIG_DFL).
- Débloquez SIGIOT et SIGSEGV.
Si un gestionnaire de signaux d'application modifie l'action de SIGSEGV entre les appels de routine d'allocation de mémoire, puis tente un accès de mémoire non valide, l'option catch_overflow ne peut pas signaler l'erreur (l'application ne se ferme pas et aucun fichier core n'est généré).
Remarque :- L'option
override_signal_handlingpeut être inefficace dans un environnement d'application à unités d'exécution car l'optioncatch_overflowutilise la sous-routine sigprocmask et de nombreux processus à unités d'exécution utilisent la sous-routine pthread_sigmask . - Si une unité d'exécution appelle la sous-routine sigwait sans inclure SIGSEGV et SIGIOT dans l'ensemble de signaux et que l'option
catch_overflowdétecte ensuite une erreur, l'unité d'exécution se bloque car l'optioncatch_overflowne peut générer que SIGSEGV ou SIGIOT. - Si un pointeur vers une mémoire non valide est transmis à une routine de noyau, celle-ci échouera et sera généralement renvoyée avec errno défini sur EFAULT. Si l'application ne vérifie pas le retour de l'appel système, cette erreur peut ne pas être détectée.
- Plage de débogage
Par défaut, si l'option
catch_overflowest activée, la détection de dépassement de mémoire tampon est effectuée pour chaque allocation du programme. Si l'optiondebug_rangeest spécifiée, seules les demandes d'allocation comprises entre une taille minimale et une taille maximale définies par l'utilisateur auront des dépassements de mémoire tampon détectés par l'optioncatch_overflow. Sinon, aucune détection de dépassement de mémoire tampon ne sera effectuée. Cette option permet à l'utilisateur de contrôler la quantité de ressources de mémoire supplémentaire consommée par l'optioncatch_overflowen utilisant uniquement l'outil dans des cas spécifiques.L'optiondebug_rangen'est significative que dans le contexte de l'optioncatch_overflow. Il est activé comme suit:
où min est la limite inférieure et max est la limite supérieure de la plage dans laquelle la détection de dépassement de mémoire tampon doit être effectuée. Si 0 est spécifié comme valeur minimale, toute valeur inférieure à la valeur maximale fera l'objet d'une détection de dépassement de mémoire tampon. Si 0 est spécifié comme valeur maximale, toute valeur supérieure à la valeur minimale fera l'objet d'une détection de dépassement de mémoire tampon.MALLOCDEBUG=catch_overflow,debug_range:min:maxLimitation: En raison d'une exigence d'implémentation interne, chaque allocation doit toujours avoir une taille de page d'au moins une longueur. Par conséquent, l'option
debug_rangeréduit simplement le temps système de l'optioncatch_overflowau lieu de l'éliminer.Si la sous-routine realloc est appelée avec une demande d'allocation comprise dans la plage spécifiée par l'utilisateur, la détection de dépassement de mémoire tampon est effectuée même si l'allocation d'origine n'était pas comprise dans la plage spécifiée. Le contraire est également vrai.
Remarque: Si l'optionoverride_signalest définie avec l'optiondebug_range, le remplacement du comportement des signaux SIGIOT et SIGSEGV est effectué pour toutes les allocations.- ensemble de fonctions
En raison d'une exigence de mise en oeuvre interne, chaque allocation sera toujours nécessairement d'une longueur d'au moins une taille de page. Par conséquent, l'option
functionsetréduit simplement le temps système de l'optioncatch_overflowau lieu de l'éliminer.Si la sous-routine realloc est appelée à partir d'une fonction qui est membre de la liste des fonctions spécifiées par l'utilisateur, la détection de dépassement de mémoire tampon est effectuée même si l'allocation d'origine n'a pas été effectuée à partir d'une fonction spécifiée. Le contraire est également vrai.
Remarque: Si l'optionoverride_signalest définie avec l'optionfunctionset, le remplacement du comportement des signaux SIGIOT et SIGSEGV est effectué pour toutes les allocations.L'option
functionsetne vérifie pas la validité des fonctions spécifiées dans la liste.- autoriser_sur-lecture
Par défaut, lorsque l'option de débogage
catch_overflowest activée et que le programme appelant tente de lire après la fin de la mémoire allouée, une violation de segmentation se produit et le processus effectue un cliché du processus. Toutefois, il se peut que l'utilisateur ne soit pas intéressé par l'interception de ce type d'erreur et qu'il ait activécatch_overflowafin d'intercepter des écrasements plus dangereux. Si vous spécifiez l'optionallow_overreading, l'optioncatch_overflowignore les surcharges afin que d'autres types d'erreur, qui peuvent être considérés comme plus graves, puissent être détectés en premier.L'optionallow_overreadingn'est significative que dans le contexte de l'optioncatch_overflow. Il est activé comme suit:MALLOCDEBUG=catch_overflow,allow_overreading,- postfree_chèque
L'option
postfree_checkingconsomme une quantité importante de mémoire supplémentaire. Les programmes dont les besoins en mémoire sont très importants risquent de ne pas pouvoir utiliser l'optionpostfree_checking.- Trace de malloc
Malloc Trace est une option de débogage conçue pour permettre le traçage de tous les appels à l'API du sous-système malloc via la fonction de trace du système.
- Journal des erreurs
Malloc Log est une option de débogage conçue pour fournir à l'utilisateur une base de données d'exécution des allocations actives dans le sous-système malloc .
- dotations de rapport
L'option
report_allocationsest un outil permettant de détecter les fuites de mémoire dans un programme d'application. L'optionreport_allocationsutilise la base de données créée par Malloc Log pour générer une liste des allocations actuellement détenues par l'utilisateur. Un enregistrement de chaque allocation réussie est effectué au moment de la demande par le journal Malloc. Lorsqu'une allocation est libérée, Malloc Log supprime son enregistrement de la base de données. A la sortie du processus, la liste des allocations toujours actives est imprimée à stderr, ce qui donne une liste des allocations qui n'ont jamais été libérées par leurs appelants.L'optionreport_allocationsrequiert la fonctionnalité de Malloc Log pour fonctionner. Par conséquent, le journal Malloc est implicitement activé lorsquereport_allocationsest activé. L'optionreport_allocationsest activée comme suit:MALLOCDEBUG=report_allocations- validate_ptrs
Par défaut, les API du sous-système malloc ne valident pas leurs pointeurs d'entrée pour s'assurer qu'elles référencent effectivement la mémoire précédemment allouée. Si l'un de ces pointeurs n'est pas valide, une altération grave du segment de mémoire peut se produire. Si vous spécifiez l'option
validate_ptrs, les API du sous-système malloc effectuent une validation étendue sur leurs pointeurs d'entrée. Si un pointeur s'avère non valide (c'est-à-dire qu'il ne fait pas référence à la mémoire précédemment allouée par un appel à l'API du sous-système malloc ), un message d'erreur indiquant pourquoi il n'est pas valide est imprimé, la fonction d'abandon est appelée et un fichier core est généré. L'optionvalidate_ptrsest similaire à la sous-optionverbose. L'optionvalidate_ptrsne prend pas effet si l'optionpostfree_checkingest activée.L'optionvalidate_ptrsest activée comme suit:MALLOCDEBUG=validate_ptrs- Détection de malloc
Malloc Detect est une option de débogage conçue pour détecter et signaler l'altération des structures de données internes du sous-système malloc lors de chaque appel à une API de sous-système malloc .
- verbose
Sous-option de Malloc Detect.
- arène de contrôle
Sous-option de Malloc Detect.
- sortie
Par défaut, les options de débogage malloc envoient leur sortie à stderr. Cela peut ne pas être souhaité pour tous les programmes. L'option
outputpermet de fournir une autre destination pour les informations imprimées. La sortie peut être envoyée à stderr, stdout ou à n'importe quel fichier du système.L'optionoutputest activée comme suit:MALLOCDEBUG=output:<filename>- poursuivre
De nombreuses options de débogage malloc appellent abort () lorsqu'elles détectent une erreur. Ce n'est pas toujours le comportement souhaité pour tous les programmes. L'option
continuepermet d'indiquer au sous-système malloc de continuer après la détection d'une erreur synchrone plutôt que d'abandonner le processus. Les messages d'erreur seront toujours consignés dans les canaux appropriés.L'optioncontinueest activée comme suit:MALLOCDEBUG=continue- Remplissage de débogage malloc
Malloc debug fill est une option de débogage conçue pour remplir la mémoire allouée via les appels malloc () avec un modèle spécifié par l'utilisateur à des fins de débogage.
Le modèle doit être spécifié sous forme de chaîne (par exemple, export MALLOCDEBUG=fill:abc définit la mémoire allouée via malloc avec le modèle " abc) et un maximum de 128 caractères est autorisé. Si le modèle n'est pas spécifié, l'option de remplissage est ignorée.
L'option de remplissage de débogage malloc peut être activée comme suit:
MALLOCDEBUG=fill:patternLe modèle peut être un nombre octal ou hexadécimal spécifié sous la forme d'une chaîne. Par exemple, le modèle "\101" est traité comme la notation octale pour le caractère'A'et le modèle “\x41”est traité comme la notation hexadécimale pour le caractère'A'
Si un nombre octal non valide est spécifié, par exemple \777, qui ne peut pas être contenu dans 1 octet, sera stocké sous la forme \377, la valeur octale maximale pouvant être stockée sous la forme 1 octet.