Maison > Tutoriel système > Linux > Un outil puissant pour résoudre les problèmes de mémoire sous Linux

Un outil puissant pour résoudre les problèmes de mémoire sous Linux

王林
Libérer: 2024-02-12 22:20:14
avant
1085 Les gens l'ont consulté

1. Fuite de mémoire

Une fuite de mémoire signifie que la mémoire tas allouée dynamiquement dans le programme n'est pas libérée ou ne peut pas être libérée pour une raison quelconque, ce qui entraîne un gaspillage de mémoire système, entraînant de graves conséquences telles qu'un ralentissement de l'exécution du programme ou même un crash du système.

Un outil puissant pour résoudre les problèmes de mémoire sous Linux

Caractéristiques

  • Dissimulation Parce que la fuite de mémoire se produit parce que le bloc mémoire n'est pas libéré, il s'agit d'un défaut d'omission plutôt que d'un défaut de faute
  • Les fuites de mémoire cumulatives ne produisent généralement pas directement de symptômes d'erreur observables, mais s'accumulent progressivement, réduisant les performances globales du système et, dans des cas extrêmes, peuvent provoquer un crash du système. La question la plus intuitive est de savoir pourquoi notre programme démarre normalement puis se termine anormalement après un certain temps.

Les fuites de mémoire ne signifient pas la disparition physique de la mémoire, mais qu'après que l'application a alloué un certain segment de mémoire, en raison d'erreurs d'utilisation, elle perd le contrôle du segment de mémoire avant qu'il ne soit libéré, ce qui entraîne la non-libération de la mémoire. . Et gaspillé.

Cause

«

Lorsque nous utilisons des variables de stockage dynamiques lors du développement d'un programme, nous sommes inévitablement confrontés à des problèmes de gestion de la mémoire. L'espace de stockage alloué dynamiquement dans le programme doit être libéré après l'exécution du programme. Les fuites de mémoire causées par la non-libération de l'espace de stockage alloué dynamiquement sont les principaux problèmes liés à l'utilisation de variables de stockage dynamiques. Dans des circonstances normales, les développeurs utiliseront souvent les fonctions de base de gestion de la mémoire fournies par le système, telles que malloc、realloc、calloc、free, etc., pour finaliser l'allocation et la libération de l'espace de stockage variable de stockage dynamique. Cependant, lorsqu'un programme de développement utilise beaucoup de variables de stockage dynamique et utilise fréquemment des appels de fonction, des erreurs de gestion de la mémoire se produisent souvent.

2. Comment résoudre les fuites de mémoire

«

Nous rencontrerons inévitablement des fuites de mémoire au cours de notre processus de développement quotidien. Il s'agit d'un problème courant. Puisqu'une fuite de mémoire s'est produite, nous devons résoudre le problème de fuite de mémoire. Je pense que vous utilisez souvent les outils suivants pour résoudre les problèmes de mémoire, comme suit :

  • memwatch
  • mtrace
  • dmalloc
  • ccmalloc
  • valgrind
  • debug_new

Aujourd'hui, Mu Rong ne présente pas l'outil de dépannage ci-dessus, mais présente un autre outil de dépannage de fuite de mémoire : AddressSanitizer (ASan). Il prend en charge Linux, OS, Android et d'autres plates-formes. Il peut non seulement détecter les fuites de mémoire, mais c'est également un outil de détection des erreurs de mémoire qui peut détecter de nombreux problèmes de mémoire courants.

Détection des problèmes de mémoire courants :

  • Fuite de mémoire
  • Accès transfrontalier
  • Mémoire libérée utilisée

3. Outil AddressSanitizer (ASan)

«

Address Sanitizer(ASan) est un outil de détection rapide des erreurs de mémoire. C'est très rapide, ne ralentissant le programme que d'environ deux fois (beaucoup plus rapide que Valgrind). Il comprend un module d'instrumentation du compilateur et une bibliothèque d'exécution qui fournit des alternatives malloc()/free(). À partir de gcc 4.8, AddressSanitizer fait partie de gcc. Bien sûr, pour obtenir une meilleure expérience, il est préférable d'utiliser la version 4.9 et supérieure, car l'AddressSanitizer de gcc 4.8 n'est pas encore parfait et le plus gros inconvénient est qu'il n'y a pas d'informations sur les symboles.

Comment utiliser :

  • Compilez et liez votre programme avec l'option -fsanitize=address.
  • Compilez avec -fno-omit-frame-pointer pour obtenir une trace de pile plus compréhensible.
  • Compilation facultative de niveau d'optimisation -O1 ou supérieur
gcc -fsanitize=address -o main -g main.c
Copier après la connexion

Fuite de mémoire

#include 

void Fun()
{
    char *pM = malloc(10);
}

int main(int argc, char *argv[])
{
    Fun();
    return 0;
}
Copier après la connexion

Sortie de compilation

Un outil puissant pour résoudre les problèmes de mémoire sous Linux

Mémoire hors limites

  • Empilez la mémoire hors des limites
#include 
#include 

void Fun()
{
    char *pM = malloc(10);
}

int main(int argc, char *argv[])
{
    //Fun();
    int *array = malloc(10*sizeof(int));
    if(array)
    {
            memset(array, 0, 10*sizeof(int));
    }
    int res = array[10];

    free(array);
    return 0;
}
Copier après la connexion

Exécuter la sortie

ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ gcc -fsanitize=address -o main -g main.c
ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ ls
main  main.c
ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ ./main
=================================================================
==3234==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000dff8 at pc 0x000000400854 bp 0x7ffccc9253d0 sp 0x7ffccc9253c0
READ of size 4 at 0x60400000dff8 thread T0
    #0 0x400853 in main /home/ubuntu/workspace_ex/Linux/ASan/main.c:16
    #1 0x7fafc87a883f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
    #2 0x4006f8 in _start (/home/ubuntu/workspace_ex/Linux/ASan/main+0x4006f8)

0x60400000dff8 is located 0 bytes to the right of 40-byte region [0x60400000dfd0,0x60400000dff8)
allocated by thread T0 here:
    #0 0x7fafc8bea602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x4007f7 in main /home/ubuntu/workspace_ex/Linux/ASan/main.c:11
    #2 0x7fafc87a883f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ubuntu/workspace_ex/Linux/ASan/main.c:16 main
Shadow bytes around the buggy address:
  0x0c087fff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c087fff9bf0: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 00[fa]
  0x0c087fff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==3234==ABORTING
Copier après la connexion
  • La mémoire globale hors des limites
#include 
#include 

int g_nArray[10] = {0};

void Fun()
{
    char *pM = malloc(10);
}

int main(int argc, char *argv[])
{
    //Fun();

    /*
    int *array = malloc(10*sizeof(int));
    if(array)
    {
            memset(array, 0, 10*sizeof(int));
    }
    int res = array[10];

    free(array);
    */

    int nIndex = g_nArray[10];
    return 0;
}
Copier après la connexion

Exécuter la sortie

ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ gcc -fsanitize=address -o main -g main.c
ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ ls
main  main.c
ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ ./main 
=================================================================
==4196==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000601128 at pc 0x00000040083e bp 0x7ffc8a332540 sp 0x7ffc8a332530
READ of size 4 at 0x000000601128 thread T0
    #0 0x40083d in main /home/ubuntu/workspace_ex/Linux/ASan/main.c:26
    #1 0x7fda216a583f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
    #2 0x400718 in _start (/home/ubuntu/workspace_ex/Linux/ASan/main+0x400718)

0x000000601128 is located 0 bytes to the right of global variable 'g_nArray' defined in 'main.c:4:5' (0x601100) of size 40
SUMMARY: AddressSanitizer: global-buffer-overflow /home/ubuntu/workspace_ex/Linux/ASan/main.c:26 main
Shadow bytes around the buggy address:
  0x0000800b81d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800b81e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800b81f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800b8200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800b8210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0000800b8220: 00 00 00 00 00[f9]f9 f9 f9 f9 f9 f9 00 00 00 00
  0x0000800b8230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800b8240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800b8250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800b8260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000800b8270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==4196==ABORTING
ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ 
Copier après la connexion

Utilisez la mémoire libérée

#include 
#include 
#include 

int g_nArray[10] = {0};
int *p;

void Fun()
{
    char *pM = malloc(10);
}

void Fun1()
{
    int nVar = 0;
    p = &nVar;
}

int main(int argc, char *argv[])
{
    //Fun();

    int *array = malloc(10*sizeof(int));
    if(array)
    {
            memset(array, 0, 10*sizeof(int));
    }
    int res = array[10];

    free(array);

    array[0] = 1;

    return 0;
}
Copier après la connexion

Exécuter la sortie

ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ gcc -fsanitize=address -o main -g main.c
ubuntu@ubuntu:~/workspace_ex/Linux/ASan$ ./main
=================================================================
==4954==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000dff8 at pc 0x000000400b68 bp 0x7ffefbe3b170 sp 0x7ffefbe3b160
READ of size 4 at 0x60400000dff8 thread T0
    #0 0x400b67 in main /home/ubuntu/workspace_ex/Linux/ASan/main.c:28
    #1 0x7f1bbb78983f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
    #2 0x400928 in _start (/home/ubuntu/workspace_ex/Linux/ASan/main+0x400928)

0x60400000dff8 is located 0 bytes to the right of 40-byte region [0x60400000dfd0,0x60400000dff8)
allocated by thread T0 here:
    #0 0x7f1bbbbcb602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x400b0b in main /home/ubuntu/workspace_ex/Linux/ASan/main.c:23
    #2 0x7f1bbb78983f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ubuntu/workspace_ex/Linux/ASan/main.c:28 main
Shadow bytes around the buggy address:
  0x0c087fff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c087fff9bf0: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 00[fa]
  0x0c087fff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==4954==ABORTING
ubuntu@ubuntu:~/workspace_ex/Linux/ASan$
Copier après la connexion

AddressSanitizer能检测的错误类型

错误类型 错误描述
(heap) Use after free 访问堆上已被释放的内存
Heap buffer overflow 堆上缓冲区访问溢出
Stack buffer overflow 栈上缓冲区访问溢出
Global buffer overflow 全局缓冲区访问溢出
Use after return 访问栈上已被释放的内存
Use after scope 栈对象使用超过定义范围
Initialization order bugs 初始化命令错误
Memory leaks 内存泄漏
  • Pour plus de détails, veuillez visiter le site officiel

Pour plus de détails, veuillez consulter la documentation officielle de Google : https://github.com/google/sanitizers/wiki/AddressSanitizer

Conclusion

«

ASan est un très bon outil pour détecter les problèmes de mémoire. Il ne nécessite pas de configuration de l'environnement et est facile à utiliser lors de la compilation, vous n'avez besoin que de -fsanitize=address -g Lors de l'exécution du programme, vous pouvez choisir d'ajouter le correspondant. Variable d'environnement ASAN_OPTIONS pour détecter de nombreux problèmes de mémoire. Si quelque chose n'est pas clair, vous pouvez consulter les instructions officielles Bienvenue pour échanger et apprendre.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:lxlinux.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal