📄 dmalloc.html
字号:
<P><A NAME="IDX42"></A><A NAME="IDX43"></A><P>Any program can be divided into 2 logical parts: text and data. Text isthe actual program code in machine-readable format and data is theinformation that the text operates on when it is executing. The data,in turn, can be divided into 3 logical parts according to where it isstored: <EM>static</EM>, <EM>stack</EM>, and <EM>heap</EM>.<P><A NAME="IDX44"></A><P>Static data is the information whose storage space is compiled into theprogram.<PRE>/* global variables are allocated as static data */int numbers[10];main(){ ...}</PRE><P><A NAME="IDX45"></A><P>Stack data is data allocated at runtime to hold information used insideof functions. This data is managed by the system in the space calledstack space.<PRE>void foo(){ /* this local variable is stored on the stack */ float total; ...}main(){ foo();}</PRE><P><A NAME="IDX46"></A><P>Heap data is also allocated at runtime and provides a programmer withdynamic memory capabilities.<PRE>main(){ /* the address is stored on the stack */ char * string; ... /* * Allocate a string of 10 bytes on the heap. Store the * address in string which is on the stack. */ string = (char *)malloc(10); ... /* de-allocate the heap memory now that we're done with it */ (void)free(string); ...}</PRE><P>It is the heap data that is managed by this library.<P>Although the above is an example of how to use the malloc and freecommands, it is not a good example of why using the heap for runtimestorage is useful.<P>Consider this: You write a program that reads a file into memory,processes it, and displays results. You would like to handle files witharbitrary size (from 10 bytes to 1.2 megabytes and more). One problem,however, is that the entire file must be in memory at one time to do thecalculations. You don't want to have to allocate 1.2 megabytes when youmight only be reading in a 10 byte file because it is wasteful of systemresources. Also, you are worried that your program might have to handlefiles of more than 1.2 megabytes.<P>A solution: first check out the file's size and then, using theheap-allocation routines, get enough storage to read the entire fileinto memory. The program will only be using the system resourcesnecessary for the job and you will be guaranteed that your program canhandle any sized file.<H3><A NAME="SEC7" HREF="dmalloc.html#TOC7">2.3.2 Functionality Supported by All Malloc Libraries</A></H3><P><A NAME="IDX47"></A><P>All malloc libraries support 4 basic memory allocation commands. Theseinclude <EM>malloc</EM>, <EM>calloc</EM>, <EM>realloc</EM>, and <EM>free</EM>. Formore information about their capabilities, check your system's manualpages -- in unix, do a <CODE>man 3 malloc</CODE>.<P><DL><DT><U>Function:</U> <B></B><DD><A NAME="IDX48"></A>void *malloc ( unsigned int <VAR>size</VAR> )<A NAME="IDX49"></A><P>Usage: <CODE>pnt = (type *)malloc(size)</CODE><P>The malloc routine is the basic memory allocation routine. It allocatesan area of <CODE>size</CODE> bytes. It will return a pointer to the spacerequested.</DL><P><DL><DT><U>Function:</U> <B></B><DD><A NAME="IDX50"></A>void *calloc ( unsigned int <VAR>number</VAR>, unsigned int<VAR>size</VAR> )<A NAME="IDX51"></A><A NAME="IDX52"></A><A NAME="IDX53"></A><P>Usage: <CODE>pnt = (type *)calloc(number, size)</CODE><P>The calloc routine allocates a certain <CODE>number</CODE> of items, each of<CODE>size</CODE> bytes, and returns a pointer to the space. It isappropriate to pass in a <CODE>sizeof(type)</CODE> value as the size argument.<P>Also, calloc nulls the space that it returns, assuring that the memoryis all zeros.</DL><P><DL><DT><U>Function:</U> <B></B><DD><A NAME="IDX54"></A>void *realloc ( void *<VAR>old_pnt</VAR>, unsigned int<VAR>new_size</VAR> )<A NAME="IDX55"></A><P>Usage: <CODE>new_pnt = (type *)realloc(old_pnt, new_size)</CODE><P>The realloc function expands or shrinks the memory allocation in<CODE>old_pnt</CODE> to <CODE>new_size</CODE> number of bytes. Realloc copies asmuch of the information from <CODE>old_pnt</CODE> as it can into the<CODE>new_pnt</CODE> space it returns, up to <CODE>new_size</CODE> bytes. If thereis a problem allocating this memory, 0L will be returned.<P>If the <CODE>old_pnt</CODE> is 0L then realloc will do the equivalent of a<CODE>malloc(new_size)</CODE>. If <CODE>new_size</CODE> is 0 and <CODE>old_pnt</CODE> isnot 0L, then it will do the equivalent of <CODE>free(old_pnt)</CODE> and willreturn 0L.</DL><P><DL><DT><U>Function:</U> <B></B><DD><A NAME="IDX56"></A>void free ( void *<VAR>pnt</VAR> )<A NAME="IDX57"></A><P>Usage: <CODE>free(pnt)</CODE><P>The free routine releases allocation in <CODE>pnt</CODE> which was returned bymalloc, calloc, or realloc back to the heap. This allows other parts ofthe program to re-use memory that is not needed anymore. It guaranteesthat the process does not grow too big and swallow a large portion ofthe system resources.</DL><P><EM>WARNING</EM>: there is a quite common myth that all of the space thatis returned by malloc libraries has already been cleared. <EM>Only</EM>the <CODE>calloc</CODE> routine will zero the memory space it returns.<H2><A NAME="SEC8" HREF="dmalloc.html#TOC8">2.4 General Features of the Library</A></H2><P><A NAME="IDX58"></A><P>The debugging features that are available in this debug malloc librarycan be divided into a couple basic classifications:<DL COMPACT><DT>file and line number information<DD><A NAME="IDX59"></A><A NAME="IDX60"></A>One of the nice things about a good debugger is its ability to providethe file and line number of an offending piece of code. This libraryattempts to give this functionality with the help of <EM>cpp</EM>, the Cpreprocessor. See section <A HREF="dmalloc.html#SEC11">3.1 Macros Providing File and Line Information</A>.<DT>return-address information<DD><A NAME="IDX61"></A>To debug calls to the library from external sources (i.e. those filesthat could not use the allocation macros), some facilities have beenprovided to supply the caller's address. This address, with the help ofa debugger, can help you locate the source of a problem. See section <A HREF="dmalloc.html#SEC12">3.2 Getting Caller Address Information</A>.<DT>fence-post (i.e. bounds) checking<DD><A NAME="IDX62"></A><A NAME="IDX63"></A><A NAME="IDX64"></A><EM>Fence-post</EM> memory is the area immediately above or below memoryallocations. It is all too easy to write code that accesses above orbelow an allocation -- especially when dealing with arrays or strings.The library can write special values in the areas around everyallocation so it will notice when these areas have been overwritten.See section <A HREF="dmalloc.html#SEC21">3.8.3 Diagnosing Fence-Post Overwritten Memory</A>.<EM>NOTE</EM>: The library cannot notice when the program <EM>reads</EM>from these areas, only when it writes values. Also, fence-post checkingwill increase the amount of memory the program allocates.<DT>heap-constancy verification<DD><A NAME="IDX65"></A>The administration of the library is reasonably complex. If any of theheap-maintenance information is corrupted, the program will either crashor give unpredictable results.By enabling heap-consistency checking, the library will run through itsadministrative structures to make sure all is in order. This will meanthat problems will be caught faster and diagnosed better.The drawback of this is, of course, that the library often takes quite along time to do this. It is suitable to enable this only duringdevelopment and debugging sessions.<EM>NOTE</EM>: the heap checking routines cannot guarantee that the testswill not cause a segmentation-fault if the heap administrationstructures are properly (or improperly if you will) overwritten. Inother words, the tests will verify that everything is okay but may notinform the user of problems in a graceful manner.<DT>logging statistics<DD><A NAME="IDX66"></A><A NAME="IDX67"></A><A NAME="IDX68"></A><A NAME="IDX69"></A>One of the reasons why the debug malloc library was initially developedwas to track programs' memory usage -- specifically to locate<EM>memory leaks</EM> which are places where allocated memory is nevergetting freed. See section <A HREF="dmalloc.html#SEC20">3.8.2 Tracking Down Non-Freed Memory</A>.The library has a number of logging capabilities that can track un-freedmemory pointers as well as runtime memory usage, memory transactions,administrative actions, and final statistics.<DT>examining freed memory<DD><A NAME="IDX70"></A><A NAME="IDX71"></A>Another common problem happens when a program frees a memory pointer butgoes on to use it again by mistake. This can lead to mysterious crashesand unexplained problems.To combat this, the library can write special values into a block ofmemory after it has been freed. This serves two purposes: it will makesure that the program will get garbage data if it trying to access thearea again, and it will allow the library to verify the area later forsigns of overwriting.</DL><P>If any of the above debugging features detect an error, the library willtry to recover. If logging is enabled then an error will be logged withas much information as possible.<P>The error messages that the library displays are designed to give themost information for developers. If the error message is notunderstood, then it is most likely just trying to indicate that a partof the heap has been corrupted.<P><A NAME="IDX72"></A><A NAME="IDX73"></A>The library can be configured to quit immediately when an error isdetected and to dump a core file or memory-image. This can be examinedwith a debugger to determine the source of the problem. The library caneither stop after dumping core or continue running.<P><A NAME="IDX74"></A><A NAME="IDX75"></A><EM>NOTE</EM>: do not be surprised if the library catches problems withyour system's routines. It took me hours to finally come to theconclusion that the localtime call, included in SunOS release 4.1,overwrites one of its fence-post markers.<H2><A NAME="SEC9" HREF="dmalloc.html#TOC9">2.5 How the Library Checks Your Program</A></H2><P>This is one of the newer sections of the library implying that it isincomplete. If you have any questions or issues that you'd like to seehandled here, please let me know.<P>The dmalloc library replaces the heap library calls normally found inyour system libraries with its own versions. When you make a call tomalloc (for example), you are calling dmalloc's version of the memoryallocation function. When you allocate memory with these functions, thedmalloc library keeps track of a number of pieces of debugginginformation about your pointer including: where it was allocated,exactly how much memory was requested, when the call was made, etc..This information can then be verified when the pointer is freed orreallocated and the details can be logged on any errors.<P>Whenever you reallocate or free a memory address, the dmalloc libraryalways performs a number of checks on the pointer to make sure that itis valid and has not been corrupted. You can configure the library toperform additional checks such as detected fence-post writing. Thelibrary can also be configured to overwrite memory with non-zeros (onlyif calloc is not called) when it is allocated and erase the memory whenthe pointers are freed.<P><A NAME="IDX76"></A>In addition to per-pointer checks, you can configure the library toperform complete heap checks. These complete checks verify all internalheap structures and include walking all of the known allocated pointersto verify each one in turn. You need this level of checking to findrandom pointers in your program which got corrupted but that won't befreed for a while. To turn on these checks, you will need to enable the'check-heap' debug token. See section <A HREF="dmalloc.html#SEC30">4.4 Description of the Debugging Tokens</A>. By default this willcause the heap to be fully checked each and every time dmalloc is calledwhether it is a malloc, free, realloc, or another dmalloc overloadedfunction.<P>Performing a full heap check can take a good bit of CPU and it may bethat you will want to run it sporadically. This can be accomplished ina couple different ways including the '-i' interval argument to thedmalloc utility. See section <A HREF="dmalloc.html#SEC26">4. Dmalloc Utility Program</A>. This will cause the check tobe run every N-th time. For instance, 'dmalloc -i 3' will cause theheap to be checked before every 3rd call to a memory function. Valuesof 100 or even 1000 for high memory usage programs are more useful thansmaller ones.<P><A NAME="IDX77"></A>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -