summaryrefslogtreecommitdiff
path: root/docs/leak.md
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2023-01-26 07:32:47 +0300
committerIvan Maidanski <ivmai@mail.ru>2023-01-26 07:53:41 +0300
commitd389c2d7f08ab48e7b6ec1a22c2afe9d201f5b12 (patch)
treede1e09811741f697ac3bd557af06c402390be641 /docs/leak.md
parenta8d383792100cb9958b430498e5a49ea4c4c2b9f (diff)
downloadbdwgc-d389c2d7f08ab48e7b6ec1a22c2afe9d201f5b12.tar.gz
Rename doc folder to docs
* CMakeLists.txt [enable_docs] (CMAKE_INSTALL_DOCDIR): Rename doc folder to docs. * Makefile.am [ENABLE_DOCS] (docdocdir, dist_docdocs_DATA, dist_docdocsplatforms_DATA): Likewise. * Makefile.direct (CXXFLAGS): Likewise. * README.md: Likewise. * docs/simple_example.md (Other platforms): Likewise. * Makefile.am [ENABLE_DOCS] (docdocdir): Rename to docdocsdir. * Makefile.am [ENABLE_DOCS] (dist_docdoc_DATA): Rename to dist_docdocs_DATA. * Makefile.am [ENABLE_DOCS] (docdocplatformsdir): Rename to docdocsplatformsdir. * Makefile.am [ENABLE_DOCS] (dist_docdocplatforms_DATA): Rename to dist_docdocsplatforms_DATA. * doc/README.autoconf: Move to docs folder. * doc/README.cmake: Likewise. * doc/README.cords: Likewise. * doc/README.environment: Likewise. * doc/README.macros: Likewise. * doc/debugging.md: Likewise. * doc/faq.md: Likewise. * doc/finalization.md: Likewise. * doc/gcdescr.md: Likewise. * doc/gcinterface.md: Likewise. * doc/leak.md: Likewise. * doc/overview.md: Likewise. * doc/porting.md: Likewise. * doc/scale.md: Likewise. * doc/simple_example.md: Likewise. * doc/tree.md: Likewise. * doc/platforms/README.aix: Move to docs/platforms folder. * doc/platforms/README.amiga: Likewise. * doc/platforms/README.arm_cross: Likewise. * doc/platforms/README.darwin: Likewise. * doc/platforms/README.dgux386: Likewise. * doc/platforms/README.emscripten: Likewise. * doc/platforms/README.ews4800: Likewise. * doc/platforms/README.hp: Likewise. * doc/platforms/README.linux: Likewise. * doc/platforms/README.mac: Likewise. * doc/platforms/README.os2: Likewise. * doc/platforms/README.sgi: Likewise. * doc/platforms/README.solaris2: Likewise. * doc/platforms/README.symbian: Likewise. * doc/platforms/README.uts: Likewise. * doc/platforms/README.win32: Likewise. * doc/platforms/README.win64: Likewise.
Diffstat (limited to 'docs/leak.md')
-rw-r--r--docs/leak.md160
1 files changed, 160 insertions, 0 deletions
diff --git a/docs/leak.md b/docs/leak.md
new file mode 100644
index 00000000..b5147596
--- /dev/null
+++ b/docs/leak.md
@@ -0,0 +1,160 @@
+# Using the Garbage Collector as Leak Detector
+
+The garbage collector may be used as a leak detector. In this case, the
+primary function of the collector is to report objects that were allocated
+(typically with `GC_MALLOC`), not deallocated (normally with `GC_FREE`), but
+are no longer accessible. Since the object is no longer accessible, there
+is normally no way to deallocate the object at a later time; thus it can
+safely be assumed that the object has been "leaked".
+
+This is substantially different from counting leak detectors, which simply
+verify that all allocated objects are eventually deallocated.
+A garbage-collector based leak detector can provide somewhat more precise
+information when an object was leaked. More importantly, it does not report
+objects that are never deallocated because they are part of "permanent" data
+structures. Thus it does not require all objects to be deallocated at process
+exit time, a potentially useless activity that often triggers large amounts
+of paging.
+
+The garbage collector provides leak detection support. This includes the
+following features:
+
+ 1. Leak detection mode can be initiated at run-time by `GC_set_find_leak(1)`
+ call at program startup instead of building the collector with `FIND_LEAK`
+ macro defined.
+ 2. Leaked objects should be reported and then correctly garbage collected.
+
+To use the collector as a leak detector, do the following steps:
+
+ 1. Activate the leak detection mode as described above.
+ 2. Change the program so that all allocation and deallocation goes through
+ the garbage collector.
+ 3. Arrange to call `GC_gcollect` (or `CHECK_LEAKS()`) at appropriate points
+ to check for leaks. (This happens implicitly but probably not with
+ a sufficient frequency for long running programs.)
+
+The second step can usually be accomplished with the
+`-DREDIRECT_MALLOC=GC_malloc` option when the collector is built, or by
+defining `malloc`, `calloc`, `realloc`, `free` (as well as `posix_memalign`,
+`reallocarray`, `strdup`, `strndup`, `wcsdup`, BSD `memalign`, GNU `valloc`,
+GNU `pvalloc`) to call the corresponding garbage collector function. But this,
+by itself, will not yield very informative diagnostics, since the collector
+does not keep track of the information about how objects were allocated. The
+error reports will include only object addresses.
+
+For more precise error reports, as much of the program as possible should use
+the all uppercase variants of these functions, after defining `GC_DEBUG`, and
+then including `gc.h`. In this environment `GC_MALLOC` is a macro which causes
+at least the file name and line number at the allocation point to be saved
+as part of the object. Leak reports will then also include this information.
+
+Many collector features (e.g. finalization and disappearing links) are less
+useful in this context, and are not fully supported. Their use will usually
+generate additional bogus leak reports, since the collector itself drops some
+associated objects.
+
+The same is generally true of thread support. However, the correct leak
+reports should be generated with linuxthreads, at least.
+
+On a few platforms (currently Solaris/SPARC, Irix, and, with
+`-DSAVE_CALL_CHAIN`, Linux/x86), `GC_MALLOC` also causes some more information
+about its call stack to be saved in the object. Such information is reproduced
+in the error reports in very non-symbolic form, but it can be very useful with
+the aid of a debugger.
+
+## An Example
+
+The `leak_detector.h` file is included in the "include" subdirectory of the
+distribution.
+
+Assume the collector has been built with `-DFIND_LEAK` or
+`GC_set_find_leak(1)` exists as the first statement in `main`.
+
+The program to be tested for leaks could look like `tests/leak.c` file
+of the distribution.
+
+On a Linux/x86 system this produces on the stderr stream:
+
+
+ Found 1 leaked objects:
+ 0x806dff0 (tests/leak.c:19, sz=4, NORMAL)
+
+
+(On most unmentioned operating systems, the output is similar to this. If the
+collector had been built on Linux/x86 with `-DSAVE_CALL_CHAIN`, the output
+would be closer to the Solaris example. For this to work, the program should
+not be compiled with `-fomit_frame_pointer`.)
+
+On Irix it reports:
+
+
+ Found 1 leaked objects:
+ 0x10040fe0 (tests/leak.c:19, sz=4, NORMAL)
+ Caller at allocation:
+ ##PC##= 0x10004910
+
+
+and on Solaris the error report is:
+
+
+ Found 1 leaked objects:
+ 0xef621fc8 (tests/leak.c:19, sz=4, NORMAL)
+ Call chain at allocation:
+ args: 4 (0x4), 200656 (0x30FD0)
+ ##PC##= 0x14ADC
+ args: 1 (0x1), -268436012 (0xEFFFFDD4)
+ ##PC##= 0x14A64
+
+
+In the latter two cases some additional information is given about how malloc
+was called when the leaked object was allocated. For Solaris, the first line
+specifies the arguments to `GC_debug_malloc` (the actual allocation routine),
+The second one specifies the program counter inside `main`, the third one
+specifies the arguments to `main`, and, finally, the program counter inside
+the caller to `main` (i.e. in the C startup code). In the Irix case, only the
+address inside the caller to `main` is given.
+
+In many cases, a debugger is needed to interpret the additional information.
+On systems supporting the `adb` debugger, the `tools/callprocs.sh` script can
+be used to replace program counter values with symbolic names. The collector
+tries to generate symbolic names for call stacks if it knows how to do so on
+the platform. This is true on Linux/x86, but not on most other platforms.
+
+## Simplified leak detection under Linux
+
+It should be possible to run the collector in the leak detection mode on
+a program a.out under Linux/x86 as follows:
+
+ 1. If possible, ensure that a.out is a single-threaded executable. On some
+ platforms this does not work at all for the multi-threaded programs.
+ 2. If possible, ensure that the `addr2line` program is installed
+ in `/usr/bin`. (It comes with most Linux distributions.)
+ 3. If possible, compile your program, which we'll call `a.out`, with full
+ debug information. This will improve the quality of the leak reports.
+ With this approach, it is no longer necessary to call `GC_` routines
+ explicitly, though that can also improve the quality of the leak reports.
+ 4. Build the collector and install it in directory _foo_ as follows (it may
+ be safe to omit the `--disable-threads` option on Linux, but the combination
+ of thread support and `malloc` replacement is not yet rock solid):
+
+ - `configure --prefix=_foo_ --enable-gc-debug --enable-redirect-malloc --disable-threads`
+ - `make`
+ - `make install`
+
+ 5. Set environment variables as follows (the last two are optional, just to
+ confirm the collector is running, and to facilitate debugging from another
+ console window if something goes wrong, respectively):
+
+ - `LD_PRELOAD=_foo_/lib/libgc.so`
+ - `GC_FIND_LEAK`
+ - `GC_PRINT_STATS`
+ - `GC_LOOP_ON_ABORT`
+
+ 6. Simply run `a.out` as you normally would. Note that if you run anything
+ else (e.g. your editor) with those environment variables set, it will also
+ be leak tested. This may or may not be useful and/or embarrassing. It can
+ generate mountains of leak reports if the application was not designed
+ to avoid leaks, e.g. because it's always short-lived.
+
+This has not yet been thoroughly tested on large applications, but it's known
+to do the right thing on at least some small ones.