1 Background:
The x86 platform has comprehensive user-mode memory detection tools such as valgrind. It can monitor detailed memory information during the running of the program to precisely locate memory problems. However, with the rapid emergence of new platforms, such as the TilePro64 CPU of Tilera, these tools cannot be transplanted in a timely manner. As a result, the new platform lacks the appropriate means to locate memory errors, such as memory out-of-bounds, instead, you can only use coarse-grained top and free commands to observe the total amount of dynamic memory of a process. The disadvantage is that the granularity is too coarse, and there are many reasons for the change in the total memory size. In a complicated system, it is difficult to precisely locate the root cause of memory problems, or even report errors, this seriously affects the development and testing efficiency of new platforms such as Tilera. To solve this problem, we propose a general new platform for c/c ++ memory error detection framework.
This framework can be applied to any platform. By Rewriting the memory allocation and release functions of the standard library, such as malloc, new, new [], free, delete, and delete ), and maintain a global memory allocation map data structure. The memory allocation after rewriting, for example, my_malloc, first calls the system malloc function, and then records the memory operation information including the file name, row number, memory size, and function call stack during each malloc execution ), use the pointer value as the key value and store it in the maintained Global map Table. The rewritten my_free is to find and delete the corresponding data items based on the passed pointer value in the map, and then call the system free to release the memory block pointed to by the pointer. In this way, when the program exits, the remaining data items in the map are the memory leakage information we expect to detect. We can output detailed logs that leak memory blocks, such as file names and row numbers. This will greatly improve the efficiency of memory issue tracing similar to the Tilera platform, and improve the speed and quality of development and testing.
2. Basic Principles:
1) rewrite the non-shared memory allocation and release functions malloc, new, new [], free, delete, and delete [] to intercept the memory operation information during execution. The reload format is as follows:
※Void * malloc (size_t nSize, char * pszFileName, int nLineNum)
※Void * new (size_t nSize, char * pszFileName, int nLineNum)
※Void * operator new [] (size_t nSize, char * pszFileName, int nLineNum)
※Void free (void * ptr)
※Void delete (void * ptr)
※Void operator delete [] (void * ptr)
2) rewrite the shared memory allocation and release function mspace_malloc and mspace_free in the following format:
※Void * my_mspace_malloc (mspace msp, unsigned int Size, char * pszFileName, int nLineNum)
※Void my_mspace_free (mspace msp, void * ptr)
3) We have reloaded malloc, new, new [], mspace_malloc. The parameters include size_t nSize, file name, and row number. Here the file name and row number are malloc, new, new [], the file name and row number of the mspace_malloc operator when called. This information will be output when Memory leakage is detected to help locate the specific location of the leak. For free, delete, delete [], the parameter mspace_free is the pointer address.
3 instances:
Taking My_malloc and My_free as an example, the rewrite function structure is as follows:
650) this. width = 650; "border =" 0 "alt =" "src =" http://www.bkjia.com/uploads/allimg/131228/1GA35Y4-0.jpg "/>
1. in the rewritten my_malloc function version, we will call the original version of malloc and pass in the corresponding size_t parameter. Then, we will record the pointer value returned by the original version of malloc, the file name and row number of the allocation. Here we use the STL map data structure for storage, using the pointer value as the key value, the file name, line number and other information as a struct is the value.
The structure of the My_free rewrite function is as follows:
650) this. width = 650; "border =" 0 "alt =" "src =" http://www.bkjia.com/uploads/allimg/131228/1GA34153-1.jpg "/>
2. When my_free is called, we find the corresponding data item in map based on the passed pointer value and delete it, and then call free to release the memory block pointed to by the pointer. In this way, when the program exits, the remaining data items in the map are the memory leakage information we are trying to detect.
4. Key points:
1) how to obtain the file name and row number of the memory allocation code?
The precompiled macros _ FILE _ and _ LINE __in C are used to expand the two macros into the FILE name and row number at the specified position during compilation.
2) Can I use the macro-defined switch to determine whether to take the common branch or the memory detection branch?
# If defined (MEM_DEBUG)
# Define malloc DEBUG_MALLOC
# Define free DEBUG_FREE
# Endif
3) When to create a map data structure for storing memory data, how to manage it, and when to print Memory leakage information?
Design a class to encapsulate the map and insert/delete operations on it, and then construct a Global Object appMemory for this class), in the Global Object appMemory) create and initialize the data structure in the constructor, and analyze and output the remaining data in the data structure in the constructor. In new, the insert interface of this global object is called to record the pointer, file name, row number, memory block size, and other information into map with the pointer value as the key, in delete, call the erase interface to delete the data items in the map corresponding to the pointer value. At the same time, access to the map requires mutual exclusion, because multiple processes may perform memory operations on the stack at the same time.
4) How to Apply for map for non-shared memory? How do I apply for a map for the shared memory?
Non-shared memory map. For multi-process, there are multiple maps, which can be processed by 3. For shared memory, process A may be applied to process B for release. However, if each process has A map, A false positive will occur when we scan each map, therefore, we need to put the map into the shared memory: we apply for a shared memory area as map, which is shared with various processes. When each process in the program calls shared memory, the detailed information such as the pointer allocated by each process and the row number of the file name are stored in the shared map. When the program ends, scan the shared map to obtain the unreleased information. When we put the map into the shared memory and use the c ++ standard library, we need to implement a shared memory-based allocator by ourselves, replace the default map allocator, and implement the map memory allocation scheme in this allocator. Can also use boost library 1.35 or later), it adds a library called boost: interprocess, refer to the http://blog.cong.co/stl-alloc.html for details
5) how to use this tool?
The Memory Leak Detection Framework provides the libmemck. h interface. The content is as follows:
650) this. width = 650; "border =" 0 "alt =" "src =" http://www.bkjia.com/uploads/allimg/131228/1GA32131-2.jpg "/>
You can use the following code in the tested program:
650) this. width = 650; "border =" 0 "alt =" "src =" http://www.bkjia.com/uploads/allimg/131228/1GA3AU-3.jpg "/>
6) When can I capture signals and generate a leak file?
Defines a global class object. In this class's constructor, the signal function is used to capture SIGINT, SIGABRT, SIGFPE, and SIGTERM signals. When one of these signals is captured, start to scan the map and write the remaining map information to the leak file for display.
7) how to control critical resources?
The map shared by each process in the shared memory needs to be locked for read/write operations between processes. Here we use signal lights.
Maps of non-shared memory processes. locks are also required for insertion and deletion of processes.
8) is malloc used as a function pointer in the program?
Because the prototype malloc (size) is rewritten to my_malloc (size ,__ FILE __,__ LINE _), the compilation fails when the program calls the tool due to inconsistent function types, the solution to this situation is to rewrite malloc (size) to my_malloc_p (size) so that the leaked memory can be reported except for the file name and row number.
This article was first published in: Baidu testing technology space] Baidu]
This article from "Baidu technology blog" blog, please be sure to keep this source http://baidutech.blog.51cto.com/4114344/743278