From bd355af04fc1df69d4ebb6733be170b9baf0dfb5 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 14 Dec 1997 22:24:57 +0000 Subject: Update. 1997-12-14 21:33 Ulrich Drepper * version.h (VERSION): Bump to 2.0.91. * db2/makedb.c (process_input): Fix typo in message. * sunrpc/rpcinfo.c (pmapdump): Unify messages. * elf/dynamic-link.h: Pretty print. * elf/rtld.c: Allow multiple preloading of a shared object. * include/limits.h: Prevent multiple inclusion. * malloc/Makefile (headers): Add mcheck.h. (distribute): Remove it here. * malloc/mcheck.h: Pretty print. * malloc/mtrace.c (mallenv): Make `const'. * malloc/mtrace.pl: Don't print table head for memory leaks if there are none. * manual/memory.texi: Update descriptor of malloc hooks. * posix/Makefile (routines): Add waitid. * posix/sys/types.h [__USE_SVID || __USE_POSIX]: Define id_t based on __id_t. * posix/sys/wait.h: Define idtype_t type. Add prototype for waitid. * signal/signal.h: Move definition of sigval_t to . * sysdeps/generic/waitid.c: Stub for waitid. * sysdeps/generic/bits/siginfo.h: Define sigval_t. Arrange to work the __need_siginfo_t defined. * sysdeps/unix/sysv/linux/bits/siginfo: Likewise. * sysdeps/generic/bits/types.h: Define __id_t. Correct definition of __FDMASK. * sysdeps/unix/sysv/linux/alpha/bits/types.h: Likewise. * sysdeps/unix/sysv/linux/bits/types.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/bits/types.h: Likewise. * sysdeps/posix/waitid.c: New file. Provided by Zack Weinberg. * rt/aio_misc.c: Rename __aio_free_req to __aio_free_request. * sysdeps/alpha/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE): Add missing parameters. * sysdeps/generic/dl-sysdep.c: Don't call __libc_init_secure. * sysdeps/generic/enbl-secure.c: Don't define __libc_uid. * sysdeps/unix/sysv/linux/init-first.c: Define __libc_uid. * sysdeps/unix/sysv/linux/sigqueue.c: Make sure __libc_uid is initialized. * sysdeps/i386/dl-machine.h: Little cleanup. * sysdeps/i386/fpu/bits/mathinline.h: Use __signbit* inline functions. (__finite): Mark function as const. Add inline code for __ieee754_atan2. * sysdeps/libm-ieee754/s_cacoshf.c: Add alternate implementation (but don't use it now). * sysdeps/libm-ieee754/s_catan.c: Use __ieee754_atan2 instead of __atan. * sysdeps/libm-ieee754/s_catanf.c: Likewise. * sysdeps/libm-ieee754/s_catanl.c: Likewise. * sysdeps/libm-ieee754/s_catanh.c: Likewise. Correct sign of real part. * sysdeps/libm-ieee754/s_catanhf.c: Likewise. * sysdeps/libm-ieee754/s_catanhl.c: Likewise. * sysdeps/libm-ieee754/s_clog10.c: Use factor to correct __ieee754_atan2 to base 10. * sysdeps/libm-ieee754/s_clog10f.c: Likewise. * sysdeps/libm-ieee754/s_clog10l.c: Likewise. * sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h: Define as old_kernel_sigaction. * sysdeps/unix/sysv/linux/net/if_slip.h: Pretty print. * wctype/Makefile (routines): Add wctype_l. * wctype/wctype.h: Add declaration of __wctype_l. * wctype/wctype_l.c: New file. 1997-12-10 00:38 Ulrich Drepper * locale/C-ctype.c: Correct data for isw* functions. * locale/programs/ld-ctype.c: Write 32bit char classes in correct byte order. * wctype/test_wctype.c: Add test for isw* functions. * wctype/wctype.c: Return value with expected byte order. * sysdeps/generic/_G_config.h: Define _G_HAVE_IO_FILE_OPEN. * sysdeps/unix/sysv/linux/_G_config.h: Likewise. --- manual/memory.texi | 261 +++++++++++++++++++++++++++++++++++++++++++++++++++-- manual/signal.texi | 1 - 2 files changed, 254 insertions(+), 8 deletions(-) (limited to 'manual') diff --git a/manual/memory.texi b/manual/memory.texi index 16dc9aa5e1..a186fd4b8c 100644 --- a/manual/memory.texi +++ b/manual/memory.texi @@ -31,6 +31,7 @@ will be freed automatically. @xref{Variable Size Automatic}. * Dynamic Allocation and C:: How to get different kinds of allocation in C. * Unconstrained Allocation:: The @code{malloc} facility allows fully general dynamic allocation. +* Allocation Debugging:: Finding memory leaks and not freed memory. * Obstacks:: Obstacks are less general than malloc but more efficient and convenient. * Variable Size Automatic:: Allocation of variable-sized blocks @@ -630,8 +631,12 @@ uses whenever it is called. You should define this function to look like @code{malloc}; that is, like: @smallexample -void *@var{function} (size_t @var{size}) +void *@var{function} (size_t @var{size}, void *@var{caller}) @end smallexample + +The value of @var{caller} is the return address found on the stack when +the @code{malloc} function was called. This value allows to trace the +memory consumption of the program. @end defvar @comment malloc.h @@ -642,8 +647,12 @@ uses whenever it is called. You should define this function to look like @code{realloc}; that is, like: @smallexample -void *@var{function} (void *@var{ptr}, size_t @var{size}) +void *@var{function} (void *@var{ptr}, size_t @var{size}, void *@var{caller}) @end smallexample + +The value of @var{caller} is the return address found on the stack when +the @code{realloc} function was called. This value allows to trace the +memory consumption of the program. @end defvar @comment malloc.h @@ -654,8 +663,12 @@ uses whenever it is called. You should define this function to look like @code{free}; that is, like: @smallexample -void @var{function} (void *@var{ptr}) +void @var{function} (void *@var{ptr}, void *@var{caller}) @end smallexample + +The value of @var{caller} is the return address found on the stack when +the @code{free} function was called. This value allows to trace the +memory consumption of the program. @end defvar You must make sure that the function you install as a hook for one of @@ -797,13 +810,13 @@ Tell @code{malloc} to perform occasional consistency checks on dynamically allocated memory, and to call @var{abortfn} when an inconsistency is found. @xref{Heap Consistency Checking}. -@item void *(*__malloc_hook) (size_t @var{size}) +@item void *(*__malloc_hook) (size_t @var{size}, void *@var{caller}) A pointer to a function that @code{malloc} uses whenever it is called. -@item void *(*__realloc_hook) (void *@var{ptr}, size_t @var{size}) +@item void *(*__realloc_hook) (void *@var{ptr}, size_t @var{size}, void *@var{caller}) A pointer to a function that @code{realloc} uses whenever it is called. -@item void (*__free_hook) (void *@var{ptr}) +@item void (*__free_hook) (void *@var{ptr}, void *@var{caller}) A pointer to a function that @code{free} uses whenever it is called. @item struct mallinfo mallinfo (void) @@ -811,6 +824,240 @@ Return information about the current dynamic memory usage. @xref{Statistics of Malloc}. @end table +@node Allocation Debugging +@section Allocation Debugging +@cindex allocation debugging +@cindex malloc debugger + +An complicated task when programming with languages which do not use +garbage collected dynamic memory allocation is to find memory leaks. +Long running programs must assure that dynamically allocated objects are +freed at the end of their lifetime. If this does not happen the system +runs out of memory, sooner or later. + +The @code{malloc} implementation in the GNU C library provides some +simple means to detect sich leaks and provide some information to find +the location. To do this the application must be started in a special +mode which is enabled by an environment variable. There are no speed +penalties if the program is compiled in preparation of the debugging if +the debug mode is not enabled. + +@menu +* Tracing malloc:: How to install the tracing functionality. +* Using the Memory Debugger:: Example programs excerpts. +* Tips for the Memory Debugger:: Some more or less clever ideas. +* Interpreting the traces:: What do all these lines mean? +@end menu + +@node Tracing malloc +@subsection How to install the tracing functionality + +@comment mcheck.h +@comment GNU +@deftypefun void mtrace (void) +When the @code{mtrace} function is called it looks for an environment +variable named @code{MALLOC_TRACE}. This variable is supposed to +contain a valid file name. The user must have write access. If the +file already exists it is truncated. If the environment variable is not +set or it does not name a valid file which can be opened for writing +nothing is done. The behaviour of @code{malloc} etc. is not changed. +For obvious reasons this also happens if the application is install SUID +or SGID. + +If the named file is successfully opened @code{mtrace} installs special +handlers for the functions @code{malloc}, @code{realloc}, and +@code{free} (@pxref{Hooks for Malloc}). From now on all uses of these +functions are traced and protocolled into the file. There is now of +course a speed penalty for all calls to the traced functions so that the +tracing should not be enabled during their normal use. + +This function is a GNU extension and generally not available on other +systems. The prototype can be found in @file{mcheck.h}. +@end deftypefun + +@comment mcheck.h +@comment GNU +@deftypefun void muntrace (void) +The @code{muntrace} function can be called after @code{mtrace} was used +to enable tracing the @code{malloc} calls. If no (succesful) call of +@code{mtrace} was made @code{muntrace} does nothing. + +Otherwise it deinstalls the handlers for @code{malloc}, @code{realloc}, +and @code{free} and then closes the protocol file. No calls are +protocolled anymore and the programs runs again with the full speed. + +This function is a GNU extension and generally not available on other +systems. The prototype can be found in @file{mcheck.h}. +@end deftypefun + +@node Using the Memory Debugger +@subsection Example programs excerpts + +Even though the tracing functionality does not influence the runtime +behaviour of the program it is no wise idea to call @code{mtrace} in all +programs. Just imagine you debug a program using @code{mtrace} and all +other programs used in the debug sessions also trace their @code{malloc} +calls. The output file would be the same for all programs and so is +unusable. Therefore on should call @code{mtrace} only if compiled for +debugging. A program could therefore start like this: + +@example +#include + +int +main (int argc, char *argv[]) +@{ +#ifdef DEBUGGING + mtrace (); +#endif + @dots{} +@} +@end example + +This is all what is needed if you want to trace the calls during the +whole runtime of the program. Alternatively you can stop the tracing at +any time with a call to @code{muntrace}. It is even possible to restart +the tracing again with a new call to @code{mtrace}. But this can course +unreliable results since there are possibly calls of the functions which +are not called. Please note that not only the application uses the +traced functions, also libraries (including the C library itself) use +this function. + +This last point is also why it is no good idea to call @code{muntrace} +before the program terminated. The libraries are informed about the +termination of the program only after the program returns from +@code{main} or calls @code{exit} and so cannot free the memory they use +before this time. + +So the best thing one can do is to call @code{mtrace} as the very first +function in the program and never call @code{muntrace}. So the program +traces almost all uses of the @code{malloc} functions (except those +calls which are executed by constructors of the program or used +libraries). + +@node Tips for the Memory Debugger +@subsection Some more or less clever ideas + +You know the situation. The program is prepared for debugging and in +all debugging sessions it runs well. But once it is started without +debugging the error shows up. In our situation here: the memory leaks +becomes visible only when we just turned off the debugging. If you +foresee such situations you can still win. Simply use something +equivalent to the following little program: + +@example +#include +#include + +static void +enable (int sig) +@{ + mtrace (); + signal (SIGUSR1, enable); +@} + +static void +disable (int sig) +@{ + muntrace (); + signal (SIGUSR2, disable); +@} + +int +main (int argc, char *argv[]) +@{ + @dots{} + + signal (SIGUSR1, enable); + signal (SIGUSR2, disable); + + @dots{} +@} +@end example + +I.e., the user can start the memory debugger any time he wants if the +program was started with @code{MALLOC_TRACE} set in the environment. +The output will of course not show the allocations which happened before +the first signal but if there is a memory leak this will show up +nevertheless. + +@node Interpreting the traces +@subsection Interpreting the traces + +If you take a look at the output it will look similar to this: + +@example += Start +@ [0x8048209] - 0x8064cc8 +@ [0x8048209] - 0x8064ce0 +@ [0x8048209] - 0x8064cf8 +@ [0x80481eb] + 0x8064c48 0x14 +@ [0x80481eb] + 0x8064c60 0x14 +@ [0x80481eb] + 0x8064c78 0x14 +@ [0x80481eb] + 0x8064c90 0x14 += End +@end example + +What this all means is not really important since the trace file is not +meant to be read by a human. Therefore no attention is payed to good +readability. Instead there is a program which comes with the GNU C +library which interprets the traces and outputs a summary in on +user-friendly way. The program is called @code{mtrace} (it is in fact a +Perl script) and it takes one or two arguments. In any case the name of +the file with the trace must be specified. If an optional precedes the +name of the trace file this must be the name of the program which +generated the trace. + +@example +drepper$ mtrace tst-mtrace log +No memory leaks. +@end example + +In this case the program @code{tst-mtrace} was run and it produced a +trace file @file{log}. The message printed by @code{mtrace} shows there +are no problems with the code, all allocated memory was freed +afterwards. + +If we call @code{mtrace} on the example trace given above we would get a +different outout: + +@example +drepper$ mtrace errlog +- 0x08064cc8 Free 2 was never alloc'd 0x8048209 +- 0x08064ce0 Free 3 was never alloc'd 0x8048209 +- 0x08064cf8 Free 4 was never alloc'd 0x8048209 + +Memory not freed: +----------------- + Address Size Caller +0x08064c48 0x14 at 0x80481eb +0x08064c60 0x14 at 0x80481eb +0x08064c78 0x14 at 0x80481eb +0x08064c90 0x14 at 0x80481eb +@end example + +We have called @code{mtrace} with only one argument and so the script +has no chance to find out what is meant with the addresses given in the +trace. We can do better: + +@example +drepper$ mtrace tst-mtrace errlog +- 0x08064cc8 Free 2 was never alloc'd /home/drepper/tst-mtrace.c:39 +- 0x08064ce0 Free 3 was never alloc'd /home/drepper/tst-mtrace.c:39 +- 0x08064cf8 Free 4 was never alloc'd /home/drepper/tst-mtrace.c:39 + +Memory not freed: +----------------- + Address Size Caller +0x08064c48 0x14 at /home/drepper/tst-mtrace.c:33 +0x08064c60 0x14 at /home/drepper/tst-mtrace.c:33 +0x08064c78 0x14 at /home/drepper/tst-mtrace.c:33 +0x08064c90 0x14 at /home/drepper/tst-mtrace.c:33 +@end example + +Suddenly the output makes much more sense and the user can see +immediately where the function calls causing the trouble can be found. + @node Obstacks @section Obstacks @cindex obstacks @@ -1442,7 +1689,7 @@ source file that uses @code{obstack_init} (@pxref{Creating Obstacks}). Most often they are defined as macros like this: @smallexample -#define obstack_chunk_alloc xmalloc +#define obstack_chunk_alloc malloc #define obstack_chunk_free free @end smallexample diff --git a/manual/signal.texi b/manual/signal.texi index e6014ec195..177b3b98c0 100644 --- a/manual/signal.texi +++ b/manual/signal.texi @@ -3148,7 +3148,6 @@ The return value is @code{0} on success and @code{-1} on failure. If @code{sigaltstack} fails, it sets @code{errno} to one of these values: @table @code -@item @item EINVAL You tried to disable a stack that was in fact currently in use. -- cgit v1.2.3