ManaPlus
Public Member Functions | Private Member Functions | Private Attributes
debug_new_recorder Class Reference

#include <debug_new.h>

Public Member Functions

 debug_new_recorder (const char *file, int line)
 
template<class _Tp >
_Tp * operator->* (_Tp *ptr)
 

Private Member Functions

void _M_process (void *ptr)
 
 debug_new_recorder (const debug_new_recorder &)
 
debug_new_recorderoperator= (const debug_new_recorder &)
 

Private Attributes

const char * _M_file
 
const int _M_line
 

Detailed Description

Recorder class to remember the call context.

The idea comes from Greg Herlihy's post in comp.lang.c++.moderated.

Definition at line 164 of file debug_new.h.

Constructor & Destructor Documentation

◆ debug_new_recorder() [1/2]

debug_new_recorder::debug_new_recorder ( const char *  file,
int  line 
)
inline

Constructor to remember the call context. The information will be used in debug_new_recorder::operator->*.

Definition at line 174 of file debug_new.h.

175  : _M_file(file), _M_line(line) {}
const char * _M_file
Definition: debug_new.h:166
const int _M_line
Definition: debug_new.h:167

◆ debug_new_recorder() [2/2]

debug_new_recorder::debug_new_recorder ( const debug_new_recorder )
private

Member Function Documentation

◆ _M_process()

void debug_new_recorder::_M_process ( void *  usr_ptr)
private

Processes the allocated memory and inserts file/line informatin. It will only be done when it can ensure the memory is allocated by one of our operator new variants.

Parameters
usr_ptrpointer returned by a new-expression

Definition at line 904 of file debug_new.cpp.

905 {
906  if (usr_ptr == _NULLPTR)
907  return;
908 
909  // In an expression `new NonPODType[size]', the pointer returned is
910  // not the pointer returned by operator new[], but offset by size_t
911  // to leave room for the size. It needs to be compensated here.
912  size_t offset = (char*)usr_ptr - (char*)_NULLPTR;
913  if (offset % PLATFORM_MEM_ALIGNMENT != 0) {
914  offset -= sizeof(size_t);
915  if (offset % PLATFORM_MEM_ALIGNMENT != 0) {
917  fprintf(new_output_fp,
918  "warning: memory unaligned; skipping processing (%s:%d)\n",
919  _M_file, _M_line);
920  return;
921  }
922  usr_ptr = (char*)usr_ptr - sizeof(size_t);
923  }
924 
925  new_ptr_list_t* ptr =
926  (new_ptr_list_t*)((char*)usr_ptr - ALIGNED_LIST_ITEM_SIZE);
927  if (ptr->magic != DEBUG_NEW_MAGIC || ptr->line != 0)
928  {
930  fprintf(new_output_fp,
931  "warning: debug_new used with placement new (%s:%d)\n",
932  _M_file, _M_line);
933  return;
934  }
935  if (new_verbose_flag) {
937  fprintf(new_output_fp,
938  "info: pointer %p allocated from %s:%d\n",
939  usr_ptr, _M_file, _M_line);
940  }
941 #if _DEBUG_NEW_FILENAME_LEN == 0
942  ptr->file = _M_file;
943 #else
944  strncpy(ptr->file, _M_file, _DEBUG_NEW_FILENAME_LEN - 1)
945  [_DEBUG_NEW_FILENAME_LEN - 1] = '\0';
946 #endif
947  ptr->line = _M_line;
948 #if _DEBUG_NEW_REMEMBER_STACK_TRACE == 2
949  free(ptr->stacktrace);
950  ptr->stacktrace = _NULLPTR;
951 #endif
952 }
#define _NULLPTR
Definition: c++11.h:327
static fast_mutex new_output_lock
Definition: debug_new.cpp:322
bool new_verbose_flag
Definition: debug_new.cpp:338
static const unsigned DEBUG_NEW_MAGIC
Definition: debug_new.cpp:285
#define _DEBUG_NEW_FILENAME_LEN
static const int ALIGNED_LIST_ITEM_SIZE
Definition: debug_new.cpp:290
FILE * new_output_fp
Definition: debug_new.cpp:345
char file[44]
File name of the caller.
Definition: debug_new.cpp:270
unsigned magic
Magic number for error detection.
Definition: debug_new.cpp:279
unsigned line
Line number of the caller; or 0.
Definition: debug_new.cpp:274

References _DEBUG_NEW_FILENAME_LEN, _M_file, _M_line, _NULLPTR, ALIGNED_LIST_ITEM_SIZE, DEBUG_NEW_MAGIC, new_ptr_list_t::file, new_ptr_list_t::line, new_ptr_list_t::magic, new_output_fp, new_output_lock, and new_verbose_flag.

Referenced by operator->*().

◆ operator->*()

template<class _Tp >
_Tp* debug_new_recorder::operator->* ( _Tp *  ptr)
inline

Operator to write the context information to memory. operator->* is chosen because it has the right precedence, it is rarely used, and it looks good: so people can tell the special usage more quickly.

Definition at line 182 of file debug_new.h.

183  { _M_process(ptr); return ptr; }
void _M_process(void *ptr)
Definition: debug_new.cpp:904

References _M_process().

◆ operator=()

debug_new_recorder& debug_new_recorder::operator= ( const debug_new_recorder )
private

Field Documentation

◆ _M_file

const char* debug_new_recorder::_M_file
private

Definition at line 166 of file debug_new.h.

Referenced by _M_process().

◆ _M_line

const int debug_new_recorder::_M_line
private

Definition at line 167 of file debug_new.h.

Referenced by _M_process().


The documentation for this class was generated from the following files: