debugging.html revision bf8889c98dd1b7b4daf701cdf96652d5c9afb837
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<TITLE>Debugging Memory Allocation in APR</TITLE>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen BGCOLOR="#FFFFFF"
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen TEXT="#000000"
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen LINK="#0000FF"
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen VLINK="#000080"
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen ALINK="#FF0000"
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<!--#include virtual="header.html" -->
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<H1 ALIGN="CENTER">Debugging Memory Allocation in APR<br></H1>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<p>The allocation mechanism's within APR have a number of debugging
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainenmodes that can be used to assist in finding memory problems. This document describes
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainenthe modes available and gives instructions on activating them.</p>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<li><a href="#options">Available debugging options</a></li>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<li><a href="#combo">Allowable combinations</a></li>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<li><a href="#howto">How to activate debugging</a></li>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<p><em>Debugging support: Define this to enable code which helps detect re-use of freed memory and other such nonsense.</em></p>
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen<p>The theory is simple. The FILL_BYTE (0xa5) is written over all malloc'd memory as we receive it, and is written over everything that we free up during a clear_pool. We check that blocks on the free list always have the FILL_BYTE in them, and we check during palloc() that the bytes still have FILL_BYTE in them. If you ever see garbage URLs or whatnot containing lots of 0xa5s then you know something used data that's been freed or uninitialized.</p>
588a0579058849aed9f7b59d8259e0c58d9fd23cTimo Sirainen<p><em>If defined all allocations will be done with malloc and free()d appropriately at the end.
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<p>This is intended to be used with something like Electric Fence or Purify to help detect memory problems. Note that if you're using efence then you should also add in ALLOC_DEBUG. But don't add in ALLOC_DEBUG if you're using Purify because ALLOC_DEBUG would hide all the uninitialized read errors that Purify can diagnose.</p>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<p><em>This is intended to detect cases where the wrong pool is used when assigning data to an object in another pool.</em></p>
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen<p>In particular, it causes the table_{set,add,merge}n routines to check that their arguments are safe for the ap_table_t they're being placed in. It currently only works with the unix multiprocess model, but could be extended to others.</p>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<p><em>Provide diagnostic information about make_table() calls which are possibly too small.</em></p>
f39a06c378f6ea80a4ae9d257f0d79221a945a57Timo Sirainen<p>This requires a recent gcc which supports __builtin_return_address(). The error_log output will be a message such as: </p>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<pre>table_push: ap_table_t created by 0x804d874 hit limit of 10</pre>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<p>Use "<em><strong>l *0x804d874</strong></em>" to find the source that corresponds to. It
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen indicates that a ap_table_t allocated by a call at that address has possibly too small an initial ap_table_t size guess.</p>
d861bc0977b229cdaeb3fb77377e2a2bd9d40d3dTimo Sirainen<p><em>Provide some statistics on the cost of allocations.</em></p>
cf41318871bd42358df3420e50614f5310b08c77Martti Rannanjärvi<p>This requires a bit of an understanding of how alloc.c works.</p>
bb11a1957aefbd2a2edf7ae25af4032899c34c41Martti Rannanjärvi<p>Not all the options outlined above can be activated at the same time. the following table gives more information.</p>
bb11a1957aefbd2a2edf7ae25af4032899c34c41Martti Rannanjärvi<th width="15%">MAKE<br>TABLE<br>PROFILE</th>
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen<p>Additionally the debugging options are not suitable for multi-threaded versions of the server. When trying to debug with these options the server should be started in single process mode.</p>
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen<p>The various options for debugging memory are now enabled in the apr_general.h header file in APR. The various options are enabled by uncommenting the define for the option you wish to use. The section of the code currently looks like this <em>(contained in src/lib/apr/inclide/apr_general.h)</em></p>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen#define ALLOC_DEBUG
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen#define POOL_DEBUG
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen#define ALLOC_USE_MALLOC
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen#define MAKE_TABLE_PROFILE
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen#define ALLOC_STATS
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainentypedef struct ap_pool_t {
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen union block_hdr *first;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen union block_hdr *last;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen struct cleanup *cleanups;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen struct process_chain *subprocesses;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen struct ap_pool_t *sub_pools;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen struct ap_pool_t *sub_next;
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen struct ap_pool_t *sub_prev;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen struct ap_pool_t *parent;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen char *free_first_avail;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen#ifdef ALLOC_USE_MALLOC
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen void *allocation_list;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen#ifdef POOL_DEBUG
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen struct ap_pool_t *joined;
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen int (*apr_abort)(int retcode);
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen struct datastruct *prog_data;
5de0c65da362236080fa699af3da03e45e480ab8Timo Sirainen<p>To enable allocation debugging simply move the #define ALLOC_DEBUG above the start of the comments block and rebuild the server.</p>
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<h3>NB. In order to use the various options the server MUST be rebuilt after editing the header file.
1f2f38f518ea14d1042c98ab039e6df053f7b285Timo Sirainen<!--#include virtual="footer.html" -->