स्वचालित मेमोरी लीक चेकर्स का एक सर्वेक्षण
इस उत्तर में, मैं मेमोरी लीक उदाहरण को समझने के लिए एक सरल आसान में कई अलग-अलग मेमोरी लीक चेकर्स की तुलना करता हूं।
कुछ भी करने से पहले, आसन विकी में इस विशाल तालिका को देखें, जो मनुष्य को ज्ञात सभी साधनों की तुलना करती है: https://github.com/google/sanitizers/wiki/AddressSanitizerComparisonOfMemoryTools/d06220f759fec97066888e5f27c7e722832b09b0924
उदाहरण का विश्लेषण किया जाएगा:
main.c
#include <stdlib.h>
void * my_malloc(size_t n) {
return malloc(n);
}
void leaky(size_t n, int do_leak) {
void *p = my_malloc(n);
if (!do_leak) {
free(p);
}
}
int main(void) {
leaky(0x10, 0);
leaky(0x10, 1);
leaky(0x100, 0);
leaky(0x100, 1);
leaky(0x1000, 0);
leaky(0x1000, 1);
}
गिटहब अपस्ट्रीम ।
हम यह देखने की कोशिश करेंगे कि विभिन्न उपकरण स्पष्ट रूप से हमें टपकी कॉल के लिए कैसे इंगित करते हैं।
Google द्वारा gperftools से tcmalloc
https://github.com/gperftools/gperftools
उबंटू 19.04 पर उपयोग:
sudo apt-get install google-perftools
gcc -ggdb3 -o main.out main.c -ltcmalloc
PPROF_PATH=/usr/bin/google-pprof \
HEAPCHECK=normal \
HEAPPROFILE=ble \
./main.out \
;
google-pprof main.out ble.0001.heap --text
प्रोग्राम रन के आउटपुट में मेमोरी रिसाव विश्लेषण होता है:
WARNING: Perftools heap leak checker is active -- Performance may suffer
Starting tracking the heap
Dumping heap profile to ble.0001.heap (Exiting, 4 kB in use)
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 272 bytes in 2 objects
The 2 largest leaks:
Using local file ./main.out.
Leak of 256 bytes in 1 objects allocated from:
@ 555bf6e5815d my_malloc
@ 555bf6e5817a leaky
@ 555bf6e581d3 main
@ 7f71e88c9b6b __libc_start_main
@ 555bf6e5808a _start
Leak of 16 bytes in 1 objects allocated from:
@ 555bf6e5815d my_malloc
@ 555bf6e5817a leaky
@ 555bf6e581b5 main
@ 7f71e88c9b6b __libc_start_main
@ 555bf6e5808a _start
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
pprof ./main.out "/tmp/main.out.24744._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv
If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it might help find leaks more re
Exiting with error code (instead of crashing) because of whole-program memory leaks
और उत्पादन google-pprof
में ढेर उपयोग विश्लेषण शामिल हैं:
Using local file main.out.
Using local file ble.0001.heap.
Total: 0.0 MB
0.0 100.0% 100.0% 0.0 100.0% my_malloc
0.0 0.0% 100.0% 0.0 100.0% __libc_start_main
0.0 0.0% 100.0% 0.0 100.0% _start
0.0 0.0% 100.0% 0.0 100.0% leaky
0.0 0.0% 100.0% 0.0 100.0% main
आउटपुट हमें दो तीन लीक की ओर इशारा करता है:
Leak of 256 bytes in 1 objects allocated from:
@ 555bf6e5815d my_malloc
@ 555bf6e5817a leaky
@ 555bf6e581d3 main
@ 7f71e88c9b6b __libc_start_main
@ 555bf6e5808a _start
Leak of 16 bytes in 1 objects allocated from:
@ 555bf6e5815d my_malloc
@ 555bf6e5817a leaky
@ 555bf6e581b5 main
@ 7f71e88c9b6b __libc_start_main
@ 555bf6e5808a _start
मुझे यकीन नहीं है कि तीसरा क्यों नहीं दिखा
किसी भी मामले में, जब आमतौर पर जब कुछ लीक होता है, तो यह बहुत बार होता है, और जब मैंने इसे एक वास्तविक परियोजना पर इस्तेमाल किया, तो मैंने बस लीक होने वाले फ़ंक्शन को बहुत आसानी से इंगित किया।
जैसा कि आउटपुट पर ही उल्लेख किया गया है, यह एक महत्वपूर्ण निष्पादन मंदी है।
आगे के प्रलेखन:
इसे भी देखें: TCMalloc का उपयोग कैसे करें?
उबंटू 19.04 में परीक्षण किया गया, google-perftools 2.5-2।
एड्रेस सेनिटाइज़र (आसन) भी Google द्वारा
https://github.com/google/sanitizers
पहले उल्लेख किया गया था: C ++ कोड / प्रोजेक्ट में मेमोरी लीक कैसे करें?TODO बनाम tcmalloc।
यह पहले से ही जीसीसी में एकीकृत है, इसलिए आप बस कर सकते हैं:
gcc -fsanitize=address -ggdb3 -o main.out main.c
./main.out
और निष्पादन आउटपुट:
=================================================================
==27223==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 4096 byte(s) in 1 object(s) allocated from:
#0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
#2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
#3 0x55bf86c5f210 in main /home/ciro/test/main.c:20
#4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)
Direct leak of 256 byte(s) in 1 object(s) allocated from:
#0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
#2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
#3 0x55bf86c5f1f2 in main /home/ciro/test/main.c:18
#4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x7fabbefc5448 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10c448)
#1 0x55bf86c5f17c in my_malloc /home/ciro/test/main.c:4
#2 0x55bf86c5f199 in leaky /home/ciro/test/main.c:8
#3 0x55bf86c5f1d4 in main /home/ciro/test/main.c:16
#4 0x7fabbecf4b6a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x26b6a)
SUMMARY: AddressSanitizer: 4368 byte(s) leaked in 3 allocation(s).
जो स्पष्ट रूप से सभी लीक की पहचान करता है। अच्छा!
आसन अन्य शांत जांच भी कर सकते हैं जैसे कि बाहर की सीमाएं लिखती हैं: स्टैक स्मैशिंग का पता चला
उबंटू 19.04, जीसीसी 8.3.0 में परीक्षण किया गया।
वेलग्रिंड
http://www.valgrind.org/
पहले बताया गया: https://stackoverflow.com/a/37661630/895245
उपयोग:
sudo apt-get install valgrind
gcc -ggdb3 -o main.out main.c
valgrind --leak-check=yes ./main.out
आउटपुट:
==32178== Memcheck, a memory error detector
==32178== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==32178== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==32178== Command: ./main.out
==32178==
==32178==
==32178== HEAP SUMMARY:
==32178== in use at exit: 4,368 bytes in 3 blocks
==32178== total heap usage: 6 allocs, 3 frees, 8,736 bytes allocated
==32178==
==32178== 16 bytes in 1 blocks are definitely lost in loss record 1 of 3
==32178== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178== by 0x10915C: my_malloc (main.c:4)
==32178== by 0x109179: leaky (main.c:8)
==32178== by 0x1091B4: main (main.c:16)
==32178==
==32178== 256 bytes in 1 blocks are definitely lost in loss record 2 of 3
==32178== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178== by 0x10915C: my_malloc (main.c:4)
==32178== by 0x109179: leaky (main.c:8)
==32178== by 0x1091D2: main (main.c:18)
==32178==
==32178== 4,096 bytes in 1 blocks are definitely lost in loss record 3 of 3
==32178== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==32178== by 0x10915C: my_malloc (main.c:4)
==32178== by 0x109179: leaky (main.c:8)
==32178== by 0x1091F0: main (main.c:20)
==32178==
==32178== LEAK SUMMARY:
==32178== definitely lost: 4,368 bytes in 3 blocks
==32178== indirectly lost: 0 bytes in 0 blocks
==32178== possibly lost: 0 bytes in 0 blocks
==32178== still reachable: 0 bytes in 0 blocks
==32178== suppressed: 0 bytes in 0 blocks
==32178==
==32178== For counts of detected and suppressed errors, rerun with: -v
==32178== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
तो एक बार फिर, सभी लीक का पता चला था।
यह भी देखें: मैं मेमोरी लीक को खोजने के लिए वेलग्रिंड का उपयोग कैसे करूं?
उबंटू 19.04 में परीक्षण किया गया, 3.14.0 मान्य।