Implementation of a dynamic memory management module

Source: Internet
Author: User

Summary: This article introduces a dynamic memory management module that can effectively detect errors such as memory leaks and write memory out-of-bounds in C Programs. It is suitable for various platforms with standard C language development environments.

Keywords: C language Dynamic Memory leakage write out of bounds

Introduction
Currently, most software on the embedded platform is written in C language. In addition to concise code and efficient operation, the flexible memory operation capability is also an important feature of the C language. However, improper memory operations are often one of the root causes of errors. For example, "Memory leakage"-failure to correctly release allocated dynamic memory is a memory error that is very difficult to detect. The continuous memory leakage will make the program performance fall to the end of completely unable to run, and thus affect all other programs with dynamic memory requirements, some relatively simple embedded platforms may even impede the operation of the operating system. Another example is "writing memory out of bounds". An illegal write memory operation is very likely to damage other data being used in this program, in severe cases, it may also affect other running programs or even the entire system. To this end, this article introduces an enhanced and customizable dynamic memory management module (fense), which is based on the memory allocation function provided by C language; it can record the memory leakage information during software operation, and also has the ability to monitor memory operations. It can be found that most of dynamic memory write errors out of bounds.

1. fense Design Principle

Fense creates a bidirectional linked list (struct head * sthead) to store information about all allocated dynamic memory blocks. Each node in the linked list corresponds to a dynamic memory block. The node contains the memory size, the source file name and row number when the allocation occurs, and the fense is deleted from st_head, check the nodes in st_head to obtain the value checksum of the node that has not been released. Fense inserts each allocated dynamic memory block into the st_head of the linked list. The node Structure of the linked list is defined as follows:

Code: struct head {

Char file;/Name of the source file to which the file belongs */

Unsigned long line;/* the row number of the allocation */

Size_t size;/* memory size allocated */

Int checksum;/* checksum of linked list nodes */

Struct head Prev, next;/* pointer to the front and back nodes of the double-stranded table */

};


/* Global Two-way linked list */

Struct head * st_head = NULL;

To detect write out-of-bounds errors, fense adds a certain size of memory before and after the memory applied by the user as the monitoring area and initializes it to a predetermined value. In this way, when the program has an out-of-bounds write operation, the predetermined value will change and fense will detect the error.

The dynamic memory structure 1 allocated by fense is shown in. From this we can see that the pointer PTR returned to the user by fense_malloc (fense memory allocation function) points to the starting position of the user's applied memory region. The linked list node and the Front/back monitoring area are used internally by fense and are invisible to users.

2. Custom options

Fense provides five macro definitions for you to customize functions. The meaning of Option Control for each group is as follows:

Warn_on_zero_malloc warning information when the user applies for zero-space allocation.

Memory block initialized during fill_on_malloc allocation

Fill_on_malloc_val: Specifies the default value for initialization.

Fill the memory block when fill_on_free is released

The default value of filling the memory block when fill_on_free_val is released

The main function of the above four options is to initialize the allocated memory and the released memory as the default value, to avoid errors caused by the use of the memory that has not been initially passed.

Fense_front_size defines the size of the pre-Monitoring Area

Fense_front_val defines the default value of the pre-Monitoring Area

Fense_end_size: the size of the monitored area after Definition

Fense_end_val: pre-defined monitoring of the job field

During fense operation, the test of out-of-bounds memory write operations is determined by comparing the current value of the monitoring region with the preset value of the monitoring region. Obviously, it cannot be ruled out that the write value of the out-of-bounds write operation that occurs in the monitoring region is exactly the same as the preset value in the monitoring region. In this case, fense cannot detect errors. In this case, you can perform multiple tests by changing the default values of the monitoring region (fense_front_val and fense_end_val) and the monitoring region size (fense_front_size and fense_end_size, in this way, the monitoring accuracy can be greatly improved.

Validate_free

Free checks whether the memory block is in the linked list.

Check_all_memory_on_free

When free, check all memory blocks in the linked list.

There is a situation where an out-of-bounds error occurs in the write operation on memory block A and is written to the area of another memory block B. In this case, you cannot find the problem by checking the validity of memory block A. If you check all dynamic memory blocks at the same time, you may find the error. The preceding options are used for this purpose.

Fense_lock obtains the operation permission for the st_head linked list.

Fense_unlock releases the operation permission on the linked list st_head.

In a multi-threaded environment, multiple threads may use fense for memory management at the same time, while the st_head linked list used by fense is a global variable, therefore, the above two macros are provided to achieve mutually exclusive access to st_head. The specific definition of macros depends on the software environment where the user is located. You can implement the macros on your own. For a single-threaded system, you only need to define the two macros as null.

For ease of use, the fense header file also includes the following definitions, so that you can introduce fense without modifying the existing source code.

Code: # define malloc (size) fense_malloc (size, _ file _, _ line _)

# Define free (PTR) fense_free (PTR, _ file _, _ line _)

# Define realloc (PTR, new_size) fense_realloc (PTR, new_size, _ file _, _ line _)

# Define colloc (Num, size) fense_calloc (Num, size, _ file _, _ line _)


3. runtime Control

The fense memory monitoring function can be dynamically switched during operation. This function is implemented by assigning the global variable st_disbaled to zero or non-zero values. During the debugging process, you can modify the st_disabled value in the debugger to control fense behavior, eliminating the need to recompile the source code. This is advantageous for software projects that require a large amount of Compilation Time for large-scale engineering or cross-platform development.

4 fense implementation

Fense provides memory management functions such as fense_malloc, fense_free, fense_realloc, and fense_calloc. The functions and calling formats are consistent with those of malloc, free, realloc, and calloc in C. Limited length. Here we will only briefly describe the implementation process of fense_malloc and fense_free.

Code:/* Memory Allocation Function */

Void * fense_malloc (size_t size, char * file, unsigned long line)

{

// Check the fense runtime switch. If fense is disabled, malloc is called.

// Allocate and return

// Check whether there is zero allocation. If yes, 0 is returned after the warning message is displayed (custom options)

// Allocate memory, including the linked list node area and the Front/back monitoring area

// Initialize the linked list node and save the allocated memory information, including the allocated size, file name, and row number.

// Insert this node into the linked list st_head

// Calculate the checksum for this node region

// Use the preset value to initialize the monitoring area before/after initialization.

// Fill the user memory area with the preset value (custom options)

// Return the starting position of the user's memory area

}

/* Memory release function */

Void fense_free (void * uptr, char * file, unsigned long line)

{

// Check the fense runtime switch. If fense is disabled, free translation is called and return

// Check the dynamic memory under all fense Management (custom options)

// Determine whether the current memory block is in the st_head linked list. If not, a prompt is displayed.

// Exit the alert information (custom options)

// Check whether the current memory block has out-of-bounds operations

// Delete the linked list node of the current memory block from st_head

// Re-calculate the checksum of the adjacent nodes before and after the current node

// Fill the released memory area with the preset value (custom options)

// Call free to release the current memory block

}


Conclusion

As a code module that monitors memory errors when running C Programs, fense can detect almost all memory leaks and most out-of-bounds operations, it also records the information required to correct program errors as much as possible, effectively reduces the debugging time of program designers, and achieves good results in actual embedded product development.

Previous Article: Development of drivers for PCI devices in Linux-Implementation of PCI drivers (III)
Next article: Using I/O commands to access the configuration space of PCI bus devices

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.