73 #if !_FAST_MUTEX_CHECK_INITIALIZATION && !defined(_NOTHREADS) 74 #error "_FAST_MUTEX_CHECK_INITIALIZATION not set: check_leaks may not work" 83 #ifndef _DEBUG_NEW_ALIGNMENT 84 #define _DEBUG_NEW_ALIGNMENT 16 94 #ifndef _DEBUG_NEW_CALLER_ADDRESS 96 #define _DEBUG_NEW_CALLER_ADDRESS __builtin_return_address(0) 98 #define _DEBUG_NEW_CALLER_ADDRESS NULL 111 #ifndef _DEBUG_NEW_ERROR_ACTION 112 #ifndef _DEBUG_NEW_ERROR_CRASH 113 #define _DEBUG_NEW_ERROR_ACTION abort() 115 #define _DEBUG_NEW_ERROR_ACTION do { *((char*)0) = 0; abort(); } while (0) 131 #ifndef _DEBUG_NEW_FILENAME_LEN 132 #define _DEBUG_NEW_FILENAME_LEN 20 142 #ifndef _DEBUG_NEW_HASHTABLESIZE 143 #define _DEBUG_NEW_HASHTABLESIZE 16384 152 #ifndef _DEBUG_NEW_HASH 153 #define _DEBUG_NEW_HASH(p) (((size_t)(p) >> 8) % _DEBUG_NEW_HASHTABLESIZE) 168 #ifndef _DEBUG_NEW_PROGNAME 169 #define _DEBUG_NEW_PROGNAME NULL 180 #ifndef _DEBUG_NEW_USE_ADDR2LINE 182 #define _DEBUG_NEW_USE_ADDR2LINE 1 184 #define _DEBUG_NEW_USE_ADDR2LINE 0 189 #pragma warning(disable: 4073) // #pragma init_seg(lib) used 190 #pragma warning(disable: 4290) // C++ exception specification ignored 191 #pragma init_seg(lib) 194 #undef _DEBUG_NEW_EMULATE_MALLOC 195 #undef _DEBUG_NEW_REDEFINE_NEW 200 #define _DEBUG_NEW_REDEFINE_NEW 0 207 (((s) + _DEBUG_NEW_ALIGNMENT - 1) & ~(_DEBUG_NEW_ALIGNMENT - 1)) 220 #if _DEBUG_NEW_FILENAME_LEN == 0 255 static size_t total_mem_alloc = 0;
285 #if _DEBUG_NEW_USE_ADDR2LINE 295 static bool print_position_from_addr(
const void*
addr)
297 static const void* last_addr = NULL;
298 static char last_info[256] =
"";
299 if (addr == last_addr)
301 if (last_info[0] ==
'\0')
303 fprintf(new_output_fp,
"%s", last_info);
308 const char addr2line_cmd[] =
"addr2line -e ";
309 #if defined(__CYGWIN__) || defined(_WIN32) 310 const int exeext_len = 4;
312 const int exeext_len = 0;
314 #if !defined(__CYGWIN__) && defined(__unix__) 315 const char ignore_err[] =
" 2>/dev/null";
316 #elif defined(__CYGWIN__) || \ 317 (defined(_WIN32) && defined(WINVER) && WINVER >= 0x0500) 318 const char ignore_err[] =
" 2>nul";
320 const char ignore_err[] =
"";
322 char*
cmd = (
char*)alloca(
strlen(new_progname)
324 +
sizeof addr2line_cmd - 1
325 +
sizeof ignore_err - 1
328 strcpy(cmd, addr2line_cmd);
329 strcpy(cmd +
sizeof addr2line_cmd - 1, new_progname);
331 #if defined(__CYGWIN__) || defined(_WIN32) 333 || (strcmp(cmd + len - 4,
".exe") != 0 &&
334 strcmp(cmd + len - 4,
".EXE") != 0))
336 strcpy(cmd + len,
".exe");
340 sprintf(cmd + len,
" %p%s", addr, ignore_err);
341 FILE* fp = popen(cmd,
"r");
344 char buffer[
sizeof last_info] =
"";
346 if (fgets(buffer,
sizeof buffer, fp))
349 if (buffer[len - 1] ==
'\n')
350 buffer[--len] =
'\0';
352 int res = pclose(fp);
357 if (res == 0 && len > 0)
360 if (buffer[len - 1] ==
'0' && buffer[len - 2] ==
':')
364 fprintf(new_output_fp,
"%s", buffer);
365 strcpy(last_info, buffer);
380 static bool print_position_from_addr(
const void*)
384 #endif // _DEBUG_NEW_USE_ADDR2LINE 397 static void print_position(
const void* ptr,
int line)
402 fprintf(new_output_fp,
"%s:%d", (
const char*)ptr, line);
404 else if (ptr != NULL)
406 if (!print_position_from_addr(ptr))
407 fprintf(new_output_fp,
"%p", ptr);
411 fprintf(new_output_fp,
"<Unknown>");
425 static new_ptr_list_t** search_pointer(
void* pointer,
size_t hash_index)
434 raw_ptr = &(*raw_ptr)->
next;
453 int array_mode_mismatch = array_mode ^ ((ptr->
line & INT_MIN) != 0);
454 if (array_mode_mismatch)
458 msg =
"delete[] after new";
460 msg =
"delete after new[]";
462 fprintf(new_output_fp,
463 "%s: pointer %p (size %u)\n\tat ",
466 (
unsigned) ptr->
size);
467 print_position(addr, 0);
468 fprintf(new_output_fp,
"\n\toriginally allocated at ");
469 if ((ptr->
line & ~INT_MIN) != 0)
470 print_position(ptr->
file, ptr->
line);
472 print_position(ptr->
addr, ptr->
line);
473 fprintf(new_output_fp,
"\n");
474 fflush(new_output_fp);
477 total_mem_alloc -= ptr->
size;
478 if (new_verbose_flag)
481 fprintf(new_output_fp,
482 "delete: freeing %p (size %u, %u bytes still allocated)\n",
484 (
unsigned) ptr->
size, (
unsigned) total_mem_alloc);
486 *raw_ptr = ptr->
next;
509 fprintf(new_output_fp,
510 "Leaked object at %p (size %u, ",
512 (
unsigned) ptr->
size);
513 if ((ptr->
line & ~INT_MIN) != 0)
514 print_position(ptr->
file, ptr->
line);
516 print_position(ptr->
addr, ptr->
line);
517 fprintf(new_output_fp,
")\n");
527 assert((line & INT_MIN) == 0);
529 Alignment_must_be_power_of_two);
535 fprintf(new_output_fp,
536 "new: out of memory when allocating %u bytes\n",
538 fflush(new_output_fp);
541 void* pointer = (
char*)ptr + aligned_list_item_size;
547 if ((
size_t)pointer == 0xfefefefecdcdcdcdULL)
549 static int counter = 0;
551 std::cerr <<
"--> MEMORY LEAK CATCH POINT, counter = " << counter <<
"\n";
560 #if _DEBUG_NEW_FILENAME_LEN == 0 567 ptr->
addr = (
void*)file;
573 ptr->
next = new_ptr_list[hash_index];
574 new_ptr_list[hash_index] = ptr;
576 if (new_verbose_flag)
579 fprintf(new_output_fp,
580 "new: allocated %p (size %u, ",
581 pointer, (
unsigned) size);
583 print_position(ptr->
file, ptr->
line);
585 print_position(ptr->
addr, ptr->
line);
586 fprintf(new_output_fp,
")\n");
588 total_mem_alloc +=
size;
597 assert((ptr->
line & INT_MIN) == 0);
598 ptr->
line |= INT_MIN;
602 void*
operator new(
size_t size)
throw(std::bad_alloc)
607 void*
operator new[](
size_t size)
throw(std::bad_alloc)
612 #if !defined(__BORLANDC__) || __BORLANDC__ > 0x551 613 void*
operator new(
size_t size,
const std::nothrow_t&)
throw()
618 void*
operator new[](
size_t size,
const std::nothrow_t&)
throw()
624 void operator delete(
void* pointer)
throw()
634 fprintf(new_output_fp,
"delete: invalid pointer %p at ", pointer);
636 fprintf(new_output_fp,
"\n");
637 fflush(new_output_fp);
643 void operator delete[](
void* pointer)
throw()
653 fprintf(new_output_fp,
"delete[]: invalid pointer %p at ", pointer);
655 fprintf(new_output_fp,
"\n");
656 fflush(new_output_fp);
662 #if HAS_PLACEMENT_DELETE 663 void operator delete(
void* pointer,
const char*
file,
int line)
throw()
665 if (new_verbose_flag)
668 fprintf(new_output_fp,
669 "info: exception thrown on initializing object at %p (",
671 print_position(file, line);
672 fprintf(new_output_fp,
")\n");
674 operator delete(pointer);
677 void operator delete[](
void* pointer,
const char*
file,
int line)
throw()
679 if (new_verbose_flag)
682 fprintf(new_output_fp,
683 "info: exception thrown on initializing objects at %p (",
685 print_position(file, line);
686 fprintf(new_output_fp,
")\n");
688 operator delete[](pointer);
691 void operator delete(
void* pointer,
const std::nothrow_t&)
throw()
696 void operator delete[](
void* pointer,
const std::nothrow_t&)
throw()
700 #endif // HAS_PLACEMENT_DELETE 702 int __debug_new_counter::_count = 0;
718 if (--_count == 0 && new_autocheck_flag)
721 new_verbose_flag =
true;
722 #if defined(__GNUC__) && __GNUC__ >= 3 723 if (!getenv(
"GLIBCPP_FORCE_NEW") && !getenv(
"GLIBCXX_FORCE_NEW"))
724 fprintf(new_output_fp,
725 "*** WARNING: GCC 3 or later is detected, please make sure the\n" 726 " environment variable GLIBCPP_FORCE_NEW (GCC 3.2 and 3.3) or\n" 727 " GLIBCXX_FORCE_NEW (GCC 3.4 and later) is defined. Check the\n" 728 " README file for details.\n");
#define STATIC_ASSERT(_Expr, _Msg)
#define _DEBUG_NEW_ALIGNMENT
Part of Wu Yongwei's new/delete debug memory leak detector.
#define _DEBUG_NEW_PROGNAME
Part of Wu Yongwei's new/delete debug memory leak detector.
#define _DEBUG_NEW_HASHTABLESIZE
#define _DEBUG_NEW_CALLER_ADDRESS
#define _DEBUG_NEW_FILENAME_LEN
#define _DEBUG_NEW_HASH(p)
char file[_DEBUG_NEW_FILENAME_LEN]
const char * new_progname
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
const int aligned_list_item_size
#define _DEBUG_NEW_ERROR_ACTION
Part of Wu Yongwei's new/delete debug memory leak detector.