📄 mpatrol.texi
字号:
You should be able to link in the mpatrol library when linking your programwithout having to recompile any of your object files or libraries, but this willonly be worthwhile on systems where stack tracebacks are supported, otherwiseyou should proceed to the next step since there will not be enough informationfor you to tell where the calls to dynamic memory allocation functions tookplace.Information on how to link the mpatrol library to an application is given at thestart of the examples (@pxref{Examples}), but you should note that if yourprogram does not directly call any of the functions in the mpatrol library thenit will not be linked in and you will not see a log file being generated whenyou run it. You can force the linking of the mpatrol library by causing@code{malloc()} to be undefined on the link line, usually through the use of the@option{-u} linker option.If your program is multithreaded then you must use the thread-safe version ofthe mpatrol library and possibly also link in the system threads library aswell. Not doing this will usually result in your program failing somewhere inthe mpatrol library code.@itemAll of the following steps will require you to recompile some or all of yourcode so that your code calls dynamic memory allocation functions from thempatrol library rather than the system C library.This first step is only available when using @command{gcc}.You can make use of the @command{gcc} option @option{-fcheck-memory-usage} whichinstructs the compiler to place calls to error-checking functions before eachaccess to memory. This can result in a dramatic slowdown of your code so youmay wish to limit the use of this option to a few source files, but it doesprovide a very thorough method of ensuring that you do not access memory beyondthe bounds of a memory allocation or attempt to access free memory. However,be aware that the checks are only placed in the bodies of functions that havebeen compiled with this option and are missing from all functions that have not.You must link in the mpatrol library when using this option, otherwise you willget linker errors.The @option{-fcheck-memory-usage} option was added to @command{gcc} to supportGNU Checker, which can be considered to be the run-time system for this option.GNU Checker also includes the ability to detect reads from uninitialised memory,something that mpatrol does not currently support, and deals with stack objectsas well. GNU Checker cannot be used in conjunction with mpatrol.@itemFor this step, if you have a rough idea of where the function calls lie that youwould like to trace or test, you need only recompile the relevant source files.You should modify these source files to include the @file{mpatrol.h} header filebefore any calls to dynamic memory allocation or memory operation functions.However, you should take particular care to ensure that all calls to memoryallocation functions in the mpatrol library will be matched by calls to memoryreallocation or deallocation functions in the mpatrol library, since if they areunmatched then the log file will either fill up with errors complaining abouttrying to free unknown allocations, or warnings about unfreed memory allocationsat the end of execution.@itemThis step requires you to recompile all of your source files to include the@file{mpatrol.h} header file. Obviously, this will take the longest amount oftime to integrate, but need not require you to change any source files if thecompiler you are using has a command line option to include a specific headerfile before any source files.For example, @command{gcc} comes with a @option{-include} option which has thisfeature, so if you had to recompile a source file called @file{test.c} then thefollowing command would allow you to include @file{mpatrol.h} without havingto modify the source file:@smallexamplegcc -include /usr/local/include/mpatrol.h -c test.c@end smallexample@end enumerateIn all cases, it will be desirable to compile your source files withcompiler-generated debugging information since that may be able to be used bythe @option{USEDEBUG} option or the @command{mpsym} command. In addition, moresymbolic information will be available if the executable files have not hadtheir symbol tables stripped from them, although mpatrol can also fall back tousing the dynamic symbol table from dynamically linked executable files.@cindex AM_WITH_MPATROLNote that an automake macro is now provided to allow you to integrate mpatrolinto a new or existing project that uses the GNU autoconf and automake tools.It is located in @file{extra/mpatrol.m4}, which should be copied to thedirectory containing all of the local autoconf and automake macros on yoursystem, usually @file{/usr/local/share/aclocal}. The automake macro it definesis called @code{AM_WITH_MPATROL}, which should be added to the libraries sectionin the @file{configure.in} file for your project. It takes one optionalparameter specifying whether mpatrol should be included in the project(@samp{yes}) or not (@samp{no}). This can also be specified as @samp{threads}if you wish to use the threadsafe version of the mpatrol library. You canoverride the value of the optional parameter with the @option{--with-mpatrol}option to the resulting @file{configure} shell script.@cindex HAVE_MPATROL@cindex HAVE_MPALLOC@cindex mpdebug.hIf you are using the @code{AM_WITH_MPATROL} automake macro then you may wish touse the @file{mpdebug.h} header file instead of @file{mpatrol.h}. This ensuresthat the @code{MP_MALLOC()} family of functions are always defined, even iflibmpatrol or libmpalloc are unavailable. It makes use of the@code{HAVE_MPATROL} and @code{HAVE_MPALLOC} preprocessor macros that arecontrolled by the automake macro, but in other respects behaves in exactly thesame way as @file{mpatrol.h}.@node Removing mpatrol, , Adding mpatrol, Integration@section Removing mpatrol@cindex removing mpatrolOnce you have ironed out all of the problems in your code with the help of thempatrol library, there will come a time where you wish to build your programwithout any of its debugging features, either to improve the speed that it runsat, or perhaps even for a release. Choose one of the following steps to helpyou remove the mpatrol library from your program (you only need to perform themif you linked your program with the mpatrol library).@enumerate 1@itemThe quickest way to remove the mpatrol library from your application is tolink with libmpalloc instead of libmpatrol. This contains replacements for allof the mpatrol library functions, either implementing memory allocation ormemory operation functions with the system C library, or doing nothing in thefunctions which perform debugging, profiling or tracing. This method is a veryquick way to remove the mpatrol library but will not result in very efficientcode.@itemThe next option is to recompile all of the source files which include the@file{mpatrol.h} header file, but this time define the @code{NDEBUG}preprocessor macro. This automatically disables the redefinition of@code{malloc()}, etc.@: and prevents calls being made to any mpatrol libraryfunctions. Obviously, this option is the most time-consuming of the two, butwill result in the complete removal of all references to the mpatrol library.@itemThe final option is to guard all of the mpatrol-specific code in your programwith a preprocessor macro, possibly called @code{HAVE_MPATROL}, and thenrecompiling all of your source code with this macro undefined. This is the bestoption but relies on you having originally made these changes when you firststarted integrating the mpatrol library into your program.@end enumerateNote that if you used the @code{AM_WITH_MPATROL} automake macro as detailed inthe previous section to build your application then you should perform a cleanrecompilation using the @option{--without-mpatrol} option to the@file{configure} shell script in order to completely remove the mpatrol library.Note also that if you used the @option{-fcheck-memory-usage} option of the GNUcompiler to check all memory accesses then you must recompile without thatoption in order for your program to run at a reasonable speed.@node Memory allocations, Operating system support, Integration, Top@chapter Memory allocations@cindex memory allocations@cindex C@cindex C++@cindex Pascal@cindex BASIC@cindex FORTRANIn the C and C++ programming languages there are generally three different typesof memory allocation that can be used to hold the contents of variables. Otherprogramming languages such as Pascal, BASIC and FORTRAN also support some ofthese types of allocation, although their implementations may be slightlydifferent.@menu* Static memory allocations:: Fixed location, fixed size.* Stack memory allocations:: Variable location, fixed size.* Dynamic memory allocations:: Variable location, variable size.@end menu@node Static memory allocations, Stack memory allocations, , Memory allocations@section Static memory allocations@cindex static memory allocations@cindex memory allocations, static@cindex file scope variables@cindex variables, file scope@cindex local static variables@cindex variables, local staticThe first type of memory allocation is known as a @emph{static memoryallocation}, which corresponds to file scope variables and local staticvariables. The addresses and sizes of these allocations are fixed at the timeof compilation@footnote{Or more accurately, at link time.} and so they can beplaced in a fixed-sized data area which then corresponds to a section within thefinal linked executable file. Such memory allocations are called static becausethey do not vary in location or size during the lifetime of the program.@cindex data sections@cindex sections@cindex BSSThere can be many types of data sections within an executable file; the threemost common are normal data, BSS data and read-only data. BSS data containsvariables and arrays which are to be initialised to zero at run-time and so istreated as a special case, since the actual contents of the section need not bestored in the executable file. Read-only data consists of constant variablesand arrays whose contents are guaranteed not to change when a program is beingrun. For example, on a typical SVR4 UNIX system the following variabledefinitions would result in them being placed in the following sections:@smallexampleint a; /* BSS data */int b = 1; /* normal data */const int c = 2; /* read-only data */@end smallexample@cindex tentative declarations@cindex declarations, tentative@cindex common variablesIn C the first example would be considered a @emph{tentative} declaration, andif there was no subsequent definition of that variable in the currenttranslation unit then it would become a @emph{common} variable in the resultingobject file. When the object file gets linked with other object files, anycommon variables with the same name become one variable, or take theirdefinition from a non-tentative definition of that variable. In the formercase, the variable is placed in the BSS section. Note that C++ has no supportfor tentative declarations.As all static memory allocations have sizes and address offsets that are knownat compile-time and are explicitly initialised, there is very little that can gowrong with them. Data can be read or written past the end of such variables,but that is a common problem with all memory allocations and is generally easyto locate in that case. On systems that separate read-only data from normaldata, writing to a read-only variable can be quickly diagnosed at run-time.@node Stack memory allocations, Dynamic memory allocations, Static memory allocations, Memory allocations@section Stack memory allocations@cindex stack memory allocations@cindex memory allocations, stack@cindex parameter variables@cindex variables, parameter@cindex call-by-value@cindex non-static local variables@cindex variables, non-static localThe second type of memory allocation is known as a @emph{stack memoryallocation}, which corresponds to non-static local variables and call-by-valueparameter variables. The sizes of these allocations are fixed at the time ofcompilation but their addresses will vary depending on when the function whichdefines them is called. Their contents are not immediately initialised, andmust be explicitly initialised by the programmer upon entry to the function orwhen they become visible in scope.@cindex stack@cindex registersSuch memory allocations are placed in a system memory area called the@emph{stack}, which is allocated per process@footnote{Or per thread on somesystems.} and generally grows down in memory. When a function is called, thestate of the calling function must be preserved so that when the called functionreturns, the calling function can resume execution. That state is stored on thestack, including all local variables and parameters. The compiler generatescode to increase the size of the stack upon entry to a function, and decreasethe size of the stack upon exit from a function, as well as saving and restoringthe values of registers.There are a few common problems using stack memory allocations, and mostgenerally involve uninitialised variables, which a good compiler can usuallydiagnose at compile-time. Some compilers also have options to initialise alllocal variables with a bit pattern so that uninitialised stack variables willcause program faults at run-time. As with static memory allocations, there canbe problems with reading or writing past the end of stack variables, but astheir sizes are fixed these can usually easily be located.@node Dynamic memory allocations, , Stack memory allocations, Memory allocations@section Dynamic memory allocations@cindex dynamic memory allocations@cindex memory allocations, dynamicThe last type of memory allocation is known as a @emph{dynamic memoryallocation}, which corresponds to memory allocated via @code{malloc()} or@code{operator new[]}. The sizes, addresses and contents of such memory varyat run-time and so can cause a lot of problems when trying to diagnose a faultin a program. These memory allocations are called dynamic memory allocationsbecause their location and size can vary throughout the lifetime of a program.@cindex heap@cindex garbage collector@cindex MLSuch memory allocations are placed in a system memory area called the@emph{heap}, which is allocated per process on some systems, but on others maybe allocated directly from the system in scattered blocks. Unlike memoryallocated on the stack, memory allocated on the heap is not freed when afunction or scope is exited and so must be explicitly freed by the programmer.The pattern of allocations and deallocations is not guaranteed to be (and is notreally expected to be) linear and so the functions that allocate memory from theheap must be able
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -