diff options
Diffstat (limited to 'mandoc_dbg_init.3')
-rw-r--r-- | mandoc_dbg_init.3 | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/mandoc_dbg_init.3 b/mandoc_dbg_init.3 new file mode 100644 index 00000000..58f737e0 --- /dev/null +++ b/mandoc_dbg_init.3 @@ -0,0 +1,280 @@ +.\" $Id$ +.\" +.\" Copyright (c) 2021, 2022 Ingo Schwarze <schwarze@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate$ +.Dt MANDOC_DBG_INIT 3 +.Os +.Sh NAME +.Nm mandoc_dbg_init , +.Nm mandoc_dbg_name , +.Nm mandoc_dbg_finish +.Nd search for memory leaks in mandoc +.Sh SYNOPSIS +.Ft void +.Fn mandoc_dbg_init "int argc" "char *argv[]" +.Ft void +.Fn mandoc_dbg_name "const char *" +.Ft void +.Fn mandoc_dbg_finish void +.Sh DESCRIPTION +If the mandoc package is built with the line +.Ql DEBUG_MEMORY=1 +in the file +.Pa configure.local , +the functions documented in +.Xr mandoc_malloc 3 +and the function +.Xr free 3 +are instrumented to record every memory allocation in a dedicated +hash table and to check that every allocation is freed again. +This compile time option is only intended for binaries that are +used exclusively for debugging. +It is not intended for production binaries because it significantly +increases run time and memory usage and makes the programs more +fragile and more error-prone. +.Pp +The function +.Fn mandoc_dbg_init +initializes the memory debugging subsystem. +It is called from the top of the +.Fn main +programs, passing through the arguments that +.Fn main +received. +The +.Sx ENVIRONMENT +section of the present manual page explains how the +.Ev DEBUG_MEMORY +environment variable controls the amount and destination of reporting. +.Pp +The function +.Fn mandoc_dbg_name +is called from the +.Xr mdoc 7 +and +.Xr man 7 +parsers whenever a +.Ic \&Dt +or +.Ic \&TH +macro is parsed, passing the complete macro line as the argument. +.Pp +The function +.Fn mandoc_dbg_finish +performs cleanup and optionally final reporting. +It is called from the end of the +.Fn main +programs, just before normal termination. +.Pp +Getting the +.Sy #include +directives right for these functions is slightly tricky. +If a file already includes +.Qq Pa mandoc_aux.h , +no additional directive is needed because +.Qq Pa mandoc_aux.h +already includes +.Qq Pa mandoc_dgb.h +if +.Ql DEBUG_MEMORY=1 +is set in +.Pa configure.local . +.Pp +If a file does not need +.Qq Pa mandoc_aux.h +but calls a function documented in the present manual page and also calls +.Xr free 3 +directly, it needs this code before the other +.Xr mandoc_headers 3 : +.Bd -literal -offset indent +#if DEBUG_MEMORY +#include "mandoc_dbg.h" +#endif +.Ed +.Pp +If a file calls a function documented in the present manual page +but does not directly call +.Xr free 3 , +it can use this less intrusive idiom: +.Bd -literal -offset indent +#if DEBUG_MEMORY +#define DEBUG_NODEF +#include "mandoc_dbg.h" +#endif +.Ed +.Sh ENVIRONMENT +The environment variable +.Ev DEBUG_MEMORY +controls the amount and destination of reporting. +.Pp +If it is unset, diagnostic output is directed to standard error output +and only fatal errors are reported. +Even though full memory accounting is always performed +by any binary that was compiled with +.Ql DEBUG_MEMORY=1 , +resulting in a significant increase in both run time and memory usage, +memory leaks are +.Em not +reported when +.Ev DEBUG_MEMORY +is not set at run time. +.Pp +If +.Ev DEBUG_MEMORY +is set, it is interpreted as a string of flags. +The flags are as follows: +.Bl -tag -width 1n +.It Cm A +Log every allocation. +This produces huge amounts of output and is usually not needed +to find memory leaks. +Its main purpose is debugging the memory debugging subsystem itself. +.Pp +When enabled, allocations are logged in this format: +.Pp +.D1 Cm A Ar file Ns .c: Ns Ar line function Ns Po Fa nmemb , size Pc\ + No = Ar address +.Pp +The meaning of the fields is the same as for the +.Cm L +option. +.It Cm F +Log every +.Xr free 3 +and every reallocation where the memory to be released or reallocated +was allocated with one of the functions documented in +.Xr mandoc_malloc 3 . +Again, this produces huge amounts of output and is usually not +needed to find memory leaks, and its main purpose is debugging the +memory debugging subsystem itself. +.Pp +The logging format is: +.Pp +.D1 Cm F Ar file Ns .c: Ns Ar line function Ns Pq address +.Pp +It provides the name of the +.Ar file +and the number of the +.Ar line +in that file which called the +.Xr free 3 +or reallocation +.Ar function , +and the +.Fa address +that was given as an argument. +.Pp +If both the +.Cm A +and the +.Cm F +flags are enabled, calls to reallocation functions often log two lines, +first an +.Cm F +line reporting the address passed in as an argument, then an +.Cm A +line reporting the adress returned as the function return value. +.It Cm L +Log every memory leak. +For every allocation made after +.Fn mandoc_dbg_init +using functions documented in +.Xr mandoc_malloc 3 +that was not freed before +.Fn mandoc_dbg_finish , +print a line in this format: +.Pp +.D1 Cm L Ar file Ns .c: Ns Ar line function Ns Po Fa nmemb , size Pc\ + No = Ar address +.Pp +It provides the name of the +.Ar file +and the number of the +.Ar line +in that file which called the allocation +.Ar function +with the arguments +.Fa nmemb +and +.Fa size +documented for +.Xr calloc 3 . +If the +.Ar function +does not take an +.Fa nmemb +argument, +.Fa nmemb +is reported as 1. +At the end of the line, the virtual +.Ar address +of the memory returned from the allocation function is reported. +.It Cm N +Log the names of manual pages processed in the following formats: +.Bd -unfilled -offset indent +.Cm N Pf . Ic \&Dt Ar name section Op Ar architecture +.Cm N Pf . Ic \&TH Ar name section Op Ar additional arguments +.Ed +.Pp +This is particularly useful if a program crashes, runs out of memory, +or enters an infinite loop. +The last +.Cm N +line logged often indicates the input file triggering the problem. +.It Cm / +Interpret the rest of +.Ev DEBUG_MEMORY +as an absolute path and redirect debugging output to that file, +appending to the file if it already exists or creating it otherwise. +.El +.Pp +If +.Ev DEBUG_MEMORY +is set, even if it is empty, +.Fn mandoc_dbg_init +always writes the line +.Pp +.D1 Cm P Ar pid Sy \&[ Ns Ar progname Ns Sy \&]\ + Sy \&[ Ns Ar argument Ns Sy \&] Ar ... +.Pp +enclosing each element of +.Fa argv +in square brackets, to avoid that arguments containing whitespace +appear in the same way as multiple arguments, and +.Fn mandoc_dbg_finish +always writes the line: +.Pp +.D1 Cm S Ar number No memory leaks found +.Sh EXAMPLES +The following is a typical sequence of commands for finding memory +leaks in the parsers, in the HTML formatter, and in the regression suite: +.Bd -literal -offset indent +make distclean +echo BUILD_CATMAN=1 >> configure.local +echo DEBUG_MEMORY=1 >> configure.local +\&./configure +make +export DEBUG_MEMORY=NL/tmp/mandoc.debug.txt +mkdir Out +export PATH=$PATH:$(pwd) +\&./catman -T html /usr/share/man Out +make regress-clean +make regress +less /tmp/mandoc.debug.txt +.Ed +.Sh SEE ALSO +.Xr mandoc_malloc 3 , +.Xr catman 8 |