Annotation of mandoc/mandoc_dbg_init.3, Revision 1.1
1.1 ! schwarze 1: .\" $Id$
! 2: .\"
! 3: .\" Copyright (c) 2021, 2022 Ingo Schwarze <schwarze@openbsd.org>
! 4: .\"
! 5: .\" Permission to use, copy, modify, and distribute this software for any
! 6: .\" purpose with or without fee is hereby granted, provided that the above
! 7: .\" copyright notice and this permission notice appear in all copies.
! 8: .\"
! 9: .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 10: .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 12: .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 15: .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: .\"
! 17: .Dd $Mdocdate$
! 18: .Dt MANDOC_DBG_INIT 3
! 19: .Os
! 20: .Sh NAME
! 21: .Nm mandoc_dbg_init ,
! 22: .Nm mandoc_dbg_name ,
! 23: .Nm mandoc_dbg_finish
! 24: .Nd search for memory leaks in mandoc
! 25: .Sh SYNOPSIS
! 26: .Ft void
! 27: .Fn mandoc_dbg_init "int argc" "char *argv[]"
! 28: .Ft void
! 29: .Fn mandoc_dbg_name "const char *"
! 30: .Ft void
! 31: .Fn mandoc_dbg_finish void
! 32: .Sh DESCRIPTION
! 33: If the mandoc package is built with the line
! 34: .Ql DEBUG_MEMORY=1
! 35: in the file
! 36: .Pa configure.local ,
! 37: the functions documented in
! 38: .Xr mandoc_malloc 3
! 39: and the function
! 40: .Xr free 3
! 41: are instrumented to record every memory allocation in a dedicated
! 42: hash table and to check that every allocation is freed again.
! 43: This compile time option is only intended for binaries that are
! 44: used exclusively for debugging.
! 45: It is not intended for production binaries because it significantly
! 46: increases run time and memory usage and makes the programs more
! 47: fragile and more error-prone.
! 48: .Pp
! 49: The function
! 50: .Fn mandoc_dbg_init
! 51: initializes the memory debugging subsystem.
! 52: It is called from the top of the
! 53: .Fn main
! 54: programs, passing through the arguments that
! 55: .Fn main
! 56: received.
! 57: The
! 58: .Sx ENVIRONMENT
! 59: section of the present manual page explains how the
! 60: .Ev DEBUG_MEMORY
! 61: environment variable controls the amount and destination of reporting.
! 62: .Pp
! 63: The function
! 64: .Fn mandoc_dbg_name
! 65: is called from the
! 66: .Xr mdoc 7
! 67: and
! 68: .Xr man 7
! 69: parsers whenever a
! 70: .Ic \&Dt
! 71: or
! 72: .Ic \&TH
! 73: macro is parsed, passing the complete macro line as the argument.
! 74: .Pp
! 75: The function
! 76: .Fn mandoc_dbg_finish
! 77: performs cleanup and optionally final reporting.
! 78: It is called from the end of the
! 79: .Fn main
! 80: programs, just before normal termination.
! 81: .Pp
! 82: Getting the
! 83: .Sy #include
! 84: directives right for these functions is slightly tricky.
! 85: If a file already includes
! 86: .Qq Pa mandoc_aux.h ,
! 87: no additional directive is needed because
! 88: .Qq Pa mandoc_aux.h
! 89: already includes
! 90: .Qq Pa mandoc_dgb.h
! 91: if
! 92: .Ql DEBUG_MEMORY=1
! 93: is set in
! 94: .Pa configure.local .
! 95: .Pp
! 96: If a file does not need
! 97: .Qq Pa mandoc_aux.h
! 98: but calls a function documented in the present manual page and also calls
! 99: .Xr free 3
! 100: directly, it needs this code before the other
! 101: .Xr mandoc_headers 3 :
! 102: .Bd -literal -offset indent
! 103: #if DEBUG_MEMORY
! 104: #include "mandoc_dbg.h"
! 105: #endif
! 106: .Ed
! 107: .Pp
! 108: If a file calls a function documented in the present manual page
! 109: but does not directly call
! 110: .Xr free 3 ,
! 111: it can use this less intrusive idiom:
! 112: .Bd -literal -offset indent
! 113: #if DEBUG_MEMORY
! 114: #define DEBUG_NODEF
! 115: #include "mandoc_dbg.h"
! 116: #endif
! 117: .Ed
! 118: .Sh ENVIRONMENT
! 119: The environment variable
! 120: .Ev DEBUG_MEMORY
! 121: controls the amount and destination of reporting.
! 122: .Pp
! 123: If it is unset, diagnostic output is directed to standard error output
! 124: and only fatal errors are reported.
! 125: Even though full memory accounting is always performed
! 126: by any binary that was compiled with
! 127: .Ql DEBUG_MEMORY=1 ,
! 128: resulting in a significant increase in both run time and memory usage,
! 129: memory leaks are
! 130: .Em not
! 131: reported when
! 132: .Ev DEBUG_MEMORY
! 133: is not set at run time.
! 134: .Pp
! 135: If
! 136: .Ev DEBUG_MEMORY
! 137: is set, it is interpreted as a string of flags.
! 138: The flags are as follows:
! 139: .Bl -tag -width 1n
! 140: .It Cm A
! 141: Log every allocation.
! 142: This produces huge amounts of output and is usually not needed
! 143: to find memory leaks.
! 144: Its main purpose is debugging the memory debugging subsystem itself.
! 145: .Pp
! 146: When enabled, allocations are logged in this format:
! 147: .Pp
! 148: .D1 Cm A Ar file Ns .c: Ns Ar line function Ns Po Fa nmemb , size Pc\
! 149: No = Ar address
! 150: .Pp
! 151: The meaning of the fields is the same as for the
! 152: .Cm L
! 153: option.
! 154: .It Cm F
! 155: Log every
! 156: .Xr free 3
! 157: and every reallocation where the memory to be released or reallocated
! 158: was allocated with one of the functions documented in
! 159: .Xr mandoc_malloc 3 .
! 160: Again, this produces huge amounts of output and is usually not
! 161: needed to find memory leaks, and its main purpose is debugging the
! 162: memory debugging subsystem itself.
! 163: .Pp
! 164: The logging format is:
! 165: .Pp
! 166: .D1 Cm F Ar file Ns .c: Ns Ar line function Ns Pq address
! 167: .Pp
! 168: It provides the name of the
! 169: .Ar file
! 170: and the number of the
! 171: .Ar line
! 172: in that file which called the
! 173: .Xr free 3
! 174: or reallocation
! 175: .Ar function ,
! 176: and the
! 177: .Fa address
! 178: that was given as an argument.
! 179: .Pp
! 180: If both the
! 181: .Cm A
! 182: and the
! 183: .Cm F
! 184: flags are enabled, calls to reallocation functions often log two lines,
! 185: first an
! 186: .Cm F
! 187: line reporting the address passed in as an argument, then an
! 188: .Cm A
! 189: line reporting the adress returned as the function return value.
! 190: .It Cm L
! 191: Log every memory leak.
! 192: For every allocation made after
! 193: .Fn mandoc_dbg_init
! 194: using functions documented in
! 195: .Xr mandoc_malloc 3
! 196: that was not freed before
! 197: .Fn mandoc_dbg_finish ,
! 198: print a line in this format:
! 199: .Pp
! 200: .D1 Cm L Ar file Ns .c: Ns Ar line function Ns Po Fa nmemb , size Pc\
! 201: No = Ar address
! 202: .Pp
! 203: It provides the name of the
! 204: .Ar file
! 205: and the number of the
! 206: .Ar line
! 207: in that file which called the allocation
! 208: .Ar function
! 209: with the arguments
! 210: .Fa nmemb
! 211: and
! 212: .Fa size
! 213: documented for
! 214: .Xr calloc 3 .
! 215: If the
! 216: .Ar function
! 217: does not take an
! 218: .Fa nmemb
! 219: argument,
! 220: .Fa nmemb
! 221: is reported as 1.
! 222: At the end of the line, the virtual
! 223: .Ar address
! 224: of the memory returned from the allocation function is reported.
! 225: .It Cm N
! 226: Log the names of manual pages processed in the following formats:
! 227: .Bd -unfilled -offset indent
! 228: .Cm N Pf . Ic \&Dt Ar name section Op Ar architecture
! 229: .Cm N Pf . Ic \&TH Ar name section Op Ar additional arguments
! 230: .Ed
! 231: .Pp
! 232: This is particularly useful if a program crashes, runs out of memory,
! 233: or enters an infinite loop.
! 234: The last
! 235: .Cm N
! 236: line logged often indicates the input file triggering the problem.
! 237: .It Cm /
! 238: Interpret the rest of
! 239: .Ev DEBUG_MEMORY
! 240: as an absolute path and redirect debugging output to that file,
! 241: appending to the file if it already exists or creating it otherwise.
! 242: .El
! 243: .Pp
! 244: If
! 245: .Ev DEBUG_MEMORY
! 246: is set, even if it is empty,
! 247: .Fn mandoc_dbg_init
! 248: always writes the line
! 249: .Pp
! 250: .D1 Cm P Ar pid Sy \&[ Ns Ar progname Ns Sy \&]\
! 251: Sy \&[ Ns Ar argument Ns Sy \&] Ar ...
! 252: .Pp
! 253: enclosing each element of
! 254: .Fa argv
! 255: in square brackets, to avoid that arguments containing whitespace
! 256: appear in the same way as multiple arguments, and
! 257: .Fn mandoc_dbg_finish
! 258: always writes the line:
! 259: .Pp
! 260: .D1 Cm S Ar number No memory leaks found
! 261: .Sh EXAMPLES
! 262: The following is a typical sequence of commands for finding memory
! 263: leaks in the parsers, in the HTML formatter, and in the regression suite:
! 264: .Bd -literal -offset indent
! 265: make distclean
! 266: echo BUILD_CATMAN=1 >> configure.local
! 267: echo DEBUG_MEMORY=1 >> configure.local
! 268: \&./configure
! 269: make
! 270: export DEBUG_MEMORY=NL/tmp/mandoc.debug.txt
! 271: mkdir Out
! 272: export PATH=$PATH:$(pwd)
! 273: \&./catman -T html /usr/share/man Out
! 274: make regress-clean
! 275: make regress
! 276: less /tmp/mandoc.debug.txt
! 277: .Ed
! 278: .Sh SEE ALSO
! 279: .Xr mandoc_malloc 3 ,
! 280: .Xr catman 8
CVSweb