1 Overview
Valgrind can effectively monitor most of the memory problems, you can't help but think, since the C + + memory problem is so common, why not add the memory problem detection function in the compiler? Unfortunately, the GCC also does not currently support memory detection, it is gratifying that clang support. Here we see how to use Clang to discover memory problems
2 clang
Clang is a compiler frontend for C, C + +, and objective-c programming languages. It uses the underlying virtual machine as the backend. Its goal is to provide a replacement for the GNU Compiler Suite (GCC), the author of Chris Ratner, developed under the auspices of Apple Inc.
3 memory leak monitoring
Addresssanitizer is a memory error detector in Clang that detects the following issues:
- Out-of-bounds accesses to heap, stack and globals
- Use-after-free
- Use-after-return (To some extent)
- Double-free, Invalid free
- Memory Leaks (experimental)
Using clang to compile the code with-fsanitize=address can open the Addresssanitizer tool, in order to print out your program call stack when memory errors are detected, you need to add options at compile time- Fno-omit-frame-pointer option, and in order to obtain clearer call stack information, compile the program with the-O1 option.
4 Sample Code
Now I'll use clang3.4 to do an example
1:int Main ()2: {3:char *p = malloc (sizeof (char) * 10);4:if (p = = NULL) { 5:return 0; 6:} 7: 8:struct elem *e = malloc (sizeof (struct elem)); 9:i F (E = = NULL) {10:free (p); 12:} 13: 14:e->a = 10; 15:e->b = 10.10; 16:e->c = p; 17: 18:double *xx = &e->b; : 20:printf ("%f\n", *xx); : 22:free (e); 24:printf ("%f\n", *xx); 26:return 0; +:}
The above code has two problems, one is that P is not released, causing a memory leak, and the second is that xx points to a piece of freed memory. Let's see how we can detect these two problems with clang.
4.1 Compiling it
1: clang-o1-g-fsanitize=address-fno-omit-frame-pointer-o Core core.c
4.2 Memory leak monitoring process with Addresssanitizer
Run the core file directly, it will automatically print out the detected memory error
1: [[email protected] test]$./core2:10.13: =================================================================4: ==11254==error:addresssanitizer:heap-use-after-free on address 0x60300000efe8 at PC 0x48211a BP 0x7fff2c776450 sp 0x 7fff2c7764485:read of size 8 at 0x60300000efe8 thread T06: #0 0x482119 in main/home/cobbliu/test/core.c:357: #1 0X36A101ECDC in __libc_start_main (/LIB64/LIBC.SO.6+0X36A101ECDC)8: #2 0x481f3c in _start (/HOME/COBBLIU/TEST/CORE+0X481F3C)9:10:0x60300000efe8 is located 8 bytes inside of 24-byte region [0X60300000EFE0,0X60300000EFF8]11:freed by thread T0 here:: #0 0x46bca9 in __interceptor_free/home/ads/build23_6u0_x64/workspace/t-coresystem-clang/label/build23_6u0_x64/ T-coresystem-clang/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64: #1 0x4820c0 in main/home/cobbliu/test/core.c:32: #2 0X36A101ECDC in __libc_start_main (/LIB64/LIBC.SO.6+0X36A101ECDC)15:16:previously allocated by thread T0 here:: #0 0x46be29 in malloc/home/ads/build23_6u0_x64/workspace/t-coresystem-clang/label/build23_6u0_x64/ t-coresystem-clang/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74: #1 0x48202a in Main/home/cobbliu/test/core.c:18: #2 0X36A101ECDC in __libc_start_main (/LIB64/LIBC.SO.6+0X36A101ECDC)20:21:summary:addresssanitizer:heap-use-after-free/home/cobbliu/test/core.c:35 Main22:shadow bytes around the buggy address:23:0x0c067fff9da0:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa24:0x0c067fff9db0:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa25:0x0c067fff9dc0:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa26:0x0c067fff9dd0:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa27:0x0c067fff9de0:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa£ º =>0x0c067fff9df0:fa FA fa fa fa fa fa fa fa °f fa fa fa fa fd[fd]fd FA29:0x0c067fff9e00:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa30:0x0c067fff9e10:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa31:0x0c067fff9e20:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa32:0x0c067fff9e30:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa33:0x0c067fff9e40:fa fa fa °f fa fa fa fa fa °f fa fa fa fa fa °f fa fa34:shadow byte legend (one Shadow byte represents 8 application bytes): 35:add Ressable:0036:partially addressable:01 Geneva 0737:heap left RedZone : Fa38:heap right Redzone:fb39:freed Heap region:fd 40:stack left Redzone:f141:stack mid redzone:f242:stack right Redzone:f343:stack partial redzone:f444:stack after Return:f5 45: Stack use after Scope:f846:global redzone:f947:global init order:f648:poisoned by User:f749:asan internal:fe 50: ==11254== Aborting
Can see, the program in the hint CORE.C 35th line has a heap-use-after-free error, and in the end there is a summary, the error code location and the corresponding stack information is played out.
5 Example code 2
The above code makes some minor changes, and we look at its detection of the double-free problem
1: /... 2: struct elem *e2 = e; 3: Free (e); 4: Free (E2); 5: /... 6:}
After compiling and running the same method as above, the following information is provided:
1: [[email protected] test]$./core2:10.13: =================================================================4: ==11952==error:addresssanitizer:attempting double-free on 0X60300000EFE0 in thread T0:5: #0 0x46bca9 in __interceptor_free/home/ads/build23_6u0_x64/workspace/t-coresystem-clang/label/build23_6u0_x64/ T-coresystem-clang/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:646: #1 0X4820BD in main/home/cobbliu/test/core.c:347: #2 0X36A101ECDC in __libc_start_main (/LIB64/LIBC.SO.6+0X36A101ECDC)8: #3 0x481f3c in _start (/HOME/COBBLIU/TEST/CORE+0X481F3C)9:10:0x60300000efe0 is located 0 bytes inside of 24-byte region [0X60300000EFE0,0X60300000EFF8]11:freed by thread T0 here:: #0 0x46bca9 in __interceptor_free/home/ads/build23_6u0_x64/workspace/t-coresystem-clang/label/build23_6u0_x64/ T-coresystem-clang/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64: #1 0x4820b0 in main/home/cobbliu/test/core.c:33: #2 0x36a101ecdc in __libc_start_main (/LIB64/LIBC.SO.6+0X36A101ECDC): 16:previously allocated by Thread T0 here:£ º #0 0x46be29 in malloc/home/ads/build23_6u0_x64/workspace/t-coresystem-clang/label/build23_6u0 _x64/t-coresystem-clang/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74: #1 0x482026 in Main/ Home/cobbliu/test/core.c:18: #2 0x36a101ecdc in __libc_start_main (/LIB64/LIBC.SO.6+0X36A101ECDC): 21:summary:addresssanitizer:double-free/home/ads/build23_6u0_x64/workspace/t-coresystem-clang/label/build23_ 6u0_x64/t-coresystem-clang/llvm-3.4/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64 __interceptor_free ==11952==aborting:
can see, addresssanitizer error, said core.c 34 line has a double-free mistake
6 Example code 3
The code above makes some minor changes, commenting out the code that releases E, to see if it detects memory leaks.
1: /... 2: //free (e); 3: /... 4: }
After compiling and running the same method as above, the following information is provided:
1: [[email protected] test]$./core2: 10.100000
As you can see, for memory leaks, Addresssanitizer can't detect it. Clang has a tool called Leaksanitizer, which is designed to detect memory leaks. Until version 3.7, Leaksanitizer was also in the experimental phase.
7 defects of Addresssanitizer
- The Addresssanitizer tool compiles the stack and stack of programs larger than the native program.
- Addresssanitizer does not support static compilation
date:2015-04-16t21:24+0800
Author:cobbliu
ORG version 7.9.3f with Emacs version 24
Validate XHTML 1.0
Troubleshooting tools and methods for memory problems –clang Addresssanitizer