Source: heli.bokee.com Author: demonstrate Release Date: 21:26:00
Content: Memory
1. Several Basic Concepts: Page, frame, paging, and segment.
Two memory allocation modes are available for processes. One uses exec functions and the other uses programmatically (malloc and other functions ).
Important segment include text segment (storing code and so on, which is generally not changed in the life cycle of the process), Data Segment
(To store data, you can use some functions to adjust the size, but the location of the low end remains unchanged), stack segment (with the use of the stack
But not small ...)
2. Static and automatic memory allocation. The former is for static variables or global variables, which are allocated at the beginning, that is, they exist until the end.
The latter is a temporary variable, such as calling a function. It is worth noting that:
In gnu c, the size of the automatic storage can be an expression that
Varies. In other C implementations, it must be a constant.
3. dynamic memory allocation is not supported by the C language itself, unlike C ++. The basic method is
Void * malloc (size_t size)
The allocated memory is not initialized (calloc will be cleared and clear allocate), so memset can be used.
. After allocation, check whether the returned pointer is null. A block returned by malloc is aligned in most cases.
(This can store any type of data). The address is a multiple of 8 (16 in a 64-bit system ),
In some special cases (page boundary), memalign, posix_memalign, and vlign can be used to return
Alignment (power of 2) memory blocks. The free memory is rarely returned to the operating system.
Use malloc. To adjust the size of malloc blocks, use realloc. Glibc does not allocate Blocks
The power of 2 is rounded up.
4. A memory (larger than a page) allocated at a time will be rounded up to the power of 2 and MMAP will be used.
Related Function mallopt, Which is returned to the operating system if there is free in the allocated function.
5. How to adjust the malloc behavior? Use mallopt to adjust the value of some parameters (malloc. h), such
M_trim_threshold (a threshold value returned to the OS Memory), m_mmap_threshold
(Memory allocation requests greater than this value are called by the MMAP system.
6. The allocated memory comes from the heap and can be used.
Int mcheck (void (* abortfn) (Enum mcheck_status status ))
To check the consistency of the allocated memory, called before malloc.
Enum mcheck_status mprobe (void * pointer)
Checks A specific block of memory. These are all GNU extension. (Mcheck. h)
7. To facilitate debugging, glibc provides users with hooks for functions such as malloc, such as _ malloc_hook.
Corresponding to a function pointer,
Void * function (size_t size, const void * caller)
Among them, caller is the receiver that calls the return value of malloc (the address of a pointer ). There are also _ malloc_initialize_hook
Function pointer, called only once (when dynamic memory is allocated for the first time ). (Malloc. h)
8. Some statistics using malloc (svid extension) can be stored using struct mallinfo,
Callable
Struct mallinfo (void)
.
9. How to detect memory leakage? Glibc provides a function
Void mtrace (void)
And Its Reaction
Void muntrace (void)
At this time, it depends on a file referred to by the Environment Variable malloc_trace and records some information in this file.
Used to detect memory leakage. In essence, the hook mentioned above is installed. These functions are generally used
# Ifdef debugging packages to reduce overhead in non-debug mode. It is said that it is not recommended to read the generated files by yourself,
Use the mtrace Program (Perl script for analysis ). The following is a simple example to illustrate this process.
Source Path:
# Include intmain (INT argc, char * argv []) {int * P, * q; # ifdef debugging mtrace (); # endif P = malloc (sizeof (INT); q = malloc (sizeof (INT); printf ("P = % P \ NQ = % P \ n", P, q); * p = 1; * q = 2; free (p); Return 0 ;}
Q is not released. We set the environment variable and touch the file.
The execution result is as follows:
P = 0x98c0378q = 0x98c0388
The file content is as follows:
= Start @./test30: [0x8048446] + 0x98c0378 0x4 @./test30: [0x8048455] + 0x98c0388 0x4 @./test30: [0x804848f]-0x98c0378
It can be seen that the memory with + indicates malloc and-Indicates release. The following 0x4 indicates the size of the allocated memory.
It can be seen that the normal situation +-the number should be the same. Currently, different numbers indicate that leakage occurs. Next let's take a look at the previous
What is the address?
08048424 :... 8048441: E8 D2 Fe FF call 8048318 8048446: 89 45 F4 mov % eax, 0xfffffff4 (% EBP) 8048449: C7 04 24 04 00 00 00 00 movl {FCKeditor} X4, (% ESP) 8048450: E8 C3 Fe FF call 8048318; 8048455: 89 45 F8 mov % eax, 0xfffffff8 (% EBP) 8048458: 8B 45 F8 mov 0xfffffff8 (% EBP ), % eax 804845b: 89 44 24 08 mov % eax, 0x8 (% ESP) 804845f: 8B 45 F4 mov 0xfffffff4 (% EBP), % eax 8048462: 89 44 24 04 mov % eax, 0x4 (% ESP) 8048466: C7 04 24 54 85 04 08 movl {FCKeditor} x8048554, (% ESP) 804846d: e8 C6 Fe FF call 8048338 8048472: 8B 45 F4 mov 0xfffffff4 (% EBP), % eax 8048475: C7 00 01 00 00 00 movl {FCKeditor} X1, (% eax)
It can be seen that it is the address where the function is called. The following uses the mtrace command line tool for analysis. The basic call method is
Mtrace binary tracefile. When gcc-ddebugging-G is used for compilation, the results will be reported.
The row is not released.
10. What is obstack?
A stack that can be seen as any "object". You can create multiple obstacks, which are similar to a stack.
Related definitions are in obstack. h. An obstack is implemented through a structured struct obstack.
The items in the obstack are stored in the chunk, And the chunk is allocated using a user-defined function (actually a macro ).
Later, some interface functions were put into the obstack. It was really a standard C implementation...
Put the grow object. To create an obstack, you only need to create a structure and then use
Static struct obstack myobstack;
Obstack_init (& myobstack );
Of course, the same can be done for malloc. However, you should first tell the compiler what chunk -.-
# Define obstack_chunk_alloc malloc
# Define obstack_chunk_free free
The size of the allocated Chunk is determined by Macro.
Int obstack_chunk_size (struct obstack * obstack-PTR)
The call method is as follows:
Obstack_chunk_size (obstack_ptr) = new-chunk-size;
If the trunk allocation fails, the function pointer corresponding to obstack_alloc_failed_handler is called.
Let's take a look at how to put something in. The most direct thing is to allocate a place
Void * obstack_alloc (struct obstack * obstack-PTR, int size)
Then manually memcpy... This is troublesome, so there is
Void * obstack_copy (struct obstack * obstack-PTR, void * address, int size)
Reduces the workload and makes strings easier.
Void * obstack_copy0 (struct obstack * obstack-PTR, void * address, int size)
In this way, the last 0x0 will be automatically added. You can call
Void obstack_free (struct obstack * obstack-PTR, void * object)
In this case, all the objects added after this object in the obstack will be released (this is the stack ~) NOTE: If object = NULL
Instead of releasing all the items in the obstack, The obstack itself is restored to the uninitialized state.
Next let's take a look at how to add a grow object, the most basic
Void obstack_blank (struct obstack * obstack-PTR, int size)
Allocate space, but not initialize,
Void obstack_grow (struct obstack * obstack-PTR, void * data, int size)
Make this part of space larger (the size can be negative, that is, it will be smaller, but will not shrink too much @), in order to facilitate the string and other data types
The following series of functions can be used:
Void obstack_grow0 (struct obstack * obstack-PTR, void * data, int size)
Void obstack_1grow (struct obstack * obstack-PTR, char C)
Void obstack_ptr_grow (struct obstack * obstack-PTR, void * Data)
Void obstack_int_grow (struct obstack * obstack-PTR, int data)
Finish the grow.
Void * obstack_finish (struct obstack * obstack-PTR)
Can you test the size of this guy before finish?
Int obstack_object_size (struct obstack * obstack-PTR)
However, in this way, each grow will check whether a new chunk needs to be allocated. Therefore, it is slow.
The corresponding fast grow series functions can be used when the chunk is correct due to the generation of grow, such
Void obstack_1grow_fast (struct obstack * obstack-PTR, char C)
Void obstack_blank_fast (struct obstack * obstack-PTR, int size)
To make it easier to check whether the remaining chunk space is sufficient
Int obstack_room (struct obstack * obstack-PTR)
The following are some other and obstack functions.
Void * obstack_base (struct obstack * obstack-PTR)
Returns the address of the next object (the top of the stack). If a growing object exists, it is the address of the object.
If alignment is required, the macro below sets its mask.
Int obstack_alignment_mask (struct obstack * obstack-PTR)
Set chunk size using a similar method.
11. macro call problems
Obstack may not work properly on the old C compiler, especially for functions that generate redefinition using MACO.
However, it can follow the iso c compiler, but it does not ensure that the parameters will be used for multiple times when macro calls are used, as shown in
Obstack_alloc (get_obstack (), 4 );
Get_obstack () or * obstack_list_ptr ++. However, such parameters in gnu c are not expanded multiple times.
12. Variable Size automatic release type, one is BSD extension, defined in stdlib. H, allocated using alloca
Extends pen2 (char * str1, char * str2, int flags, int mode) {char * name = (char *) alloca (strlen (str1) + strlen (str2) + 1 ); stpcpy (name, str1), str2); Return open (name, flags, mode );}
This advantage is that longjmp () does not have to be manually released. And the memory allocated by alloca is
Unified management does not cause memory fragmentation. However, it may not be supported by the GNU system. If the allocated memory is too large, the program will crash.
In addition, the GCC method can be used:
Int open2 (char * str1, char * str2, int flags, int mode) {char name [strlen (str1) + strlen (str2) + 1]; stpcpy (name, str1), str2); Return open (name, flags, mode );}
The two methods are different. The latter may still allocate memory in the stack. Therefore, when the scope ends, the memory is released.
. The former can be used to loop the body, and the latter cannot.
13. What is the use of BRK () and sbrk () to adjust the high end of data segment?
Int BRK (void * ADDR)
Int sbrk (ptrdiff_t delta)
The origin of the name is that the data segment and stack in the original process are opposite. One is long from top to bottom, and the other is long from bottom to top.
Break-.-B is used to separate them.
14. The root can call some related functions to lock a page, so that it cannot be switched out.
Overhead of re-reading. The related functions are in sys/mmem. h.
Int mlock (const void * ADDR, size_t Len)
Int munlock (const void * ADDR, size_t Len)
Int mlockall (INT flags)
Int munlockall (void)
These are posix.1b standards.