In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
In this issue, the editor will bring you about how to solve the memory leak detection code of C++ program under Linux. The article is rich in content and analyzes and describes for you from a professional point of view. I hope you can get something after reading this article.
There are many methods for program memory leak detection under Linux, and the most commonly used one is to use valgrind tool. But valgrind is equivalent to letting the program run in the virtual machine, which will not only bring a large cost of system resources, but also have a great impact on the running efficiency of the program. For that kind of program that takes up a lot of resources, it is not easy to use if it takes a long time to run to expose the leakage problem.
Linux under the C++ program to achieve a lightweight leak detection code is actually more convenient, the following I give a simple example, and make a simple explanation. Of course, we should still advocate the use of shared pointers, and using shared pointers to automatically manage memory can avoid unnecessary troubles such as memory leaks.
Basic principles:
Use the _ _ malloc_hook and _ _ free_hook functions provided by glibc to monitor whether memory allocation is available. (see glibc's official documentation for details)
Use the backtrace function to obtain the function call stack and record
Using backtrace_symbols to parse the function corresponding to the call stack
Further processing:
Use abi::__cxa_demangle to parse function names into source code style
Use addr2line to parse the corresponding lines of code for the function call stack
For address resolution in the dynamic library (.so), the base address of the dynamic library mapping needs to be found in the / proc//maps file before it can be resolved.
Note:
Use-g-rdynamic in compilation connection parameters
The code implemented in each of the above steps may not reach * *, or even stupid. If there is a better implementation solution, please replace it directly, and you are welcome to give us your advice.
Sample code:
Leakmom.cpp
/ * Prototypes for _ _ malloc_hook, _ free_hook * / # include # include "leakmon.h" CMutexLock gLock; std::map gPtrInfo; std::map gLeakInfo; const int LmCallStack:: MAX_STACK_LAYERS = 32; / * Prototypes for our hooks. * / static void my_init_hook (void); static void* my_malloc_hook (size_t, const void*); static void my_free_hook (void*, const void*); void* (* _ MALLOC_HOOK_VOLATILE old_malloc_hook) (size_t _ size, const void*); void (* _ MALLOC_HOOK_VOLATILE old_free_hook) (void* _ ptr, const void*); / * Override initializing hook from the C library. * / void (* _ MALLOC_HOOK_VOLATILE _ malloc_initialize_hook) (void) = my_init_hook; void my_init_hook (void) {old_malloc_hook = _ _ malloc_hook; old_free_hook = _ _ free_hook; _ _ malloc_hook = my_malloc_hook; _ _ free_hook = my_free_hook;} static void * my_malloc_hook (size_t size, const void * caller) {void * result GLock.lock (); / * Restore all old hooks * / _ malloc_hook = old_malloc_hook; _ _ free_hook = old_free_hook; / * Call recursively * / result = malloc (size); / * Save underlying hooks * / old_malloc_hook = _ _ malloc_hook; old_free_hook = _ _ free_hook; / * printf might call malloc, so protect it too. * / / printf ("malloc (% u) returns% p\ n", (unsigned int) size, result); RecordPtr (result, size); / * Restore our own hooks * / _ _ malloc_hook = my_malloc_hook; _ _ free_hook = my_free_hook; gLock.unlock (); return result;} static void my_free_hook (void * ptr, const void * caller) {gLock.lock () / * Restore all old hooks * / _ malloc_hook = old_malloc_hook; _ _ free_hook = old_free_hook; / * Call recursively * / free (ptr); / * Save underlying hooks * / old_malloc_hook = _ _ malloc_hook; old_free_hook = _ _ free_hook; / * printf might call free, so protect it too. * / / printf ("freed pointer% p\ n", ptr); RemovePtr (ptr); / * Restore our own hooks * / _ _ malloc_hook = my_malloc_hook; _ _ free_hook = my_free_hook; gLock.unlock ();} void RecordPtr (void* ptr, size_t size) {/ / get call stack void* array [LmCallStack:: MAX_STACK_LAYERS] Int cstSize = backtrace (array, LmCallStack:: MAX_STACK_LAYERS); / / Save pointer call stack LmCallStack* callstack = new LmCallStack (array, cstSize); gLock.lock (); std::map:: iterator it = gLeakInfo.find (callstack); if (it! = gLeakInfo. End () {it- > second .size + = size; it- > second .alloc + +; _ PtrInfo pi (it- > first, size); gPtrInfo [ptr] = pi;} else {_ AllocInfo aif (size, 1,0); std::pair ret = gLeakInfo .insert (std::pair (callstack, aif)) If (ret. Second) {_ PtrInfo pi (ret. First- > first, size); gPtrInfo [ptr] = pi;} else {/ / failed}} gLock.unlock ();} void RemovePtr (void* ptr) {gLock.lock (); std::map:: iterator it = gPtrInfo.find (ptr) If (it! = gPtrInfo. End () {std::map:: iterator itc = gLeakInfo. Find (it- > second. CSK); if (itc! = gLeakInfo. End () {itc- > second .size-= it- > second .size; itc- > second .free + +; if (0 = = (itc- > second. Alloc-itc-> second. Free) {assert (0 = = itc-> second. Size); delete itc-> first; gLeakInfo.erase (itc);}} gPtrInfo.erase (it);} gLock.unlock ();} void Report () {char * * strings = NULL; gLock.lock () _ _ malloc_hook = old_malloc_hook; _ _ free_hook = old_free_hook; for (std:: map
< const LmCallStack *, _AllocInfo, __comp>:: iterator it = gLeakInfo .begin (); it! = gLeakInfo .end (); it++) {printf ("\ n") Printf ("= > size:% ld, allocs:% d, frees:% d, a murf:% d\ n", it- > second.size, it- > second.alloc, it- > second.free, it- > second.alloc-it- > second.free); printf ("= = > stacks backtrace:\ n"); strings = backtrace_symbols ((void**) it- > first-> callstack, it- > first-> size) If (strings) {for (int I = 2; I)
< it -> < second->Size) | (first- > size = = second- > size & & memcmp (first- > callstack, second- > callstack, sizeof (void*) * first- > size) < 0);}}; struct _ PtrInfo {_ PtrInfo (const LmCallStack* c=NULL, long slots 0) {csk = c Size=s;} const LmCallStack * csk; long size;}; struct _ AllocInfo {_ AllocInfo (long slots 0, int a = 0, int fission 0) {size=s; alloc=a; free=f;} / / long size; int alloc; int free;} Class CMutexLock {public: CMutexLock (); ~ CMutexLock (); public: void lock (); void unlock (); private: pthread_mutex_t m_mutex;}; / / void RecordPtr (void* ptr, size_t size); void RemovePtr (void* ptr); void Report () The above is the editor for you to share how to solve the Linux C++ program memory leak detection code, if you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.