I've been sitting on a thread debugging package for a while now, and it seems to have stabilized. I'll commit it soon unless someone thinks it should be done differently. It's a wrapper around whatever thread package is used from libldap_r.
Patch to HEAD: http://folk.uio.no/hbf/OpenLDAP/thr_debug.diff New files: * libraries/libldap_r/ldap_thr_debug.h: Re#defines ldap_*_thread_* symbols which will be declared by other files, according to LDAP_THREAD*_IMPLEMENTATION macros #defined before #including the file. * libraries/libldap_r/thr_debug.c. Impact on other files: * include/ldap_int_thread.h, include/ldap_pvt_thread.h: - #define ldap_int_thread_equal() and ldap_pvt_thread_equal(). - Move ldap_pvt_thread_*_t declarations from ldap_pvt_thread.h to ldap_int_thread.h. - Define some ldap_debug_* types. - Multiple inclusion gets hairier, since the files can be #included twice - once with the symbols they declare #defined as the wrapper symbols. * libraries/libldap_r/*.c: - #define LDAP_THREAD*_IMPLEMENTATION as appropriate, then #include new file "ldap_thr_debug.h". - Use ldap_pvt_thread_*_t instead of ldap_int_thread_*_t some places. * libraries/libldap_r/thr_posix.c: - Use mutex attribute PTHREAD_MUTEX_ERRORCHECK - or PTHREAD_MUTEX_ERRORCHECK_NP for Linux. * libraries/libldap_r/tpool.c: - Remove its private thread-implementation-dependent TID_EQ() macro, use the new and equivalent ldap_int_thread_equal() instead. - Needs a preprocessor hack to support thr_debug. Description, copied from libraries/libldap_r/thr_debug.c: This package provides three types of thread operation debugging: - Print error messages and abort() when thread operations fail: Operations on threads, mutexes, condition variables, rdwr locks. Some thread pool operations are also checked, but not those for which failure can happen in normal slapd operation. - Wrap those types except threads and pools in structs that contain a state variable or a pointer to dummy allocated memory, and check that on all operations. The dummy memory variant lets malloc debuggers see some incorrect use as memory leaks, access to freed memory, etc. - Print a count of leaked thread resources after cleanup. Compile-time (./configure) setup: Macros defined in CPPFLAGS. LDAP_THREAD_DEBUG or LDAP_THREAD_DEBUG=2 Enables debugging, but value & 2 turns off type wrapping. LDAP_UINTPTR_T=integer type to hold pointers, preferably unsigned. Used by dummy memory option "scramble". Default = unsigned long. In addition, you may need to set up an implementation-specific way to enable whatever error checking your thread library provides. Currently only implemented for Posix threads (pthreads), where you may need to define LDAP_INT_THREAD_MUTEXATTR. The default is PTHREAD_MUTEX_ERRORCHECK, or PTHREAD_MUTEX_ERRORCHECK_NP for Linux threads. See pthread_mutexattr_settype(3). Run-time configuration: Environment variable LDAP_THREAD_DEBUG. The variable may contain a comma- or space-separated option list. Options: off - Disable this package. Error checking: noabort - Do not abort() on errors. noerror - Do not report errors. Implies noabort. nocount - Do not report counts of unreleased resources. State variable/dummy memory, unless type wrapping is disabled: noalloc - Default. Use a state variable, not dummy memory. dupinit - Implies noalloc. Check if resources that have not been destroyed are reinitialized. Tools that report uninitialized memory access should disable such warnings about debug_already_initialized(). alloc - Allocate dummy memory and store pointers as-is. Malloc debuggers might not notice unreleased resources in global variables as memory leaks. scramble - Store bitwise complement of dummy memory pointer. That never escapes memory leak detectors - but detection while the program is running will report active resources as leaks. Do not use this if a garbage collector is in use:-) adjptr - Point to end of dummy memory. Purify reports these as "potential leaks" (PLK). I have not checked other malloc debuggers. Tracing: tracethreads - Report create/join/exit/kill of threads. -- Hallvard
