Rumah >Tutorial sistem >LINUX >Alat yang berkuasa untuk menyelesaikan masalah memori di bawah Linux

Alat yang berkuasa untuk menyelesaikan masalah memori di bawah Linux

王林
王林ke hadapan
2024-02-12 22:20:141087semak imbas

1. Kebocoran memori

Memory Leak bermakna memori timbunan yang diperuntukkan secara dinamik dalam program tidak dikeluarkan atau tidak boleh dikeluarkan atas sebab tertentu, mengakibatkan pembaziran memori sistem, yang membawa kepada akibat yang serius seperti kelembapan program atau ranap sistem.

Alat yang berkuasa untuk menyelesaikan masalah memori di bawah Linux

Ciri-ciri

  • Penyembunyian Kerana kebocoran memori berlaku kerana blok memori tidak dilepaskan, ia adalah kecacatan ketinggalan dan bukannya kecacatan kesalahan
  • Kebocoran memori kumulatif biasanya tidak secara langsung menghasilkan simptom ralat yang boleh diperhatikan, tetapi secara beransur-ansur terkumpul, mengurangkan prestasi keseluruhan sistem, dan dalam kes yang melampau boleh menyebabkan sistem ranap. Soalan yang paling intuitif ialah mengapa program kami mula berjalan seperti biasa dan kemudian keluar secara tidak normal selepas beberapa ketika.

Kebocoran memori tidak bermakna kehilangan fizikal memori, tetapi selepas aplikasi memperuntukkan segmen memori tertentu, disebabkan oleh ralat penggunaan, ia kehilangan kawalan ke atas segmen memori sebelum ia dikeluarkan, mengakibatkan memori tidak dilepaskan Dan membazir.

Sebab

Apabila kami menggunakan pembolehubah storan dinamik semasa pembangunan program, kami pasti menghadapi masalah pengurusan memori. Ruang storan yang diperuntukkan secara dinamik dalam program perlu dikeluarkan selepas program dilaksanakan. Kebocoran memori yang disebabkan oleh tidak melepaskan ruang storan yang diperuntukkan secara dinamik adalah masalah utama menggunakan pembolehubah storan dinamik. Dalam keadaan biasa, pembangun selalunya akan menggunakan fungsi pengurusan memori asas yang disediakan oleh sistem, seperti malloc、realloc、calloc、free, dsb., untuk melengkapkan peruntukan dan pelepasan ruang storan pembolehubah storan dinamik. Walau bagaimanapun, apabila membangunkan program yang menggunakan banyak pembolehubah storan dinamik dan kerap menggunakan panggilan fungsi, ralat pengurusan memori sering berlaku.

2. Bagaimana untuk menyelesaikan masalah kebocoran memori

Kita pasti akan menghadapi kebocoran memori semasa proses pembangunan harian kita Ini adalah masalah biasa. Memandangkan kebocoran memori telah berlaku, kita perlu menyelesaikan masalah kebocoran memori. Saya percaya anda sering menggunakan alatan berikut untuk menyelesaikan masalah ingatan, seperti berikut:

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

Hari ini, Mu Rong tidak memperkenalkan alat penyelesaian masalah di atas, tetapi memperkenalkan satu lagi alat penyelesaian masalah kebocoran memori: AddressSanitizer (ASan). Ia menyokong Linux, OS, Android dan platform lain Ia bukan sahaja dapat mengesan kebocoran memori, ia adalah alat pengesan ralat memori yang boleh mengesan banyak masalah memori biasa.

Pengesanan masalah ingatan biasa:

  • Kebocoran memori
  • Akses rentas sempadan
  • Memori bebas digunakan

3. Alat AddressSanitizer(ASan)

Address Sanitizer(ASan) ialah alat pengesanan ralat memori yang pantas. Ia sangat pantas, hanya memperlahankan program kira-kira dua kali (lebih cepat daripada Valgrind). Ia termasuk modul instrumentasi pengkompil dan perpustakaan masa jalan yang menyediakan alternatif malloc()/free(). Bermula dengan gcc 4.8, AddressSanitizer menjadi sebahagian daripada gcc. Sudah tentu, untuk mendapatkan pengalaman yang lebih baik, sebaiknya gunakan versi 4.9 dan ke atas, kerana AddressSanitizer gcc 4.8 masih belum sempurna, dan kelemahan terbesar ialah tiada maklumat simbol.

Cara penggunaan:

  • Susun dan pautkan program anda dengan pilihan -fsanitize=address.
  • Susun dengan -fno-omit-frame-pointer untuk mendapatkan surih tindanan yang lebih mudah difahami.
  • Pilihan -O1 atau kompilasi tahap pengoptimuman yang lebih tinggi
rreeee

Memori bocor

gcc -fsanitize=address -o main -g main.c

Kompilasi output

Alat yang berkuasa untuk menyelesaikan masalah memori di bawah Linux

Memori di luar sempadan

  • Tumpukan memori di luar batas
rreeee

Jalankan output

#include 

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

int main(int argc, char *argv[])
{
    Fun();
    return 0;
}
  • Memori global di luar batas
rreeee

Jalankan output

#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;
}

Gunakan memori yang dibebaskan

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

Jalankan output

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$

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 内存泄漏
  • Untuk butiran lanjut, sila layari laman web rasmi

Untuk butiran, sila lihat dokumentasi rasmi Google: https://github.com/google/sanitizers/wiki/AddressSanitizer

Kesimpulan

ASan ialah alat yang sangat baik untuk mengesan masalah memori Ia tidak memerlukan konfigurasi persekitaran dan mudah digunakan Apabila menyusun, anda hanya perlu -fsanitize=address -g ASAN_OPTIONS pembolehubah persekitaran untuk mengesan banyak masalah memori. Jika ada yang kurang jelas, anda boleh menyemak arahan rasmi Selamat datang untuk bertukar dan belajar.

Atas ialah kandungan terperinci Alat yang berkuasa untuk menyelesaikan masalah memori di bawah Linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:lxlinux.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam