summaryrefslogtreecommitdiff
path: root/contrib/sendmail/libsm/heap.html
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/libsm/heap.html')
-rw-r--r--contrib/sendmail/libsm/heap.html424
1 files changed, 0 insertions, 424 deletions
diff --git a/contrib/sendmail/libsm/heap.html b/contrib/sendmail/libsm/heap.html
deleted file mode 100644
index bc32b012e7570..0000000000000
--- a/contrib/sendmail/libsm/heap.html
+++ /dev/null
@@ -1,424 +0,0 @@
-<html>
-<head>
- <title>libsm : Memory Allocation</title>
-</head>
-<body>
-
-<a href="index.html">Back to libsm overview</a>
-
-<center>
- <h1> libsm : Memory Allocation </h1>
- <br> $Id: heap.html,v 1.9 2000/12/08 21:41:42 ca Exp $
-</center>
-
-<h2> Introduction </h2>
-
-The heap package provides a layer of abstraction on top of
-<tt>malloc</tt>, <tt>realloc</tt> and <tt>free</tt>
-that provides optional error checking and memory leak detection,
-and which optionally raises an exception when an allocation request
-cannot be satisfied.
-
-<h2> Synopsis </h2>
-
-<pre>
-#include &lt;sm/heap.h&gt;
-
-/*
-** Wrappers for malloc, realloc, free
-*/
-void *sm_malloc(size_t size);
-void *sm_realloc(void *ptr, size_t size);
-void sm_free(void *ptr);
-
-/*
-** Wrappers for malloc, realloc that raise an exception instead of
-** returning NULL on heap exhaustion.
-*/
-void *sm_malloc_x(size_t size);
-void *sm_realloc_x(void *ptr, size_t size);
-
-/*
-** Print a list of currently allocated blocks,
-** used to diagnose memory leaks.
-*/
-void sm_heap_report(FILE *stream, int verbosity);
-
-/*
-** Low level interfaces.
-*/
-int sm_heap_group();
-int sm_heap_setgroup(int g);
-int sm_heap_newgroup();
-void *sm_malloc_tagged(size_t size, char *file, int line, int group);
-void *sm_malloc_tagged_x(size_t size, char *file, int line, int group);
-bool sm_heap_register(void *ptr, size_t size, char *file, int line);
-</pre>
-
-<h2> How to allocate and free memory </h2>
-
- <tt>sm_malloc</tt>, <tt>sm_realloc</tt> and <tt>sm_free</tt>
- are portable plug in replacements
- for <tt>malloc</tt>, <tt>realloc</tt> and <tt>free</tt> that provide
- error checking and memory leak detection.
- <tt>sm_malloc_x</tt> and <tt>sm_realloc_x</tt>
- are variants of
- <tt>sm_malloc</tt> and <tt>sm_realloc</tt>
- that raise an exception on error.
- To use the package effectively,
- all calls to <tt>malloc</tt>, <tt>realloc</tt> and <tt>free</tt>
- should be replaced by calls
- to the corresponding <tt>sm_</tt>* routines.
-
-<dl>
-<dt>
-<tt> void *sm_malloc(size_t size) </tt>
-<dd>
- This function is a plug-in replacement for <tt>malloc</tt>.
- It allocates <tt>size</tt> bytes of memory on the heap
- and returns a pointer to it,
- or it returns <tt>NULL</tt> on failure.
- <p>
-
- The C standard says that <tt>malloc(0)</tt> may return
- either <tt>NULL</tt> or a non-<tt>NULL</tt> value.
- To ensure consistent behaviour on all platforms,
- <tt>sm_malloc(0)</tt> is equivalent to <tt>sm_malloc(1)</tt>.
- <p>
-
- In addition, if heap checking is enabled, then <tt>sm_malloc</tt>
- maintains a hash table describing all currently allocated
- memory blocks. This table is used for argument validity
- checking in <tt>sm_realloc</tt> and <tt>sm_free</tt>,
- and it can be printed using <tt>sm_heap_report</tt>
- as an aid to finding memory leaks.
- <p>
-
-<dt>
-<tt> void *sm_malloc_x(size_t size) </tt>
-<dd>
- This function is just like <tt>sm_malloc</tt>
- except that it raises the <tt>SmHeapOutOfMemory</tt> exception
- instead of returning <tt>NULL</tt> on error.
- <p>
-
-<dt>
-<tt> void *sm_realloc(void *ptr, size_t size) </tt>
-<dd>
- This function is a plug-in replacement for <tt>realloc</tt>.
- If <tt>ptr</tt> is null then this call is equivalent
- to <tt>sm_malloc(size)</tt>.
- Otherwise, the size of the object pointed to by <tt>ptr</tt>
- is changed to <tt>size</tt> bytes, and a pointer to the
- (possibly moved) object is returned.
- If the space cannot be allocated, then the object pointed to
- by <tt>ptr</tt> is unchanged and <tt>NULL</tt> is returned.
- <p>
-
- If <tt>size</tt> is 0 then we pretend that <tt>size</tt> is 1.
- This may be a mistake.
- <p>
-
- If ptr is not NULL and heap checking is enabled,
- then ptr is required to be a value that was
- previously returned by sm_malloc or sm_realloc, and which
- has not yet been freed by sm_free. If this condition is not
- met, then the program is aborted using sm_abort.
- <p>
-
-<dt>
-<tt> void *sm_realloc_x(void *ptr, size_t size) </tt>
-<dd>
- This function is just like <tt>sm_realloc</tt>
- except that it raises the SmHeapOutOfMemory exception
- instead of returning <tt>NULL</tt> on error.
- <p>
-
-<dt>
-<tt> void sm_free(void *ptr) </tt>
-<dd>
- This function is a plug-in replacement for free.
- If heap checking is disabled, then this function is equivalent
- to a call to free. Otherwise, the following additional semantics
- apply.
- <p>
-
- If ptr is NULL, this function has no effect.
- <p>
-
- Otherwise, ptr is required to be a value that was
- previously returned by sm_malloc or sm_realloc, and which
- has not yet been freed by sm_free. If this condition is not
- met, then the program is aborted using sm_abort.
- <p>
-
- Otherwise, if there is no error, then the block pointed to by ptr
- will be set to all zeros before free() is called. This is intended
- to assist in detecting the use of dangling pointers.
-</dl>
-
-<h2> How to control tag information </h2>
-
-When heap checking is enabled,
-the heap package maintains a hash table which associates the
-following values with each currently allocated block:
-
-<dl>
-<dt>
-<tt> size_t size </tt>
-<dd>
- The size of the block.
-<dt>
-<tt> char *tag </tt>
-<dd>
- By default, this is the name of the source file from which
- the block was allocated, but you can specify an arbitrary
- string pointer, or <tt>NULL</tt>.
-<dt>
-<tt> int num </tt>
-<dd>
- By default, this is the line number from which the block was
- allocated.
-<dt>
-<tt> int group </tt>
-<dd>
- By convention, group==0 indicates that the block is permanently
- allocated and will never be freed. The meanings of other group
- numbers are defined by the application developer.
- Unless you take special action, all blocks allocated by
- <tt>sm_malloc</tt> and <tt>sm_malloc_x</tt> will be assigned
- to group 1.
-</dl>
-
-These tag values are printed by <tt>sm_heap_report</tt>,
-and are used to help analyze memory allocation behaviour
-and to find memory leaks.
-The following functions give you precise control over the
-tag values associated with each allocated block.
-
-<dl>
-<dt>
-<tt> void *sm_malloc_tagged(size_t size, int tag, int num, int group) </tt>
-<dd>
- Just like <tt>sm_malloc</tt>, except you directly specify
- all of the tag values.
- If heap checking is disabled at compile time, then a call
- to <tt>sm_malloc_tagged</tt> is macro expanded to
- a call to <tt>malloc</tt>.
- <p>
-
- Note that the expression <tt>sm_malloc(size)</tt> is macro expanded to
-
-<blockquote><pre>
-sm_malloc_tagged(size, __FILE__, __LINE__, sm_heap_group())
-</pre></blockquote>
-
-<dt>
-<tt> void *sm_malloc_tagged_x(size_t size, int tag, int num, int group) </tt>
-<dd>
- A variant of <tt>sm_malloc_tagged</tt>
- that raises an exception on error.
- A call to <tt>sm_malloc_x</tt> is macro expanded
- to a call to <tt>sm_malloc_tagged_x</tt>.
- <p>
-
-<dt>
-<tt> int sm_heap_group() </tt>
-<dd>
- The heap package maintains a thread-local variable containing
- the current group number.
- This is the group that <tt>sm_malloc</tt> and <tt>sm_malloc_x</tt>
- will assign a newly allocated block to.
- The initial value of this variable is 1.
- The current value of this variable is returned by
- <tt>sm_heap_group()</tt>.
- <p>
-
-<dt>
-<tt> int sm_heap_setgroup(int g) </tt>
-<dd>
- Set the current group to the specified value.
-</dl>
-
-Here are two examples of how you might use these interfaces.
-
-<ol>
-<li>
-One way to detect memory leaks is to turn on heap checking
-and call <tt>sm_heap_report(stdout,2)</tt>
-when the program exits.
-This prints a list of all allocated blocks that do not belong to group 0.
-(Blocks in group 0 are assumed to be permanently allocated,
-and so their existence at program exit does not indicate a leak.)
-If you want to allocate a block and assign it to group 0,
-you have two choices:
-
-<blockquote><pre>
-int g = sm_heap_group();
-sm_heap_setgroup(0);
-p = sm_malloc_x(size);
-sm_heap_setgroup(g);
-</pre></blockquote>
-
-or
-
-<blockquote><pre>
-p = sm_malloc_tagged_x(size, __FILE__, __LINE__, 0);
-</pre></blockquote>
-
-<li>
-Suppose you have a utility function foo_alloc which allocates
-and initializes a 'foo' object. When sm_heap_report is called,
-all unfreed 'foo' objects will be reported to have the same
-source code file name and line number.
-That might make it difficult to determine where a memory leak is.
-<p>
-
-Here is how you can arrange for more precise reporting for
-unfreed foo objects:
-
-<blockquote><pre>
-#include &lt;sm/heap.h&gt;
-
-#if SM_HEAP_CHECK
-# define foo_alloc_x() foo_alloc_tagged_x(__FILE__,__LINE)
- FOO *foo_alloc_tagged_x(char *, int);
-#else
- FOO *foo_alloc_x(void);
-# define foo_alloc_tagged_x(file,line) foo_alloc_x()
-#endif
-
-...
-
-#if SM_HEAP_CHECK
-FOO *
-foo_alloc_tagged_x(char *file, int line)
-#else
-FOO *
-foo_alloc_x(void)
-#endif
-{
- FOO *p;
-
- p = sm_malloc_tagged_x(sizeof(FOO), file, line, sm_heap_group());
- ...
- return p;
-}
-</pre></blockquote>
-</ol>
-
-<h2> How to dump the block list </h2>
-
-To perform memory leak detection, you need to arrange for your
-program to call sm_heap_report at appropriate times.
-
-<dl>
-<dt>
-<tt> void sm_heap_report(FILE *stream, int verbosity) </tt>
-<dd>
- If heap checking is disabled, this function does nothing.
- If verbosity &lt;= 0, this function does nothing.
- <p>
-
- If verbosity &gt;= 1, then sm_heap_report prints a single line
- to stream giving the total number of bytes currently allocated.
- If you call sm_heap_report each time the program has reached a
- "ground state", and the reported amount of heap storage is
- monotonically increasing, that indicates a leak.
- <p>
-
- If verbosity &gt;= 2, then sm_heap_report additionally prints one line
- for each block of memory currently allocated, providing that
- the group != 0.
- (Such blocks are assumed to be permanently allocated storage, and
- are not reported to cut down the level of noise.)
- <p>
-
- If verbosity &gt;= 3, then sm_heap_report prints one line for each
- allocated block, regardless of the group.
-</dl>
-
-<h2> How to enable heap checking </h2>
-
-The overhead of using the package can be made as small as you want.
-You have three options:
-
-<ol>
-<li>
- If you compile your software with -DSM_HEAP_CHECK=0 then
- sm_malloc, sm_realloc and sm_free will be redefined
- as macros that call malloc, realloc, and free. In this case,
- there is zero overhead.
-<li>
- If you do not define -DSM_HEAP_CHECK=0, and you do not explicitly
- turn on heap checking at run time, then your program will run
- without error checking and memory leak detection, and the additional
- cost of calling sm_malloc, sm_realloc and sm_free is a
- function call and test. That overhead is sufficiently low that
- the checking code can be left compiled in a production environment.
-<li>
- If you do not define -DSM_HEAP_CHECK=0, and you explicitly turn on
- heap checking at run time, then the additional cost of calling
- sm_malloc, sm_realloc and sm_free is a hash table lookup.
-</ol>
-
- Here's how to modify your application to use the heap package.
- First, change all calls to malloc, realloc and free to sm_malloc,
- sm_realloc and sm_free.
- Make sure that there is a -d command line option that
- uses the libsm debug package to enable named debug options.
- Add the following code to your program just before it calls exit,
- or register an atexit handler function containing the following code:
-
-<blockquote><pre>
-#if SM_HEAP_CHECK
- /* dump the heap, if we are checking for memory leaks */
- if (sm_debug_active(&SmHeapCheck, 2))
- sm_heap_report(stdout, sm_debug_level(&SmHeapCheck) - 1);
-#endif
-</pre></blockquote>
-
- To turn on heap checking, use the command line option "-dsm_check_heap.1".
- This will cause a table of all currently allocated blocks to be
- maintained. The table is used by sm_realloc and sm_free to perform
- validity checking on the first argument.
-
- <p>
- The command line option "-dsm_check_heap.2" will cause your application
- to invoke sm_heap_report with verbosity=1 just before exit.
- That will print a single line reporting total storage allocation.
-
- <p>
- The command line option "-dsm_check_heap.3" will cause your application
- to invoke sm_heap_report with verbosity=2 just before exit.
- This will print a list of all leaked blocks.
-
- <p>
- The command line option "-dsm_check_heap.4" will cause your application
- to invoke sm_heap_report with verbosity=3 just before exit.
- This will print a list of all allocated blocks.
-
-<h2> Using sm_heap_register </h2>
-
- Suppose you call a library routine foo that allocates a block of storage
- for you using malloc, and expects you to free the block later using
- free. Because the storage was not allocated using sm_malloc, you
- will normally get an abort if you try to pass the pointer to
- sm_free. The way to fix this problem is to 'register' the pointer
- returned by foo with the heap package, by calling sm_heap_register:
-
-<blockquote><pre>
-bool sm_heap_register(ptr, size, file, line, group)
-</pre></blockquote>
-
- The 'ptr' argument is the pointer returned by foo. The 'size' argument
- can be smaller than the actual size of the allocated block, but it must
- not be larger. The file and line arguments indicate at which line of
- source code the block was allocated, and is printed by sm_heap_report.
- For group, you probably want to pass sm_heap_group().
- <p>
- This function returns <tt>true</tt> on success,
- or <tt>false</tt> if it failed due to heap exhaustion.
-
-</body>
-</html>