#if LIBCWD_THREAD_SAFE && CWDEBUG_ALLOC && __GNUC__ == 3
#define private public  
#if (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
#include <bits/stl_alloc.h>
#else
#include <cstdlib>              
#include <ext/pool_allocator.h>
#endif
#undef private
#endif 
 
#include <cerrno>
#include <iostream>
#include <algorithm>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/time.h>   
#include <sys/resource.h>       
#endif
#include <cstdlib>              
#include <new>
#include "cwd_debug.h"
#include "macros.h"
#include "private_debug_stack.inl"
#include <libcwd/class_location.inl>
 
extern "C" int raise(int);
 
#if LIBCWD_THREAD_SAFE
using libcwd::_private_::rwlock_tct;
using libcwd::_private_::debug_objects_instance;
using libcwd::_private_::debug_channels_instance;
#define DEBUG_OBJECTS_ACQUIRE_WRITE_LOCK        rwlock_tct<libcwd::_private_::debug_objects_instance>::wrlock()
#define DEBUG_OBJECTS_RELEASE_WRITE_LOCK        rwlock_tct<libcwd::_private_::debug_objects_instance>::wrunlock()
#define DEBUG_OBJECTS_ACQUIRE_READ_LOCK         rwlock_tct<libcwd::_private_::debug_objects_instance>::rdlock()
#define DEBUG_OBJECTS_RELEASE_READ_LOCK         rwlock_tct<libcwd::_private_::debug_objects_instance>::rdunlock()
#define DEBUG_OBJECTS_ACQUIRE_READ2WRITE_LOCK   rwlock_tct<libcwd::_private_::debug_objects_instance>::rd2wrlock()
#define DEBUG_OBJECTS_ACQUIRE_WRITE2READ_LOCK   rwlock_tct<libcwd::_private_::debug_objects_instance>::wr2rdlock()
#define DEBUG_CHANNELS_ACQUIRE_WRITE_LOCK       rwlock_tct<libcwd::_private_::debug_channels_instance>::wrlock()
#define DEBUG_CHANNELS_RELEASE_WRITE_LOCK       rwlock_tct<libcwd::_private_::debug_channels_instance>::wrunlock()
#define DEBUG_CHANNELS_ACQUIRE_READ_LOCK        rwlock_tct<libcwd::_private_::debug_channels_instance>::rdlock()
#define DEBUG_CHANNELS_RELEASE_READ_LOCK        rwlock_tct<libcwd::_private_::debug_channels_instance>::rdunlock()
#define DEBUG_CHANNELS_ACQUIRE_READ2WRITE_LOCK  rwlock_tct<libcwd::_private_::debug_channels_instance>::rd2wrlock()
#define DEBUG_CHANNELS_ACQUIRE_WRITE2READ_LOCK  rwlock_tct<libcwd::_private_::debug_channels_instance>::wr2rdlock()
#define COMMA_IFTHREADS(x) ,x
#else 
#define DEBUG_OBJECTS_ACQUIRE_WRITE_LOCK
#define DEBUG_OBJECTS_RELEASE_WRITE_LOCK
#define DEBUG_OBJECTS_ACQUIRE_READ_LOCK
#define DEBUG_OBJECTS_RELEASE_READ_LOCK
#define DEBUG_OBJECTS_ACQUIRE_READ2WRITE_LOCK
#define DEBUG_OBJECTS_ACQUIRE_WRITE2READ_LOCK
#define DEBUG_CHANNELS_ACQUIRE_WRITE_LOCK
#define DEBUG_CHANNELS_RELEASE_WRITE_LOCK
#define DEBUG_CHANNELS_ACQUIRE_READ_LOCK
#define DEBUG_CHANNELS_RELEASE_READ_LOCK
#define DEBUG_CHANNELS_ACQUIRE_READ2WRITE_LOCK
#define DEBUG_CHANNELS_ACQUIRE_WRITE2READ_LOCK
#define COMMA_IFTHREADS(x)
#endif 
 
#define NEED_SUPRESSION_OF_MALLOC_AND_BFD (__GNUC__ == 3 && \
    ((__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 0) || \
     (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 1) || \
     (__GNUC_MINOR__ == 0)))
 
 
namespace _private_ {
 
#if LIBCWD_THREAD_SAFE && CWDEBUG_ALLOC && __GNUC__ == 3
 
#if (__GNUC_MINOR__ == 4)
#if (__GNUC_PATCHLEVEL__ <= 1)
__gnu_cxx::_STL_mutex_lock* pool_allocator_lock_symbol_ptr;
#else
__gthread_mutex_t* pool_allocator_lock_symbol_ptr;
#endif
#endif
 
inline
bool allocator_trylock()
{
#if (__GNUC_MINOR__ < 4)
 
#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
  if (!std::__default_alloc_template<true, 0>::_S_node_allocator_lock._M_init_flag)
    std::__default_alloc_template<true, 0>::_S_node_allocator_lock._M_initialize();
#endif
 
  return (__gthread_mutex_trylock(&std::__default_alloc_template<true, 0>::_S_node_allocator_lock._M_lock) == 0);
 
#else 
 
  if (!pool_allocator_lock_symbol_ptr)
    return false;
 
  #if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
  #if (__GNUC_PATCHLEVEL__ <= 1)
    if (!pool_allocator_lock_symbol_ptr->_M_init_flag)
      pool_allocator_lock_symbol_ptr->_M_initialize();
  #else
  
  #error "Sorry, not implemented yet."
  #endif
  #endif
 
#if (__GNUC_PATCHLEVEL__ <= 1)
  return (__gthread_mutex_trylock(&pool_allocator_lock_symbol_ptr->_M_lock) == 0);
#else
  return (__gthread_mutex_trylock(pool_allocator_lock_symbol_ptr) == 0);
#endif
 
#endif 
}
 
inline
void allocator_unlock()
{
#if (__GNUC_MINOR__ < 4)
#if !defined(__GTHREAD_MUTEX_INIT) && defined(__GTHREAD_MUTEX_INIT_FUNCTION)
  if (!std::__default_alloc_template<true, 0>::_S_node_allocator_lock._M_init_flag)
    std::__default_alloc_template<true, 0>::_S_node_allocator_lock._M_initialize();
#endif
  __gthread_mutex_unlock(&std::__default_alloc_template<true, 0>::_S_node_allocator_lock._M_lock);
 
#else 
 
#if (__GNUC_PATCHLEVEL__ <= 1)
  __gthread_mutex_unlock(&pool_allocator_lock_symbol_ptr->_M_lock);
#else
  __gthread_mutex_unlock(pool_allocator_lock_symbol_ptr);
#endif
 
#endif 
}
 
#endif 
 
} 
 
    using _private_::set_alloc_checking_on;
    using _private_::set_alloc_checking_off;
#if CWDEBUG_ALLOC
    using _private_::debug_message_st;
#endif
 
    class buffer_ct : public _private_::auto_internal_stringbuf {
    private:
      typedef pos_type streampos_t;
      streampos_t position;
#if LIBCWD_THREAD_SAFE
      
      bool unfinished_already_printed;
      bool continued_needed;
#endif
    public:
#if LIBCWD_THREAD_SAFE
      buffer_ct() : unfinished_already_printed(false), continued_needed(false) { }
#endif
      void writeto(std::ostream* os LIBCWD_COMMA_TSD_PARAM, debug_ct& debug_object,
          bool request_unfinished, bool do_flush COMMA_IFTHREADS(bool ends_on_newline)
          COMMA_IFTHREADS(bool possible_nonewline_cf));
      void store_position() {
        position = this->pubseekoff(0, std::ios_base::cur, std::ios_base::out);
      }
      void restore_position() {
        this->pubseekpos(position, std::ios_base::out);
        this->pubseekpos(0, std::ios_base::in);
#if LIBCWD_THREAD_SAFE
        continued_needed = false;
#endif
      }
      void write_prefix_to(std::ostream* os)
      {
        streampos_t old_in_pos = this->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
        this->pubseekpos(0, std::ios_base::in);
        os->put(this->sgetc());
        int size = position - std::streampos(0);
        for (int c = 1; c < size; ++c)
          os->put(this->snextc());
        this->pubseekpos(old_in_pos, std::ios_base::in);
      }
    };
 
    void buffer_ct::writeto(std::ostream* os LIBCWD_COMMA_TSD_PARAM,
#if LIBCWD_THREAD_SAFE
        debug_ct& debug_object,
#else
        debug_ct&,
#endif
        bool request_unfinished, bool do_flush COMMA_IFTHREADS(bool ends_on_newline)
        COMMA_IFTHREADS(bool possible_nonewline_cf))
    {
      
      
      
      
      
      
      
      
 
#if LIBCWD_THREAD_SAFE && CWDEBUG_ALLOC && __GNUC__ == 3
      typedef debug_message_st* msgbuf_t;
      msgbuf_t msgbuf;
      
      
      
      
      
      
      bool const queue_msg = __libcwd_tsd.inside_malloc_or_free && !_private_::allocator_trylock();
      if (__libcwd_tsd.inside_malloc_or_free && !queue_msg)
        _private_::allocator_unlock();  
      int const extra_size = sizeof(debug_message_st) - sizeof(msgbuf->buf);
#else
      typedef char* msgbuf_t;
      msgbuf_t msgbuf;
      bool const queue_msg = false;
      int const extra_size = 0;
#endif
      int curlen;
      curlen = this->pubseekoff(0, std::ios_base::cur, std::ios_base::out) - this->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
      bool free_msgbuf = false;
      if (queue_msg)
        msgbuf = (msgbuf_t)
malloc(curlen + extra_size);
 
      else if (curlen > 512 || !(msgbuf = (msgbuf_t)__builtin_alloca(curlen + extra_size)))
      {
        msgbuf = (msgbuf_t)
malloc(curlen + extra_size);
 
        free_msgbuf = true;
      }
#if LIBCWD_THREAD_SAFE && CWDEBUG_ALLOC && __GNUC__ == 3
      this->sgetn(msgbuf->buf, curlen);
#else
      this->sgetn(msgbuf, curlen);
#endif
#if LIBCWD_THREAD_SAFE && CWDEBUG_ALLOC && __GNUC__ == 3
      if (queue_msg)    
      {
        
        
        
        msgbuf->curlen = curlen;
        msgbuf->prev = NULL;
        msgbuf->next = debug_object.queue;
        if (debug_object.queue)
          debug_object.queue->prev = msgbuf;
        else
          debug_object.queue_top = msgbuf;
        debug_object.queue = msgbuf;
      }
      else
      {
#endif
#if CWDEBUG_ALLOC
        
        
        int saved_internal = _private_::set_library_call_on(LIBCWD_TSD);
#endif
#if LIBCWD_THREAD_SAFE
        LIBCWD_DISABLE_CANCEL;                  
        _private_::mutex_tct<_private_::set_ostream_instance>::lock();
        bool got_lock = debug_object.M_mutex;
        if (got_lock)
        {
          debug_object.M_mutex->lock();
          __libcwd_tsd.pthread_lock_interface_is_locked = true;
        }
        std::ostream* locked_os = os;
        _private_::mutex_tct<_private_::set_ostream_instance>::unlock();
        if (!got_lock && _private_::WST_multi_threaded)
        {
          static bool WST_second_time = false;  
          if (!WST_second_time)
          {
            WST_second_time = true;
            DoutFatal(
dc::core, 
"When using multiple threads, you must provide a locking mechanism for the debug output stream.  " 
                "You can pass a pointer to a mutex with `debug_ct::set_ostream' (see documentation/reference-manual/group__group__destination.html).");
          }
        }
#endif
#if LIBCWD_THREAD_SAFE
        if (debug_object.newlineless_tsd && debug_object.newlineless_tsd != &__libcwd_tsd)
        {
          if (debug_object.unfinished_oss)
          {
            if (debug_object.unfinished_oss != this)
            {
              locked_os->write("<unfinished>\n", 13);
              debug_object.unfinished_oss->unfinished_already_printed = true;
              debug_object.unfinished_oss->continued_needed = true;
            }
          }
          else
            locked_os->write("<no newline>\n", 13);
        }
        if (continued_needed && curlen > 0)
        {
          continued_needed = false;
          write_prefix_to(locked_os);
          locked_os->write("<continued> ", 12);
        }
#endif 
#if LIBCWD_THREAD_SAFE && CWDEBUG_ALLOC && __GNUC__ == 3
        debug_message_st* message = debug_object.queue_top;
        if (message)
        {
          
          debug_message_st* next_message;
          do
          {
            next_message = message->prev;
            locked_os->write(message->buf, message->curlen);
            __libcwd_tsd.internal = 1;
            free(message);
            __libcwd_tsd.internal = 0;
          }
          while ((message = next_message));
          debug_object.queue_top = debug_object.queue = NULL;
        }
        
        locked_os->write(msgbuf->buf, curlen);
#else 
#if LIBCWD_THREAD_SAFE
        locked_os->write(msgbuf, curlen);
#else 
        os->write(msgbuf, curlen);
#endif 
#endif 
#if LIBCWD_THREAD_SAFE
        if (request_unfinished && !unfinished_already_printed)
          locked_os->write("<unfinished>\n", 13);
#else
        if (request_unfinished)
          os->write("<unfinished>\n", 13);
#endif
        if (do_flush)
#if LIBCWD_THREAD_SAFE
          locked_os->flush();
#else
          os->flush();
#endif
#if LIBCWD_THREAD_SAFE
        unfinished_already_printed = ends_on_newline;
        if (ends_on_newline)
        {
          debug_object.unfinished_oss = NULL;
          debug_object.newlineless_tsd = NULL;
        }
        else if (curlen > 0)
        {
          debug_object.newlineless_tsd = &__libcwd_tsd;
          if (possible_nonewline_cf)
            debug_object.unfinished_oss = NULL;
          else
            debug_object.unfinished_oss = this;
        }
        if (got_lock)
        {
          __libcwd_tsd.pthread_lock_interface_is_locked = false;
          debug_object.M_mutex->unlock();
        }
        LIBCWD_ENABLE_CANCEL;
#endif 
#if CWDEBUG_ALLOC
        _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD);
#endif
#if LIBCWD_THREAD_SAFE && CWDEBUG_ALLOC && __GNUC__ == 3
      }
#endif
      if (free_msgbuf)
        free(msgbuf);
    }
 
    
    unsigned long const config_signature_lib_c = config_signature_header_c;
 
    
    unsigned long get_config_signature_lib_c()
    {
      return config_signature_lib_c;
    }
 
    
    void conf_check_failed()
    {
      DoutFatal(
dc::fatal, 
"check_configuration: This version of libcwd was compiled with a different configuration than is currently used in libcwd/config.h!");
 
    }
 
    void version_check_failed()
    {
      DoutFatal(
dc::fatal, 
"check_configuration: This version of libcwd does not match the version of libcwd/config.h! Are your paths correct? Did you recently upgrade libcwd and forgot to recompile this application?");
 
    }
 
 
    namespace {
      unsigned short int WST_max_len = 8;       
                                                
    } 
 
    namespace channels {
      namespace dc {
 
#ifndef HIDE_FROM_DOXYGEN
            ("DEBUG")
#endif
            ;
 
#ifndef HIDE_FROM_DOXYGEN
           ("NOTICE")
#endif
           ;
 
#ifndef HIDE_FROM_DOXYGEN
            ("SYSTEM")
#endif
            ;
 
#ifndef HIDE_FROM_DOXYGEN
            ("MALLOC")
#endif
            ;
 
#ifndef HIDE_FROM_DOXYGEN
            ("WARNING")
#endif
            ;
 
 
#ifndef HIDE_FROM_DOXYGEN
            (continued_maskbit)
#endif
            ;
 
#ifndef HIDE_FROM_DOXYGEN
            (finish_maskbit)
#endif
            ;
 
#ifndef HIDE_FROM_DOXYGEN
            ("FATAL", fatal_maskbit)
#endif
            ;
 
#ifndef HIDE_FROM_DOXYGEN
            ("COREDUMP", coredump_maskbit)
#endif
            ;
 
      } 
    } 
 
    channel_ct const channel_ct::off_channel
#ifndef HIDE_FROM_DOXYGEN
        ("!NEVER!", false)
#endif
        ;
 
#if CWDEBUG_LOCATION
    namespace cwbfd {
      extern bool ST_init(LIBCWD_TSD_PARAM);
    } 
#endif
 
    void ST_initialize_globals(LIBCWD_TSD_PARAM)
    {
      static bool ST_already_called;
      if (ST_already_called)
        return;
      ST_already_called = true;
#if CWDEBUG_ALLOC
      init_debugmalloc();
#endif
#if LIBCWD_THREAD_SAFE
      _private_::initialize_global_mutexes();
#endif
      _private_::process_environment_variables();
 
      
      
      
#if CWDEBUG_LOCATION
#endif
      
 
        DoutFatal(
dc::core, 
"Calling debug_ct::NS_init recursively from ST_initialize_globals");
 
 
      
#ifdef RLIMIT_CORE
      struct rlimit corelim;
      if (getrlimit(RLIMIT_CORE, &corelim))
      corelim.rlim_cur = corelim.rlim_max;
      if (corelim.rlim_max != RLIM_INFINITY && !_private_::suppress_startup_msgs)
      {
        debug_ct::OnOffState state;
        
        
        Dout(
dc::warning, 
"core size is limited (hard limit: " << (
unsigned long)(corelim.rlim_max / 1024) << 
" kb).  Core dumps might be truncated!");
 
      }
      if (setrlimit(RLIMIT_CORE, &corelim))
#else
      if (!_private_::suppress_startup_msgs)
      {
        debug_ct::OnOffState state;
      }
#endif
 
#if CWDEBUG_LOCATION
      cwbfd::ST_init(LIBCWD_TSD);               
#endif
#if CWDEBUG_DEBUG && !CWDEBUG_DEBUGOUTPUT
      
      (void)std::uncaught_exceptions();         
#endif
    }
 
    namespace _private_ {
 
#if !LIBCWD_THREAD_SAFE
      TSD_st __libcwd_tsd;
#endif
#if LIBCWD_THREAD_SAFE
      extern bool WST_is_NPTL;
#endif
 
      debug_channels_ct debug_channels;         
      debug_objects_ct debug_objects;           
 
      
      void debug_channels_ct::init(LIBCWD_TSD_PARAM)
      {
#if LIBCWD_THREAD_SAFE
        _private_::rwlock_tct<libcwd::_private_::debug_channels_instance>::initialize();
#endif
        DEBUG_CHANNELS_ACQUIRE_READ_LOCK;
        if (!WNS_debug_channels)                        
        {
          DEBUG_CHANNELS_ACQUIRE_READ2WRITE_LOCK;
          set_alloc_checking_off(LIBCWD_TSD);
          WNS_debug_channels = new debug_channels_ct::container_type;           
          set_alloc_checking_on(LIBCWD_TSD);
          DEBUG_CHANNELS_RELEASE_WRITE_LOCK;
        }
#if LIBCWD_THREAD_SAFE
        else
          DEBUG_CHANNELS_RELEASE_READ_LOCK;
#endif
      }
 
#if LIBCWD_THREAD_SAFE
      
      void debug_channels_ct::init_and_rdlock()
      {
        _private_::rwlock_tct<libcwd::_private_::debug_channels_instance>::initialize();
        DEBUG_CHANNELS_ACQUIRE_READ_LOCK;
        if (!WNS_debug_channels)                        
        {
          LIBCWD_TSD_DECLARATION;
          set_alloc_checking_off(LIBCWD_TSD);
          DEBUG_CHANNELS_ACQUIRE_READ2WRITE_LOCK;
          WNS_debug_channels = new debug_channels_ct::container_type;           
          DEBUG_CHANNELS_ACQUIRE_WRITE2READ_LOCK;
          set_alloc_checking_on(LIBCWD_TSD);
        }
      }
#endif
 
      
      void debug_objects_ct::init(LIBCWD_TSD_PARAM)
      {
#if LIBCWD_THREAD_SAFE
        _private_::rwlock_tct<libcwd::_private_::debug_objects_instance>::initialize();
#endif
        DEBUG_OBJECTS_ACQUIRE_READ_LOCK;
        if (!WNS_debug_objects)                         
        {
          DEBUGDEBUG_CERR( (char const*)"_debug_objects == NULL; initializing it" );
#if CWDEBUG_ALLOC
          
          init_debugmalloc();
#endif
          DEBUG_OBJECTS_ACQUIRE_READ2WRITE_LOCK;
          set_alloc_checking_off(LIBCWD_TSD);
          WNS_debug_objects = new debug_objects_ct::container_type;
          set_alloc_checking_on(LIBCWD_TSD);
          DEBUG_OBJECTS_RELEASE_WRITE_LOCK;
        }
#if LIBCWD_THREAD_SAFE
        else
          DEBUG_OBJECTS_RELEASE_READ_LOCK;
#endif
      }
 
#if LIBCWD_THREAD_SAFE
      
      void debug_objects_ct::init_and_rdlock()
      {
        _private_::rwlock_tct<libcwd::_private_::debug_objects_instance>::initialize();
        DEBUG_OBJECTS_ACQUIRE_READ_LOCK;
        if (!WNS_debug_objects)                         
        {
          DEBUGDEBUG_CERR( "_debug_objects == NULL; initializing it" );
#if CWDEBUG_ALLOC
          
          init_debugmalloc();
#endif
          LIBCWD_TSD_DECLARATION;
          set_alloc_checking_off(LIBCWD_TSD);
          DEBUG_OBJECTS_ACQUIRE_READ2WRITE_LOCK;
          WNS_debug_objects = new debug_objects_ct::container_type;
          DEBUG_OBJECTS_ACQUIRE_WRITE2READ_LOCK;
          set_alloc_checking_on(LIBCWD_TSD);
        }
      }
#endif
 
      
      void debug_objects_ct::ST_uninit()
      {
        if (WNS_debug_objects)
        {
          LIBCWD_TSD_DECLARATION;
          set_alloc_checking_off(LIBCWD_TSD);
          delete WNS_debug_objects;
          set_alloc_checking_on(LIBCWD_TSD);
          WNS_debug_objects = NULL;
        }
      }
 
    } 
 
#if CWDEBUG_DEBUG
    static long WST_debug_object_init_magic = 0;
 
    static void init_debug_object_init_magic()
    {
      struct timeval rn;
      gettimeofday(&rn, NULL);
      WST_debug_object_init_magic = rn.tv_usec;
      if (!WST_debug_object_init_magic)
        WST_debug_object_init_magic = 1;
      DEBUGDEBUG_CERR( "Set WST_debug_object_init_magic to " << WST_debug_object_init_magic );
    }
#endif
 
    class laf_ct {
    public:
      buffer_ct buffer;
        
 
      _private_::bufferstream_ct bufferstream;
        
 
        
 
      char const* label;
        
 
      int err;
        
 
    public:
      laf_ct(
control_flag_t m, 
char const* l, 
int e) : bufferstream(&buffer), mask(m), label(l), err(e) { }
 
    };
 
    static inline void write_whitespace_to(std::ostream& os, unsigned int size)
    {
      for (unsigned int i = size; i > 0; --i)
        os.put(' ');
    }
 
    namespace _private_ {
      static char WST_dummy_laf[sizeof(laf_ct)] __attribute__((__aligned__));
    } 
 
    {
#if LIBCWD_THREAD_SAFE
      
#if CWDEBUG_DEBUGT || CWDEBUG_ALLOC
      LIBCWD_TSD_DECLARATION;
#endif
      LIBCWD_DISABLE_CANCEL;
      if (!_private_::mutex_tct<_private_::kill_threads_instance>::try_lock())
      {
#if CWDEBUG_ALLOC
        __libcwd_tsd.internal = 0;      
        ++__libcwd_tsd.library_call;;   
                                        
#endif
        
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
        pthread_exit(PTHREAD_CANCELED);
      }
      
#endif
#if LIBCWD_THREAD_SAFE && CWDEBUG_DEBUG && defined(__linux)
      if (!_private_::WST_is_NPTL && pthread_self() == (pthread_t)2049)
      {
        ::write(1, "WARNING: Thread manager core dumped.  Going into infinite loop.  Please detach process with gdb.\n", 97);
        while(1) ;
      }
#endif
      raise(6);
#if LIBCWD_THREAD_SAFE
      LIBCWD_ENABLE_CANCEL;
#endif
      _Exit(6);         
    }
 
    size_t debug_string_ct::calculate_capacity(size_t size)
    {
      size_t capacity_plus_one = M_default_capacity + 1;                        
      while(
size >= capacity_plus_one)
 
        capacity_plus_one *= 2;
      return capacity_plus_one - 1;
    }
 
    void debug_string_ct::NS_internal_init(char const* str, size_t len)
    {
      M_default_capacity = min_capacity_c;
      M_str = (
char*)
malloc((M_default_capacity = M_capacity = calculate_capacity(len)) + 1);   
 
      strncpy(M_str, str, len);
      M_size = len;
      M_str[M_size] = 0;
    }
 
    
    void debug_string_ct::deinitialize()
    {
      free(M_str);
      M_str = NULL;
    }
 
    
    debug_string_ct::~debug_string_ct()
    {
#if CWDEBUG_DEBUG && LIBCWD_THREAD_SAFE
      LIBCWD_ASSERT(M_str == NULL);     
                                        
#endif
    }
 
    void debug_string_ct::internal_assign(char const* str, size_t len)
    {
      if (len > M_capacity || (M_capacity > M_default_capacity && len < M_default_capacity))
        M_str = (char*)realloc(M_str, (M_capacity = calculate_capacity(len)) + 1);
      strncpy(M_str, str, len);
      M_size = len;
      M_str[M_size] = 0;
    }
 
    void debug_string_ct::internal_append(char const* str, size_t len)
    {
      if (M_size + len > M_capacity || (M_capacity > M_default_capacity && M_size + len < M_default_capacity))
        M_str = (char*)realloc(M_str, (M_capacity = calculate_capacity(M_size + len)) + 1);
      strncpy(M_str + M_size, str, len);
      M_size += len;
      M_str[M_size] = 0;
    }
 
    void debug_string_ct::internal_prepend(char const* str, size_t len)
    {
      if (M_size + len > M_capacity || (M_capacity > M_default_capacity && M_size + len < M_default_capacity))
        M_str = (char*)realloc(M_str, (M_capacity = calculate_capacity(M_size + len)) + 1);
      memmove(M_str + len, M_str, M_size + 1);
      strncpy(M_str, str, len);
      M_size += len;
    }
 
    {
        return;
      LIBCWD_TSD_DECLARATION;
      set_alloc_checking_off(LIBCWD_TSD);
      M_default_capacity = min_capacity_c;
      M_str = (
char*)realloc(M_str, (M_default_capacity = M_capacity = calculate_capacity(
size)) + 1);
 
      set_alloc_checking_on(LIBCWD_TSD);
    }
 
    void debug_string_ct::internal_swallow(debug_string_ct const& ds)
    {
      
      free(M_str);
      M_str = ds.M_str;
      M_size = ds.M_size;
      M_capacity = ds.M_capacity;
      M_default_capacity = ds.M_default_capacity;
    }
 
    {
      LIBCWD_TSD_DECLARATION;
      debug_string_stack_element_ct* current_margin_stack = LIBCWD_TSD_MEMBER(M_margin_stack);
      set_alloc_checking_off(LIBCWD_TSD);
      void* new_debug_string = 
malloc(
sizeof(debug_string_stack_element_ct));
 
      LIBCWD_TSD_MEMBER(M_margin_stack) = 
new (new_debug_string) debug_string_stack_element_ct(LIBCWD_TSD_MEMBER(
margin));
 
      set_alloc_checking_on(LIBCWD_TSD);
      LIBCWD_TSD_MEMBER(M_margin_stack)->next = current_margin_stack;
    }
 
    {
      LIBCWD_TSD_DECLARATION;
      if (!LIBCWD_TSD_MEMBER(M_margin_stack))
        DoutFatal(
dc::core, 
"Calling `debug_ct::pop_margin' more often than `debug_ct::push_margin'.");
 
      debug_string_stack_element_ct* next = LIBCWD_TSD_MEMBER(M_margin_stack)->next;
      set_alloc_checking_off(LIBCWD_TSD);
      LIBCWD_TSD_MEMBER(
margin).internal_swallow(LIBCWD_TSD_MEMBER(M_margin_stack)->debug_string);
 
      free(LIBCWD_TSD_MEMBER(M_margin_stack));
      set_alloc_checking_on(LIBCWD_TSD);
      LIBCWD_TSD_MEMBER(M_margin_stack) = next;
    }
 
    {
      LIBCWD_TSD_DECLARATION;
      debug_string_stack_element_ct* current_marker_stack = LIBCWD_TSD_MEMBER(M_marker_stack);
      set_alloc_checking_off(LIBCWD_TSD);
      void* new_debug_string = 
malloc(
sizeof(debug_string_stack_element_ct));
 
      LIBCWD_TSD_MEMBER(M_marker_stack) = 
new (new_debug_string) debug_string_stack_element_ct(LIBCWD_TSD_MEMBER(
marker));
 
      set_alloc_checking_on(LIBCWD_TSD);
      LIBCWD_TSD_MEMBER(M_marker_stack)->next = current_marker_stack;
    }
 
    {
      LIBCWD_TSD_DECLARATION;
      if (!LIBCWD_TSD_MEMBER(M_marker_stack))
        DoutFatal(
dc::core, 
"Calling `debug_ct::pop_marker' more often than `debug_ct::push_marker'.");
 
      debug_string_stack_element_ct* next = LIBCWD_TSD_MEMBER(M_marker_stack)->next;
      set_alloc_checking_off(LIBCWD_TSD);
      LIBCWD_TSD_MEMBER(
marker).internal_swallow(LIBCWD_TSD_MEMBER(M_marker_stack)->debug_string);
 
      free(LIBCWD_TSD_MEMBER(M_marker_stack));
      set_alloc_checking_on(LIBCWD_TSD);
      LIBCWD_TSD_MEMBER(M_marker_stack) = next;
    }
 
    void debug_tsd_st::start(debug_ct& debug_object, channel_set_data_st& channel_set LIBCWD_COMMA_TSD_PARAM)
    {
#if CWDEBUG_DEBUG || CWDEBUG_DEBUGT
#if LIBCWD_THREAD_SAFE
      
      LIBCWD_ASSERT( tsd_initialized );
#else
      if (!tsd_initialized)
        init();
#endif
#endif
 
      if (NEED_SUPRESSION_OF_MALLOC_AND_BFD)
      {
#if CWDEBUG_LOCATION
#endif
      }
 
      
      
      
      if ((channel_set.mask & (continued_maskbit|finish_maskbit)))
      {
        current->err = errno;                           
        if (!(current->mask & continued_expected_maskbit))
        {
          std::ostream* target_os = (channel_set.mask & 
cerr_cf) ? &std::cerr : debug_object.real_os;
 
#if LIBCWD_THREAD_SAFE
          
          int res;
          struct timespec const t = { 0, 5000000 };
          int count = 0;
          do
          {
            if (!(res = debug_object.M_mutex->try_lock()))
              break;
            nanosleep(&t, NULL);
          }
          while(++count < 40);
#endif
          target_os->put('\n');
#if LIBCWD_THREAD_SAFE
          if (res == 0)
            debug_object.M_mutex->unlock();
#endif
          char const* channame = (channel_set.mask & finish_maskbit) ? "finish" : "continued";
#if CWDEBUG_LOCATION
              " without (first using) a matching `continued_cf'.");
#else
              "' without (first using) a matching `continued_cf'.");
#endif
        }
#if CWDEBUG_DEBUG
        
        LIBCWD_ASSERT( current != reinterpret_cast<laf_ct*>(_private_::WST_dummy_laf) );
#endif
        current->mask = channel_set.mask;               
        if ((current->mask & finish_maskbit))
          current->mask &= ~continued_expected_maskbit;
        return;
      }
 
      set_alloc_checking_off(LIBCWD_TSD);
 
      ++LIBCWD_DO_TSD_MEMBER_OFF(debug_object);
      DEBUGDEBUG_CERR( "Entering debug_ct::start(), _off became " << LIBCWD_DO_TSD_MEMBER_OFF(debug_object) );
 
      
      if ((current->mask & continued_cf_maskbit) && unfinished_expected)
      {
#if CWDEBUG_DEBUG
        
        
        LIBCWD_ASSERT( current != reinterpret_cast<laf_ct*>(_private_::WST_dummy_laf) );
#endif
        int saved_errno = errno;                                
        
        std::ostream* target_os = (channel_set.mask & 
cerr_cf) ? &std::cerr : debug_object.real_os;
 
        current->buffer.writeto(target_os LIBCWD_COMMA_TSD, debug_object,
            true,                       
            false                       
            COMMA_IFTHREADS(true)       
            COMMA_IFTHREADS(false));    
        
        current->buffer.restore_position();
        current_bufferstream->write("<continued> ", 12);        
        errno = saved_errno;
      }
 
      
      
      
      if (!start_expected)
      {
        
        laf_stack.push(current);
 
        
        indent += 4;
 
        
        
        channel_set.mask |= (current->mask & 
cerr_cf);
 
      }
 
      
      DEBUGDEBUG_CERR( "creating new laf_ct" );
      int saved_internal = _private_::set_library_call_on(LIBCWD_TSD);
      _private_::set_invisible_on(LIBCWD_TSD);
      current = new laf_ct(channel_set.mask, channel_set.label, errno);         
      _private_::set_invisible_off(LIBCWD_TSD);
      _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD);
      DEBUGDEBUG_CERR( "current = " << (void*)current );
      current_bufferstream = ¤t->bufferstream;
      DEBUGDEBUG_CERR( "laf_ct created" );
 
      
      start_expected = false;
 
      
      unfinished_expected = true;
 
      
      
      {
        current_bufferstream->write(margin.c_str(), margin.size());
        current_bufferstream->write(channel_set.label, WST_max_len);
        current_bufferstream->write(marker.c_str(), marker.size());
        write_whitespace_to(*current_bufferstream, indent);
      }
      {
          write_whitespace_to(*current_bufferstream, margin.size());
        else
          current_bufferstream->write(margin.c_str(), margin.size());
#if !CWDEBUG_DEBUGOUTPUT
#endif
        {
            write_whitespace_to(*current_bufferstream, WST_max_len);
          else
            current_bufferstream->write(channel_set.label, WST_max_len);
            write_whitespace_to(*current_bufferstream, marker.size());
          else
            current_bufferstream->write(marker.c_str(), marker.size());
          write_whitespace_to(*current_bufferstream, indent);
        }
      }
 
      if ((channel_set.mask & continued_cf_maskbit))
      {
        
        
        current->buffer.store_position();
      }
 
      --LIBCWD_DO_TSD_MEMBER_OFF(debug_object);
      DEBUGDEBUG_CERR( "Leaving debug_ct::start(), _off became " << LIBCWD_DO_TSD_MEMBER_OFF(debug_object) );
 
      set_alloc_checking_on(LIBCWD_TSD);
    }
 
    {
#if CWDEBUG_DEBUG
      LIBCWD_ASSERT( current != reinterpret_cast<laf_ct*>(_private_::WST_dummy_laf) );
#endif
      std::ostream* target_os = (current->mask & 
cerr_cf) ? &std::cerr : debug_object.real_os;
 
 
      set_alloc_checking_off(LIBCWD_TSD);
 
      if (NEED_SUPRESSION_OF_MALLOC_AND_BFD)
      {
#if CWDEBUG_LOCATION
#endif
      }
 
      
      if ((current->mask & continued_cf_maskbit) && !(current->mask & finish_maskbit))
      {
        
        current->mask |= continued_expected_maskbit;
        if ((current->mask & continued_maskbit))
          unfinished_expected = true;
        
        {
          
          
          
          
          current->buffer.writeto(target_os LIBCWD_COMMA_TSD, debug_object,
              false,                    
              true                      
              COMMA_IFTHREADS(false)    
              COMMA_IFTHREADS(false));  
        }
        set_alloc_checking_on(LIBCWD_TSD);
        return;
      }
 
      ++LIBCWD_DO_TSD_MEMBER_OFF(debug_object);
      DEBUGDEBUG_CERR( "Entering debug_ct::finish(), _off became " << LIBCWD_DO_TSD_MEMBER_OFF(debug_object) );
 
      
      {
        
#if CWDEBUG_ALLOC
        int saved_internal = _private_::set_library_call_on(LIBCWD_TSD);
#endif
#if !LIBCWD_THREAD_SAFE
        char const* error_text = strerror(current->err);
#else 
        char error_text_buf[512];
        char const* error_text;
#ifdef _GNU_SOURCE
        error_text = strerror_r(current->err, error_text_buf, sizeof(error_text_buf));
#else   
        if (strerror_r(current->err, error_text_buf, sizeof(error_text_buf)) == -1)
        {
          if (errno == ERANGE)
            error_text = "<libcwd: Oops, error text longer than 512 characters>";
          else
            error_text = "Unknown Error";
 
        }
        else
          error_text = error_text_buf;
#endif
#endif
#if CWDEBUG_ALLOC
        _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD);
#endif
        *current_bufferstream << ": " << strerrno(current->err) << " (" << error_text << ')';
      }
        current_bufferstream->put('\n');
 
      
      if (current->mask != 0)
      {
        if ((current->mask & (coredump_maskbit|fatal_maskbit)))
        {
          current->buffer.writeto(target_os LIBCWD_COMMA_TSD, debug_object,
              false,                    
              !__libcwd_tsd.recursive_fatal     
              COMMA_IFTHREADS(true));   
          __libcwd_tsd.recursive_fatal = true;
          if ((current->mask & coredump_maskbit))
          DEBUGDEBUG_CERR( "Deleting `current' " << (void*)current );
          int saved_internal = _private_::set_library_call_on(LIBCWD_TSD);
          _private_::set_invisible_on(LIBCWD_TSD);
          delete current;
          _private_::set_invisible_off(LIBCWD_TSD);
          _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD);
          DEBUGDEBUG_CERR( "Done deleting `current'" );
          set_alloc_checking_on(LIBCWD_TSD);
#if CWDEBUG_ALLOC
          if (__libcwd_tsd.internal)                    
            _private_::set_library_call_on(LIBCWD_TSD); 
#endif
#if LIBCWD_THREAD_SAFE
          LIBCWD_DISABLE_CANCEL;
          if (!_private_::mutex_tct<_private_::kill_threads_instance>::try_lock())
          {
            
            pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
            pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
            pthread_exit(PTHREAD_CANCELED);
          }
          _private_::rwlock_tct<_private_::threadlist_instance>::rdlock(true);
          
          for(_private_::threadlist_t::iterator thread_iter = _private_::threadlist->begin(); thread_iter != _private_::threadlist->end(); ++thread_iter)
            if (!pthread_equal((*thread_iter).tid, pthread_self())
#ifdef __linux
                && (_private_::WST_is_NPTL || (*thread_iter).tid != (pthread_t)1024)
#endif
                )
              pthread_cancel((*thread_iter).tid);
          _private_::rwlock_tct<_private_::threadlist_instance>::rdunlock();
          LIBCWD_ENABLE_CANCEL;
#endif
          _Exit(254);   
        }
        {
          current->buffer.writeto(target_os LIBCWD_COMMA_TSD, debug_object,
              false, debug_object.interactive COMMA_IFTHREADS(!(current->mask & 
nonewline_cf))
 
              COMMA_IFTHREADS(true));
#if LIBCWD_THREAD_SAFE
          debug_object.M_mutex->lock();
#endif
          *target_os << "(type return)";
          if (debug_object.interactive)
          {
            *target_os << std::flush;
            while(std::cin.get() != '\n') ;
          }
#if LIBCWD_THREAD_SAFE
          debug_object.M_mutex->unlock();
#endif
        }
        else
          current->buffer.writeto(target_os LIBCWD_COMMA_TSD, debug_object,
              COMMA_IFTHREADS(true));
      }
      else
        current->buffer.writeto(target_os LIBCWD_COMMA_TSD, debug_object,
            false, 
false COMMA_IFTHREADS(!(current->mask & 
nonewline_cf)) COMMA_IFTHREADS(
true));
 
 
      DEBUGDEBUG_CERR( "Deleting `current' " << (void*)current );
      int saved_internal = _private_::set_library_call_on(LIBCWD_TSD);
      _private_::set_invisible_on(LIBCWD_TSD);
      delete current;
      _private_::set_invisible_off(LIBCWD_TSD);
      _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD);
      DEBUGDEBUG_CERR( "Done deleting `current'" );
 
      if (start_expected)
      {
        
        indent -= 4;
        laf_stack.pop();
      }
 
      
      if (laf_stack.size())
      {
        current = laf_stack.top();
        DEBUGDEBUG_CERR( "current = " << (void*)current );
        current_bufferstream = ¤t->bufferstream;
      }
      else
      {
        current = reinterpret_cast<laf_ct*>(_private_::WST_dummy_laf);  
        DEBUGDEBUG_CERR( "current = " << (void*)current );
        current_bufferstream = NULL;
      }
 
      start_expected = true;
      unfinished_expected = false;
 
      --LIBCWD_DO_TSD_MEMBER_OFF(debug_object);
      DEBUGDEBUG_CERR( "Leaving debug_ct::finish(), _off became " << LIBCWD_DO_TSD_MEMBER_OFF(debug_object) );
 
      set_alloc_checking_on(LIBCWD_TSD);
    }
 
PRAGMA_DIAGNOSTIC_PUSH_IGNORE_infinite_recursion
    void debug_tsd_st::fatal_finish(debug_ct& debug_object, channel_set_data_st& channel_set LIBCWD_COMMA_TSD_PARAM)
    {
      finish(debug_object, channel_set LIBCWD_COMMA_TSD);
 
      DoutFatal( 
dc::core, 
"Don't use `DoutFatal' together with `continued_cf', use `Dout' instead.  (This message can also occur when using DoutFatal correctly but from the constructor of a global object)." );
 
      _Exit(1); 
    }
PRAGMA_DIAGNOSTIC_POP
 
#if LIBCWD_THREAD_SAFE
    int debug_ct::S_index_count = 0;
#endif
 
    bool debug_ct::NS_init(LIBCWD_TSD_PARAM)
    {
      if (NS_being_initialized)
        return false;
 
      ST_initialize_globals(LIBCWD_TSD);
                                        
                                        
 
      if (WNS_initialized)
        return true;
 
      NS_being_initialized = true;
 
#if LIBCWD_THREAD_SAFE
      M_mutex = NULL;
      unfinished_oss = NULL;
#endif
 
#if CWDEBUG_DEBUG
      if (!WST_debug_object_init_magic)
        init_debug_object_init_magic();
      init_magic = WST_debug_object_init_magic;
      DEBUGDEBUG_CERR( "Set init_magic to " << init_magic );
      DEBUGDEBUG_CERR( "Setting WNS_initialized to true" );
#endif
 
      LIBCWD_DEFER_CANCEL;
      _private_::debug_objects.init(LIBCWD_TSD);
      set_alloc_checking_off(LIBCWD_TSD);               
      DEBUG_OBJECTS_ACQUIRE_WRITE_LOCK;
      if (find(_private_::debug_objects.write_locked().begin(),
               _private_::debug_objects.write_locked().end(), this)
          == _private_::debug_objects.write_locked().end()) 
        _private_::debug_objects.write_locked().push_back(this);
      DEBUG_OBJECTS_RELEASE_WRITE_LOCK;
#if LIBCWD_THREAD_SAFE
      set_alloc_checking_on(LIBCWD_TSD);
      LIBCWD_RESTORE_CANCEL;
      set_alloc_checking_off(LIBCWD_TSD);               
#endif
      int saved_internal = _private_::set_library_call_on(LIBCWD_TSD);
      _private_::set_invisible_on(LIBCWD_TSD);
      _private_::set_invisible_off(LIBCWD_TSD);
      _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD);
#if LIBCWD_THREAD_SAFE
      WNS_index = S_index_count++;
#if CWDEBUG_DEBUGT
      LIBCWD_ASSERT( !_private_::WST_multi_threaded ); 
#endif
      LIBCWD_ASSERT( __libcwd_tsd.do_array[WNS_index] == NULL );
      debug_tsd_st& tsd(*(__libcwd_tsd.do_array[WNS_index] =  new debug_tsd_st));
#endif
      tsd.init();
      set_alloc_checking_on(LIBCWD_TSD);
 
#if CWDEBUG_DEBUGOUTPUT
      LIBCWD_TSD_MEMBER_OFF = -1;               
#else
      LIBCWD_TSD_MEMBER_OFF = 0;                
                                                
                                                
#endif
      DEBUGDEBUG_CERR( "debug_ct::NS_init(), _off set to " << LIBCWD_TSD_MEMBER_OFF );
 
      set_ostream(&std::cerr);                  
      interactive = true;                       
 
      NS_being_initialized = false;
      WNS_initialized = true;
      return true;                              
    }
 
    void debug_tsd_st::init()
    {
      DEBUGDEBUG_CERR( "Entering debug_tsd_st::init (this == " << (void*)this << ")");
#if CWDEBUG_DEBUGM
      LIBCWD_TSD_DECLARATION;
      LIBCWD_ASSERT( __libcwd_tsd.internal );
#endif
      start_expected = true;                    
      unfinished_expected = false;
 
      
      
      current = reinterpret_cast<laf_ct*>(_private_::WST_dummy_laf);
      DEBUGDEBUG_CERR( "current = " << (void*)current );
      current_bufferstream = NULL;
      laf_stack.init();
      continued_stack.init();
      margin.NS_internal_init("", 0);
      marker.NS_internal_init(": ", 2);         
#if CWDEBUG_DEBUGOUTPUT
      first_time = true;
#endif
      off_count = 0;
      M_margin_stack = NULL;
      M_marker_stack = NULL;
      indent = 0;
 
 
      tsd_initialized = true;
      DEBUGDEBUG_CERR( "Leaving debug_tsd_st::init (this == " << (void*)this <<
          "); &tsd_initialized == " << (void*)&tsd_initialized );
    }
 
#if LIBCWD_THREAD_SAFE
    namespace _private_ {
#if CWDEBUG_DEBUGT
      void debug_tsd_init(LIBCWD_TSD_PARAM_UNUSED)
#else
      void debug_tsd_init(LIBCWD_TSD_PARAM)
#endif
      {
          set_alloc_checking_off(LIBCWD_TSD);
          LIBCWD_ASSERT( __libcwd_tsd.do_array[(debugObject).WNS_index] == NULL );
          debug_tsd_st& tsd(*(__libcwd_tsd.do_array[(debugObject).WNS_index] =  new debug_tsd_st));
          tsd.init();
          set_alloc_checking_on(LIBCWD_TSD);
          LIBCWD_DO_TSD_MEMBER_OFF(debugObject) = 0;
        );
      }
    } 
#endif
 
    debug_tsd_st::~debug_tsd_st()
    {
#if LIBCWD_THREAD_SAFE
      
      
      
      
 
      
      margin.deinitialize();
      marker.deinitialize();
#endif
      if (!tsd_initialized)     
        return;
      
      if (continued_stack.size())
      if (laf_stack.size())
    }
 
    {
      channel_ct* tmp = NULL;
      LIBCWD_TSD_DECLARATION;
      LIBCWD_DEFER_CANCEL;
      _private_::debug_channels.init(LIBCWD_TSD);
      DEBUG_CHANNELS_ACQUIRE_READ_LOCK;
      for(_private_::debug_channels_ct::container_type::const_iterator i(_private_::debug_channels.read_locked().begin());
          i != _private_::debug_channels.read_locked().end(); ++i)
      {
        if (!strncasecmp(label, (*i)->get_label(), strlen(label)))
          tmp = (*i);
      }
      DEBUG_CHANNELS_RELEASE_READ_LOCK;
      LIBCWD_RESTORE_CANCEL;
      return tmp;
    }
 
    {
      LIBCWD_TSD_DECLARATION;
      if (LIBCWD_DO_TSD_MEMBER_OFF(debug_object) < 0)
      {
        LIBCWD_DEFER_CANCEL;
        _private_::debug_channels.init(LIBCWD_TSD);
        LIBCWD_RESTORE_CANCEL;
        LIBCWD_DEFER_CLEANUP_PUSH(&rwlock_tct<libcwd::_private_::debug_channels_instance>::cleanup, NULL);
        DEBUG_CHANNELS_ACQUIRE_READ_LOCK;
        for(_private_::debug_channels_ct::container_type::const_iterator i(_private_::debug_channels.read_locked().begin());
            i != _private_::debug_channels.read_locked().end(); ++i)
        {
          if (NEED_SUPRESSION_OF_MALLOC_AND_BFD)
          {
#if CWDEBUG_LOCATION
#endif
          }
          LibcwDoutStream.write(LIBCWD_DO_TSD_MEMBER(debug_object, margin).c_str(), LIBCWD_DO_TSD_MEMBER(debug_object, margin).size());
          LibcwDoutStream.write((*i)->get_label(), WST_max_len);
          if ((*i)->is_on(LIBCWD_TSD))
            LibcwDoutStream.write(": Enabled", 9);
          else
            LibcwDoutStream.write(": Disabled", 10);
          if (NEED_SUPRESSION_OF_MALLOC_AND_BFD)
          {
#if CWDEBUG_LOCATION
#endif
          }
          LibcwDoutScopeEnd;
        }
        DEBUG_CHANNELS_RELEASE_READ_LOCK;
        LIBCWD_CLEANUP_POP_RESTORE(false);
      }
    }
 
    void channel_ct::NS_initialize(char const* label LIBCWD_COMMA_TSD_PARAM, bool add_to_channel_list)
    {
      
 
      if (WNS_initialized)
        return;         
 
      DEBUGDEBUG_CERR( "Entering `channel_ct::NS_initialize(\"" << label << "\")'" );
 
      size_t label_len = strlen(label);
 
 
      LIBCWD_DEFER_CANCEL;
      _private_::debug_channels.init(LIBCWD_TSD);
 
      static _private_::debug_channels_ct hidden_channels;
      hidden_channels.init(LIBCWD_TSD);
 
      DEBUG_CHANNELS_ACQUIRE_WRITE_LOCK;
 
      set_alloc_checking_off(LIBCWD_TSD);       
      _private_::debug_channels_ct::container_type& channels(_private_::debug_channels.write_locked());
      for(_private_::debug_channels_ct::container_type::iterator i(channels.begin()); i != channels.end(); ++i)
        const_cast<char*>((*i)->get_label())[WST_max_len] = ' ';
      _private_::debug_channels_ct::container_type& channels_not_listed(hidden_channels.write_locked());
      for(_private_::debug_channels_ct::container_type::iterator i(channels_not_listed.begin());
          i != channels_not_listed.end(); ++i)
        const_cast<char*>((*i)->get_label())[WST_max_len] = ' ';
 
      
      
      
      
      
      
      
      
      
      
      
      if (label_len > WST_max_len)
        WST_max_len = label_len;
 
      for(_private_::debug_channels_ct::container_type::iterator i(channels.begin()); i != channels.end(); ++i)
        const_cast<char*>((*i)->get_label())[WST_max_len] = '\0';
      for(_private_::debug_channels_ct::container_type::iterator i(channels_not_listed.begin());
          i != channels_not_listed.end(); ++i)
        const_cast<char*>((*i)->get_label())[WST_max_len] = '\0';
      set_alloc_checking_on(LIBCWD_TSD);
 
#if LIBCWD_THREAD_SAFE
      
      
      static int next_index;
      WNS_index = ++next_index;         
 
      __libcwd_tsd.off_cnt_array[WNS_index] = 0;
#else
      off_cnt = 0;
#endif
 
PRAGMA_DIAGNOSTIC_PUSH_IGNORE_stringop_overflow
      strncpy(WNS_label, label, label_len);
PRAGMA_DIAGNOSTIC_POP
      WNS_label[WST_max_len] = '\0';
 
      set_alloc_checking_off(LIBCWD_TSD);       
      if (add_to_channel_list)
      {
        
        
        
        
        _private_::debug_channels_ct::container_type::iterator i(channels.begin());
        for(; i != channels.end(); ++i)
          if (strncmp((*i)->get_label(), WNS_label, WST_max_len) > 0)
            break;
        channels.insert(i, this);
      }
      else
        channels_not_listed.push_back(this);
      set_alloc_checking_on(LIBCWD_TSD);
 
      DEBUG_CHANNELS_RELEASE_WRITE_LOCK;
      LIBCWD_RESTORE_CANCEL;
 
      
      if (strncmp(WNS_label, "WARNING", label_len) == 0)
#if LIBCWD_THREAD_SAFE
        __libcwd_tsd.off_cnt_array[WNS_index] = -1;
#else
        off_cnt = -1;
#endif
 
      DEBUGDEBUG_CERR( "Leaving `channel_ct::NS_initialize(\"" << label << "\")" );
 
      WNS_initialized = true;
    }
 
    void fatal_channel_ct::NS_initialize(
char const* label, 
control_flag_t maskbit LIBCWD_COMMA_TSD_PARAM)
 
    {
       
 
      if (WNS_maskbit)
        return;         
 
      WNS_maskbit = maskbit;
 
      DEBUGDEBUG_CERR( "Entering `fatal_channel_ct::NS_initialize(\"" << label << "\")'" );
 
      size_t label_len = strlen(label);
 
 
      LIBCWD_DEFER_CANCEL;
      _private_::debug_channels.init(LIBCWD_TSD);
      DEBUG_CHANNELS_ACQUIRE_WRITE_LOCK;
 
      set_alloc_checking_off(LIBCWD_TSD);       
      _private_::debug_channels_ct::container_type& channels(_private_::debug_channels.write_locked());
      for(_private_::debug_channels_ct::container_type::iterator i(channels.begin()); i != channels.end(); ++i)
        const_cast<char*>((*i)->get_label())[WST_max_len] = ' ';
 
      
      if (label_len > WST_max_len)
        WST_max_len = label_len;
 
      for(_private_::debug_channels_ct::container_type::iterator i(channels.begin()); i != channels.end(); ++i)
        const_cast<char*>((*i)->get_label())[WST_max_len] = '\0';
      set_alloc_checking_on(LIBCWD_TSD);
 
PRAGMA_DIAGNOSTIC_PUSH_IGNORE_stringop_overflow
      strncpy(WNS_label, label, label_len);
PRAGMA_DIAGNOSTIC_POP
      WNS_label[WST_max_len] = '\0';
 
      DEBUG_CHANNELS_RELEASE_WRITE_LOCK;
      LIBCWD_RESTORE_CANCEL;
 
      DEBUGDEBUG_CERR( "Leaving `fatal_channel_ct::NS_initialize(\"" << label << "\")" );
    }
 
    {
      if (!WNS_maskbit)
        WNS_maskbit = maskbit;
    }
 
    char const always_channel_ct::label[
max_label_len_c + 1] = { 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 
'>', 0 };
 
 
    void channel_ct::off()
    {
#if LIBCWD_THREAD_SAFE
      LIBCWD_TSD_DECLARATION;
      __libcwd_tsd.off_cnt_array[WNS_index] += 1;
#else
      ++off_cnt;
#endif
    }
 
    void channel_ct::on()
    {
#if LIBCWD_THREAD_SAFE
      LIBCWD_TSD_DECLARATION;
      if (__libcwd_tsd.off_cnt_array[WNS_index] == -1)
#else
      if (off_cnt == -1)
#endif
#if LIBCWD_THREAD_SAFE
      __libcwd_tsd.off_cnt_array[WNS_index] -= 1;
#else
      --off_cnt;
#endif
    }
 
    
    
    
 
    namespace _private_ {
      void print_pop_error() {
        DoutFatal(
dc::core, 
"Using \"dc::finish\" without corresponding \"continued_cf\" or " 
            "calling the Dout(dc::finish, ...) more often than its corresponding "
            "Dout(dc::channel|continued_cf, ...).  Note that the wrong \"dc::finish\" doesn't "
            "have to be the one that we core dumped on, if two or more are nested.");
      }
    }
 
    {
#if CWDEBUG_DEBUG
      DEBUGDEBUG_CERR( "continued_cf detected" );
      if (!do_tsd_ptr || !do_tsd_ptr->tsd_initialized)
      {
        if (do_tsd_ptr)
          DEBUGDEBUG_CERR( "&do_tsd_ptr->tsd_initialized == " << (void*)&do_tsd_ptr->tsd_initialized );
        FATALDEBUGDEBUG_CERR( "Don't use DoutFatal together with continued_cf, use Dout instead." );
      }
#endif
      mask |= continued_cf_maskbit;
      if (!on)
      {
        ++(do_tsd_ptr->off_count);
        DEBUGDEBUG_CERR( "Channel is switched off. Increased off_count to " << do_tsd_ptr->off_count );
      }
      else
      {
        do_tsd_ptr->continued_stack.push(do_tsd_ptr->off_count);
        DEBUGDEBUG_CERR( "Channel is switched on. Pushed off_count (" << do_tsd_ptr->off_count << ") to stack (size now " <<
            do_tsd_ptr->continued_stack.size() << ") and set off_count to 0" );
        do_tsd_ptr->off_count = 0;
      }
      return *(reinterpret_cast<continued_channel_set_st*>(this));
    }
 
    continued_channel_set_st& channel_set_bootstrap_st::operator|(continued_channel_ct const& cdc)
    {
#if CWDEBUG_DEBUG
      if ((cdc.get_maskbit() & continued_maskbit))
        DEBUGDEBUG_CERR( "dc::continued detected" );
      else
        DEBUGDEBUG_CERR( "dc::finish detected" );
#endif
 
      if ((on = !do_tsd_ptr->off_count))
      {
        DEBUGDEBUG_CERR( "Channel is switched on (off_count is 0)" );
        do_tsd_ptr->current->mask |= cdc.get_maskbit();                                 
        mask = do_tsd_ptr->current->mask;
        label = do_tsd_ptr->current->label;
        if (cdc.get_maskbit() == finish_maskbit)
        {
          do_tsd_ptr->off_count = do_tsd_ptr->continued_stack.top();
          do_tsd_ptr->continued_stack.pop();
          DEBUGDEBUG_CERR( "Restoring off_count to " << do_tsd_ptr->off_count << ". Stack size now " << do_tsd_ptr->continued_stack.size() );
        }
      }
      else
      {
        DEBUGDEBUG_CERR( "Channel is switched off (off_count is " << do_tsd_ptr->off_count << ')' );
        if (cdc.get_maskbit() == finish_maskbit)
        {
          DEBUGDEBUG_CERR( "` decrementing off_count with 1" );
          --(do_tsd_ptr->off_count);
        }
      }
      return *reinterpret_cast<continued_channel_set_st*>(this);
    }
 
    namespace _private_ {
 
      void assert_fail(char const* expr, char const* file, int line, char const* function)
      {
#if CWDEBUG_DEBUG
        LIBCWD_TSD_DECLARATION;
        if (__libcwd_tsd.recursive_assert
#if CWDEBUG_DEBUGM
            || __libcwd_tsd.inside_malloc_or_free
#endif
            )
        {
          if (!__libcwd_tsd.recursive_assert
#if CWDEBUG_ALLOC
              && __libcwd_tsd.library_call < 6
#endif
              )
          {
#if CWDEBUG_ALLOC
            int saved_internal = 0;     
            bool is_internal = __libcwd_tsd.internal;
            if (is_internal)
              saved_internal = _private_::set_library_call_on(LIBCWD_TSD);      
            else
              ++__libcwd_tsd.library_call;
#endif
#if CWDEBUG_ALLOC
            if (is_internal)
              _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD);
            else
              --__libcwd_tsd.library_call;
#endif
          }
          set_alloc_checking_off(LIBCWD_TSD);
          FATALDEBUGDEBUG_CERR(file << ':' << line << ": " << function << ": Assertion `" << expr << "' failed.\n");
          set_alloc_checking_on(LIBCWD_TSD);
        }
        __libcwd_tsd.recursive_assert = true;
#if CWDEBUG_DEBUGT
        __libcwd_tsd.internal_debugging_code = true;
#endif
#endif
        DoutFatal(
dc::core, file << 
':' << line << 
": " << 
function << 
": Assertion `" << expr << 
"' failed.\n");
 
      }
 
    } 
 
    void debug_ct::force_on(debug_ct::OnOffState& state)
    {
      LIBCWD_TSD_DECLARATION;
#if CWDEBUG_DEBUG
      if (!NS_init(LIBCWD_TSD))
        DoutFatal(
dc::core, 
"Calling debug_ct::NS_init recursively from debug_ct::force_on");
 
#else
      (void)NS_init(LIBCWD_TSD);
#endif
      state._off = LIBCWD_TSD_MEMBER_OFF;
#if CWDEBUG_DEBUGOUTPUT
      state.first_time = LIBCWD_TSD_MEMBER(first_time);
#endif
      LIBCWD_TSD_MEMBER_OFF = -1;                                       
    }
 
    void debug_ct::restore(debug_ct::OnOffState const& state)
    {
      LIBCWD_TSD_DECLARATION;
#if CWDEBUG_DEBUGOUTPUT
      if (state.first_time != LIBCWD_TSD_MEMBER(first_time))            
#endif
      if (LIBCWD_TSD_MEMBER_OFF != -1)
      LIBCWD_TSD_MEMBER_OFF = state._off;                               
    }
 
    void channel_ct::force_on(channel_ct::OnOffState& state, char const* label)
    {
      LIBCWD_TSD_DECLARATION;
      NS_initialize(label LIBCWD_COMMA_TSD, true);
#if LIBCWD_THREAD_SAFE
      int& off_cnt(__libcwd_tsd.off_cnt_array[WNS_index]);
#endif
      state.off_cnt = off_cnt;
      off_cnt = -1;                                     
    }
 
    void channel_ct::restore(channel_ct::OnOffState const& state)
    {
#if LIBCWD_THREAD_SAFE
      LIBCWD_TSD_DECLARATION;
      int& off_cnt(__libcwd_tsd.off_cnt_array[WNS_index]);
#endif
      if (off_cnt != -1)
      off_cnt = state.off_cnt;                          
    }
 
#if LIBCWD_THREAD_SAFE
template<>
  void debug_ct::set_ostream(std::ostream* os, pthread_mutex_t* mutex)
  {
    LIBCWD_TSD_DECLARATION;
    _private_::set_alloc_checking_off(LIBCWD_TSD);
    _private_::lock_interface_base_ct* new_mutex = new _private_::pthread_lock_interface_ct(mutex);     
    _private_::set_alloc_checking_on(LIBCWD_TSD);
    LIBCWD_DEFER_CANCEL;
    _private_::mutex_tct<_private_::set_ostream_instance>::lock();
    _private_::lock_interface_base_ct* old_mutex = M_mutex;
    if (old_mutex)
      old_mutex->lock();                
    M_mutex = new_mutex;
    if (old_mutex)
    {
      old_mutex->unlock();
      _private_::set_alloc_checking_off(LIBCWD_TSD);
      delete old_mutex;
      _private_::set_alloc_checking_on(LIBCWD_TSD);
    }
    private_set_ostream(os);
    _private_::mutex_tct<_private_::set_ostream_instance>::unlock();
    LIBCWD_RESTORE_CANCEL;
  }
#endif 
 
void debug_ct::set_ostream(std::ostream* os)
{
#if LIBCWD_THREAD_SAFE
  if (_private_::WST_multi_threaded)
#if CWDEBUG_LOCATION
    Dout(
dc::warning, location_ct((
char*)__builtin_return_address(0) + 
builtin_return_address_offset) << 
": You should passing a locking mechanism to `set_ostream' for the ostream (see documentation/reference-manual/group__group__destination.html)");
 
#else
    DoutFatal(
dc::core, 
"You must pass a locking mechanism to `set_ostream' for the ostream (see documentation/reference-manual/group__group__destination.html)");
 
#endif
#if CWDEBUG_DEBUGT
  LIBCWD_TSD_DECLARATION;
#endif
  LIBCWD_DEFER_CANCEL;
  _private_::mutex_tct<_private_::set_ostream_instance>::lock();
#endif
  private_set_ostream(os);
#if LIBCWD_THREAD_SAFE
  _private_::mutex_tct<_private_::set_ostream_instance>::unlock();
  LIBCWD_RESTORE_CANCEL;
#endif
}
 
} 
 
extern "C" char const* const __libcwd_version = VERSION;
 
 
  namespace _private_ {
    extern void demangle_symbol(
char const* in, _private_::internal_string& out);
 
  } 
} 
void off()
Turn this channel off.
Definition: debug.cc:1780
 
void on()
Cancel one call to ‘off()’.
Definition: debug.cc:1795
 
size_t size() const
The size of the string.
Definition: class_debug_string.inl:89
 
void reserve(size_t)
Reserve memory for the string in advance.
Definition: debug.cc:905
 
This is the main header file of libcwd.
 
#define Dout(cntrl, data)
Macro for writing debug output.
Definition: debug.h:154
 
#define Debug(STATEMENTS...)
Encapsulation macro for general debugging code.
Definition: debug.h:124
 
void core_dump()
Dump core of current thread.
Definition: debug.cc:806
 
control_flag_t const blank_marker_cf
Replace marker by white space.
Definition: control_flag.h:50
 
control_flag_t const noprefix_cf
Omit margin, label, marker and indentation.
Definition: control_flag.h:38
 
control_flag_t const nolabel_cf
Omit label, marker and indentation.
Definition: control_flag.h:41
 
unsigned int control_flag_t
Definition: control_flag.h:31
 
control_flag_t const nonewline_cf
Omit the default new line at the end.
Definition: control_flag.h:35
 
control_flag_t const blank_margin_cf
Replace margin by white space.
Definition: control_flag.h:44
 
continued_cf_nt
continued_cf has its own type for overloading purposes.
Definition: control_flag.h:75
 
control_flag_t const error_cf
Append error string according to errno.
Definition: control_flag.h:62
 
control_flag_t const cerr_cf
Force output to be written to cerr.
Definition: control_flag.h:53
 
control_flag_t const blank_label_cf
Replace label by white space.
Definition: control_flag.h:47
 
control_flag_t const wait_cf
If interactive, wait till return is pressed.
Definition: control_flag.h:59
 
control_flag_t const flush_cf
Flush ostream after writing this output.
Definition: control_flag.h:56
 
channel_ct system
Definition: debug.cc:467
 
channel_ct malloc
Definition: debug.cc:474
 
channel_ct bfd
Definition: bfd.cc:92
 
continued_channel_ct finish
Definition: debug.cc:517
 
fatal_channel_ct fatal
Definition: debug.cc:527
 
channel_ct notice
Definition: debug.cc:460
 
continued_channel_ct continued
Definition: debug.cc:506
 
channel_ct debug
Definition: debug.cc:453
 
always_channel_ct always
Definition: debug.cc:495
 
fatal_channel_ct core
Definition: debug.cc:537
 
channel_ct warning
Definition: debug.cc:485
 
void demangle_symbol(char const *input, std::string &output)
Demangle mangled symbol name input and write the result to string output.
Definition: demangle3.cc:825
 
std::ostream * get_ostream() const
Get the ostream device as set with set_ostream().
Definition: class_debug.inl:128
 
#define DoutFatal(cntrl, data)
Macro for writing fatal debug output to the default debug object libcw_do .
Definition: debug.h:164
 
channel_ct * find_channel(char const *label)
Find debug channel with label label.
Definition: debug.cc:1528
 
#define ForAllDebugObjects(STATEMENT...)
Looping over all debug objects.
Definition: debug.h:209
 
void list_channels_on(debug_ct &debug_object)
List all debug channels to a given debug object.
Definition: debug.cc:1575
 
namespace for libcwd.
Definition: debug.cc:87
 
debug_ct libcw_do
The default debug object.
Definition: debug.cc:429
 
int const builtin_return_address_offset
Offset to __builtin_return_address() needed to get the correct line number from location_ct.
Definition: sys.h:39
 
unsigned short const max_label_len_c
The maximum number of characters that are allowed in a debug channel label.
Definition: max_label_len.h:24
 
   «