OLD | NEW |
1 // Copyright (c) 2005, Google Inc. | 1 // Copyright (c) 2005, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 #include "google/tcmalloc.h" | 93 #include "google/tcmalloc.h" |
94 #include "thread_cache.h" | 94 #include "thread_cache.h" |
95 #include "tests/testutil.h" | 95 #include "tests/testutil.h" |
96 | 96 |
97 // Windows doesn't define pvalloc and a few other obsolete unix | 97 // Windows doesn't define pvalloc and a few other obsolete unix |
98 // functions; nor does it define posix_memalign (which is not obsolete). | 98 // functions; nor does it define posix_memalign (which is not obsolete). |
99 #if defined(_MSC_VER) || defined(__MINGW32__) | 99 #if defined(_MSC_VER) || defined(__MINGW32__) |
100 # define cfree free // don't bother to try to test these obsolete fns | 100 # define cfree free // don't bother to try to test these obsolete fns |
101 # define valloc malloc | 101 # define valloc malloc |
102 # define pvalloc malloc | 102 # define pvalloc malloc |
103 # ifdef PERFTOOLS_NO_ALIGNED_MALLOC | 103 // I'd like to map posix_memalign to _aligned_malloc, but _aligned_malloc |
104 # define _aligned_malloc(size, alignment) malloc(size) | 104 // must be paired with _aligned_free (not normal free), which is too |
105 # else | 105 // invasive a change to how we allocate memory here. So just bail |
106 # include <malloc.h> // for _aligned_malloc | |
107 # endif | |
108 # define memalign(alignment, size) _aligned_malloc(size, alignment) | |
109 // Assume if we fail, it's because of out-of-memory. | |
110 // Note, this isn't a perfect analogue: we don't enforce constraints on "align" | |
111 # include <errno.h> | 106 # include <errno.h> |
112 # define posix_memalign(pptr, align, size) \ | 107 # define memalign(alignment, size) malloc(size) |
113 ((*(pptr)=_aligned_malloc(size, align)) ? 0 : ENOMEM) | 108 # define posix_memalign(pptr, align, size) ((*(pptr)=malloc(size)) ? 0 : ENOMEM) |
114 #endif | 109 #endif |
115 | 110 |
116 // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old | 111 // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old |
117 // form of the name instead. | 112 // form of the name instead. |
118 #ifndef MAP_ANONYMOUS | 113 #ifndef MAP_ANONYMOUS |
119 # define MAP_ANONYMOUS MAP_ANON | 114 # define MAP_ANONYMOUS MAP_ANON |
120 #endif | 115 #endif |
121 | 116 |
122 #define LOGSTREAM stdout | 117 #define LOGSTREAM stdout |
123 | 118 |
124 using std::vector; | 119 using std::vector; |
125 using std::string; | 120 using std::string; |
126 | 121 |
127 DECLARE_double(tcmalloc_release_rate); | 122 DECLARE_double(tcmalloc_release_rate); |
128 DECLARE_int32(max_free_queue_size); // in debugallocation.cc | 123 DECLARE_int32(max_free_queue_size); // in debugallocation.cc |
| 124 DECLARE_int64(tcmalloc_sample_parameter); |
129 | 125 |
130 namespace testing { | 126 namespace testing { |
131 | 127 |
132 static const int FLAGS_numtests = 50000; | 128 static const int FLAGS_numtests = 50000; |
133 static const int FLAGS_log_every_n_tests = 50000; // log exactly once | 129 static const int FLAGS_log_every_n_tests = 50000; // log exactly once |
134 | 130 |
135 // Testing parameters | 131 // Testing parameters |
136 static const int FLAGS_lgmaxsize = 16; // lg() of the max size object to alloc | 132 static const int FLAGS_lgmaxsize = 16; // lg() of the max size object to alloc |
137 static const int FLAGS_numthreads = 10; // Number of threads | 133 static const int FLAGS_numthreads = 10; // Number of threads |
138 static const int FLAGS_threadmb = 4; // Max memory size allocated by thread | 134 static const int FLAGS_threadmb = 4; // Max memory size allocated by thread |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 CHECK(p[i] == '\0'); | 548 CHECK(p[i] == '\0'); |
553 } | 549 } |
554 free(p); | 550 free(p); |
555 } | 551 } |
556 } | 552 } |
557 | 553 |
558 // This makes sure that reallocing a small number of bytes in either | 554 // This makes sure that reallocing a small number of bytes in either |
559 // direction doesn't cause us to allocate new memory. | 555 // direction doesn't cause us to allocate new memory. |
560 static void TestRealloc() { | 556 static void TestRealloc() { |
561 #ifndef DEBUGALLOCATION // debug alloc doesn't try to minimize reallocs | 557 #ifndef DEBUGALLOCATION // debug alloc doesn't try to minimize reallocs |
| 558 // When sampling, we always allocate in units of page-size, which |
| 559 // makes reallocs of small sizes do extra work (thus, failing these |
| 560 // checks). Since sampling is random, we turn off sampling to make |
| 561 // sure that doesn't happen to us here. |
| 562 const int64 old_sample_parameter = FLAGS_tcmalloc_sample_parameter; |
| 563 FLAGS_tcmalloc_sample_parameter = 0; // turn off sampling |
| 564 |
562 int start_sizes[] = { 100, 1000, 10000, 100000 }; | 565 int start_sizes[] = { 100, 1000, 10000, 100000 }; |
563 int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 }; | 566 int deltas[] = { 1, -2, 4, -8, 16, -32, 64, -128 }; |
564 | 567 |
565 for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) { | 568 for (int s = 0; s < sizeof(start_sizes)/sizeof(*start_sizes); ++s) { |
566 void* p = malloc(start_sizes[s]); | 569 void* p = malloc(start_sizes[s]); |
567 CHECK(p); | 570 CHECK(p); |
568 // The larger the start-size, the larger the non-reallocing delta. | 571 // The larger the start-size, the larger the non-reallocing delta. |
569 for (int d = 0; d < s*2; ++d) { | 572 for (int d = 0; d < (s+1) * 2; ++d) { |
570 void* new_p = realloc(p, start_sizes[s] + deltas[d]); | 573 void* new_p = realloc(p, start_sizes[s] + deltas[d]); |
571 CHECK(p == new_p); // realloc should not allocate new memory | 574 CHECK(p == new_p); // realloc should not allocate new memory |
572 } | 575 } |
573 // Test again, but this time reallocing smaller first. | 576 // Test again, but this time reallocing smaller first. |
574 for (int d = 0; d < s*2; ++d) { | 577 for (int d = 0; d < s*2; ++d) { |
575 void* new_p = realloc(p, start_sizes[s] - deltas[d]); | 578 void* new_p = realloc(p, start_sizes[s] - deltas[d]); |
576 CHECK(p == new_p); // realloc should not allocate new memory | 579 CHECK(p == new_p); // realloc should not allocate new memory |
577 } | 580 } |
578 free(p); | 581 free(p); |
579 } | 582 } |
| 583 FLAGS_tcmalloc_sample_parameter = old_sample_parameter; |
580 #endif | 584 #endif |
581 } | 585 } |
582 | 586 |
583 static void TestNewHandler() throw (std::bad_alloc) { | 587 static void TestNewHandler() throw (std::bad_alloc) { |
584 ++news_handled; | 588 ++news_handled; |
585 throw std::bad_alloc(); | 589 throw std::bad_alloc(); |
586 } | 590 } |
587 | 591 |
588 static void TestOneNew(void* (*func)(size_t)) { | 592 static void TestOneNew(void* (*func)(size_t)) { |
589 // success test | 593 // success test |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 // the hook takes. | 685 // the hook takes. |
682 #define MAKE_HOOK_CALLBACK(hook_type) \ | 686 #define MAKE_HOOK_CALLBACK(hook_type) \ |
683 static int g_##hook_type##_calls = 0; \ | 687 static int g_##hook_type##_calls = 0; \ |
684 static void IncrementCallsTo##hook_type(...) { \ | 688 static void IncrementCallsTo##hook_type(...) { \ |
685 g_##hook_type##_calls++; \ | 689 g_##hook_type##_calls++; \ |
686 } \ | 690 } \ |
687 static void Verify##hook_type##WasCalled() { \ | 691 static void Verify##hook_type##WasCalled() { \ |
688 CHECK_GT(g_##hook_type##_calls, 0); \ | 692 CHECK_GT(g_##hook_type##_calls, 0); \ |
689 g_##hook_type##_calls = 0; /* reset for next call */ \ | 693 g_##hook_type##_calls = 0; /* reset for next call */ \ |
690 } \ | 694 } \ |
691 static MallocHook::hook_type g_old_##hook_type; \ | |
692 static void Set##hook_type() { \ | 695 static void Set##hook_type() { \ |
693 g_old_##hook_type = MallocHook::Set##hook_type( \ | 696 CHECK(MallocHook::Add##hook_type( \ |
694 (MallocHook::hook_type)&IncrementCallsTo##hook_type); \ | 697 (MallocHook::hook_type)&IncrementCallsTo##hook_type)); \ |
695 } \ | 698 } \ |
696 static void Reset##hook_type() { \ | 699 static void Reset##hook_type() { \ |
697 CHECK_EQ(MallocHook::Set##hook_type(g_old_##hook_type), \ | 700 CHECK(MallocHook::Remove##hook_type( \ |
698 (MallocHook::hook_type)&IncrementCallsTo##hook_type); \ | 701 (MallocHook::hook_type)&IncrementCallsTo##hook_type)); \ |
699 } | 702 } |
700 | 703 |
701 // We do one for each hook typedef in malloc_hook.h | 704 // We do one for each hook typedef in malloc_hook.h |
702 MAKE_HOOK_CALLBACK(NewHook); | 705 MAKE_HOOK_CALLBACK(NewHook); |
703 MAKE_HOOK_CALLBACK(DeleteHook); | 706 MAKE_HOOK_CALLBACK(DeleteHook); |
704 MAKE_HOOK_CALLBACK(MmapHook); | 707 MAKE_HOOK_CALLBACK(MmapHook); |
705 MAKE_HOOK_CALLBACK(MremapHook); | 708 MAKE_HOOK_CALLBACK(MremapHook); |
706 MAKE_HOOK_CALLBACK(MunmapHook); | 709 MAKE_HOOK_CALLBACK(MunmapHook); |
707 MAKE_HOOK_CALLBACK(SbrkHook); | 710 MAKE_HOOK_CALLBACK(SbrkHook); |
708 | 711 |
709 static void TestAlignmentForSize(int size) { | 712 static void TestAlignmentForSize(int size) { |
710 fprintf(LOGSTREAM, "Testing alignment of malloc(%d)\n", size); | 713 fprintf(LOGSTREAM, "Testing alignment of malloc(%d)\n", size); |
711 static const int kNum = 100; | 714 static const int kNum = 100; |
712 void* ptrs[kNum]; | 715 void* ptrs[kNum]; |
713 for (int i = 0; i < kNum; i++) { | 716 for (int i = 0; i < kNum; i++) { |
714 ptrs[i] = malloc(size); | 717 ptrs[i] = malloc(size); |
715 uintptr_t p = reinterpret_cast<uintptr_t>(ptrs[i]); | 718 uintptr_t p = reinterpret_cast<uintptr_t>(ptrs[i]); |
716 CHECK((p % sizeof(void*)) == 0); | 719 CHECK((p % sizeof(void*)) == 0); |
717 CHECK((p % sizeof(double)) == 0); | 720 CHECK((p % sizeof(double)) == 0); |
718 | 721 |
719 // Must have 16-byte alignment for large enough objects | 722 // Must have 16-byte alignment for large enough objects |
720 #ifndef DEBUGALLOCATION // debug allocation doesn't need to align like this | |
721 if (size >= 16) { | 723 if (size >= 16) { |
722 CHECK((p % 16) == 0); | 724 CHECK((p % 16) == 0); |
723 } | 725 } |
724 #endif | |
725 } | 726 } |
726 for (int i = 0; i < kNum; i++) { | 727 for (int i = 0; i < kNum; i++) { |
727 free(ptrs[i]); | 728 free(ptrs[i]); |
728 } | 729 } |
729 } | 730 } |
730 | 731 |
731 static void TestMallocAlignment() { | 732 static void TestMallocAlignment() { |
732 for (int lg = 0; lg < 16; lg++) { | 733 for (int lg = 0; lg < 16; lg++) { |
733 TestAlignmentForSize((1<<lg) - 1); | 734 TestAlignmentForSize((1<<lg) - 1); |
734 TestAlignmentForSize((1<<lg) + 0); | 735 TestAlignmentForSize((1<<lg) + 0); |
(...skipping 21 matching lines...) Expand all Loading... |
756 uintptr_t ptr; | 757 uintptr_t ptr; |
757 base::MallocRange::Type expected_type; | 758 base::MallocRange::Type expected_type; |
758 size_t min_size; | 759 size_t min_size; |
759 bool matched; | 760 bool matched; |
760 }; | 761 }; |
761 | 762 |
762 static void RangeCallback(void* arg, const base::MallocRange* r) { | 763 static void RangeCallback(void* arg, const base::MallocRange* r) { |
763 RangeCallbackState* state = reinterpret_cast<RangeCallbackState*>(arg); | 764 RangeCallbackState* state = reinterpret_cast<RangeCallbackState*>(arg); |
764 if (state->ptr >= r->address && | 765 if (state->ptr >= r->address && |
765 state->ptr < r->address + r->length) { | 766 state->ptr < r->address + r->length) { |
766 CHECK_EQ(r->type, state->expected_type); | 767 if (state->expected_type == base::MallocRange::FREE) { |
| 768 // We are expecting r->type == FREE, but ReleaseMemory |
| 769 // may have already moved us to UNMAPPED state instead (this happens in |
| 770 // approximately 0.1% of executions). Accept either state. |
| 771 CHECK(r->type == base::MallocRange::FREE || |
| 772 r->type == base::MallocRange::UNMAPPED); |
| 773 } else { |
| 774 CHECK_EQ(r->type, state->expected_type); |
| 775 } |
767 CHECK_GE(r->length, state->min_size); | 776 CHECK_GE(r->length, state->min_size); |
768 state->matched = true; | 777 state->matched = true; |
769 } | 778 } |
770 } | 779 } |
771 | 780 |
772 // Check that at least one of the callbacks from Ranges() contains | 781 // Check that at least one of the callbacks from Ranges() contains |
773 // the specified address with the specified type, and has size | 782 // the specified address with the specified type, and has size |
774 // >= min_size. | 783 // >= min_size. |
775 static void CheckRangeCallback(void* ptr, base::MallocRange::Type type, | 784 static void CheckRangeCallback(void* ptr, base::MallocRange::Type type, |
776 size_t min_size) { | 785 size_t min_size) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes()); | 871 EXPECT_EQ(starting_bytes + MB, GetUnmappedBytes()); |
863 | 872 |
864 // Releasing less than a page should still trigger a release. | 873 // Releasing less than a page should still trigger a release. |
865 MallocExtension::instance()->ReleaseToSystem(1); | 874 MallocExtension::instance()->ReleaseToSystem(1); |
866 EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes()); | 875 EXPECT_EQ(starting_bytes + 2*MB, GetUnmappedBytes()); |
867 | 876 |
868 FLAGS_tcmalloc_release_rate = old_tcmalloc_release_rate; | 877 FLAGS_tcmalloc_release_rate = old_tcmalloc_release_rate; |
869 #endif // #ifndef DEBUGALLOCATION | 878 #endif // #ifndef DEBUGALLOCATION |
870 } | 879 } |
871 | 880 |
872 bool g_no_memory = false; | 881 // On MSVC10, in release mode, the optimizer convinces itself |
| 882 // g_no_memory is never changed (I guess it doesn't realize OnNoMemory |
| 883 // might be called). Work around this by setting the var volatile. |
| 884 volatile bool g_no_memory = false; |
873 std::new_handler g_old_handler = NULL; | 885 std::new_handler g_old_handler = NULL; |
874 static void OnNoMemory() { | 886 static void OnNoMemory() { |
875 g_no_memory = true; | 887 g_no_memory = true; |
876 std::set_new_handler(g_old_handler); | 888 std::set_new_handler(g_old_handler); |
877 } | 889 } |
878 | 890 |
879 static void TestSetNewMode() { | 891 static void TestSetNewMode() { |
880 int old_mode = tc_set_new_mode(1); | 892 int old_mode = tc_set_new_mode(1); |
881 | 893 |
882 // DebugAllocation will try to catch huge allocations. We need to avoid this | 894 // DebugAllocation will try to catch huge allocations. We need to avoid this |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 | 1002 |
991 // Test each of the memory-allocation functions once, just as a sanity-check | 1003 // Test each of the memory-allocation functions once, just as a sanity-check |
992 fprintf(LOGSTREAM, "Sanity-testing all the memory allocation functions\n"); | 1004 fprintf(LOGSTREAM, "Sanity-testing all the memory allocation functions\n"); |
993 { | 1005 { |
994 // We use new-hook and delete-hook to verify we actually called the | 1006 // We use new-hook and delete-hook to verify we actually called the |
995 // tcmalloc version of these routines, and not the libc version. | 1007 // tcmalloc version of these routines, and not the libc version. |
996 SetNewHook(); // defined as part of MAKE_HOOK_CALLBACK, above | 1008 SetNewHook(); // defined as part of MAKE_HOOK_CALLBACK, above |
997 SetDeleteHook(); // ditto | 1009 SetDeleteHook(); // ditto |
998 | 1010 |
999 void* p1 = malloc(10); | 1011 void* p1 = malloc(10); |
| 1012 CHECK(p1 != NULL); // force use of this variable |
1000 VerifyNewHookWasCalled(); | 1013 VerifyNewHookWasCalled(); |
| 1014 // Also test the non-standard tc_malloc_size |
| 1015 size_t actual_p1_size = tc_malloc_size(p1); |
| 1016 CHECK_GE(actual_p1_size, 10); |
| 1017 CHECK_LT(actual_p1_size, 100000); // a reasonable upper-bound, I think |
1001 free(p1); | 1018 free(p1); |
1002 VerifyDeleteHookWasCalled(); | 1019 VerifyDeleteHookWasCalled(); |
1003 | 1020 |
| 1021 |
1004 p1 = calloc(10, 2); | 1022 p1 = calloc(10, 2); |
| 1023 CHECK(p1 != NULL); |
1005 VerifyNewHookWasCalled(); | 1024 VerifyNewHookWasCalled(); |
1006 p1 = realloc(p1, 30); | 1025 // We make sure we realloc to a big size, since some systems (OS |
| 1026 // X) will notice if the realloced size continues to fit into the |
| 1027 // malloc-block and make this a noop if so. |
| 1028 p1 = realloc(p1, 30000); |
| 1029 CHECK(p1 != NULL); |
1007 VerifyNewHookWasCalled(); | 1030 VerifyNewHookWasCalled(); |
1008 VerifyDeleteHookWasCalled(); | 1031 VerifyDeleteHookWasCalled(); |
1009 cfree(p1); // synonym for free | 1032 cfree(p1); // synonym for free |
1010 VerifyDeleteHookWasCalled(); | 1033 VerifyDeleteHookWasCalled(); |
1011 | 1034 |
1012 CHECK_EQ(posix_memalign(&p1, sizeof(p1), 40), 0); | 1035 CHECK_EQ(posix_memalign(&p1, sizeof(p1), 40), 0); |
| 1036 CHECK(p1 != NULL); |
1013 VerifyNewHookWasCalled(); | 1037 VerifyNewHookWasCalled(); |
1014 free(p1); | 1038 free(p1); |
1015 VerifyDeleteHookWasCalled(); | 1039 VerifyDeleteHookWasCalled(); |
1016 | 1040 |
1017 p1 = memalign(sizeof(p1) * 2, 50); | 1041 p1 = memalign(sizeof(p1) * 2, 50); |
| 1042 CHECK(p1 != NULL); |
1018 VerifyNewHookWasCalled(); | 1043 VerifyNewHookWasCalled(); |
1019 free(p1); | 1044 free(p1); |
1020 VerifyDeleteHookWasCalled(); | 1045 VerifyDeleteHookWasCalled(); |
1021 | 1046 |
| 1047 // Windows has _aligned_malloc. Let's test that that's captured too. |
| 1048 #if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(PERFTOOLS_NO_ALIGNED
_MALLOC) |
| 1049 p1 = _aligned_malloc(sizeof(p1) * 2, 64); |
| 1050 VerifyNewHookWasCalled(); |
| 1051 _aligned_free(p1); |
| 1052 VerifyDeleteHookWasCalled(); |
| 1053 #endif |
| 1054 |
1022 p1 = valloc(60); | 1055 p1 = valloc(60); |
| 1056 CHECK(p1 != NULL); |
1023 VerifyNewHookWasCalled(); | 1057 VerifyNewHookWasCalled(); |
1024 free(p1); | 1058 free(p1); |
1025 VerifyDeleteHookWasCalled(); | 1059 VerifyDeleteHookWasCalled(); |
1026 | 1060 |
1027 p1 = pvalloc(70); | 1061 p1 = pvalloc(70); |
| 1062 CHECK(p1 != NULL); |
1028 VerifyNewHookWasCalled(); | 1063 VerifyNewHookWasCalled(); |
1029 free(p1); | 1064 free(p1); |
1030 VerifyDeleteHookWasCalled(); | 1065 VerifyDeleteHookWasCalled(); |
1031 | 1066 |
1032 char* p2 = new char; | 1067 char* p2 = new char; |
| 1068 CHECK(p2 != NULL); |
1033 VerifyNewHookWasCalled(); | 1069 VerifyNewHookWasCalled(); |
1034 delete p2; | 1070 delete p2; |
1035 VerifyDeleteHookWasCalled(); | 1071 VerifyDeleteHookWasCalled(); |
1036 | 1072 |
1037 p2 = new char[100]; | 1073 p2 = new char[100]; |
| 1074 CHECK(p2 != NULL); |
1038 VerifyNewHookWasCalled(); | 1075 VerifyNewHookWasCalled(); |
1039 delete[] p2; | 1076 delete[] p2; |
1040 VerifyDeleteHookWasCalled(); | 1077 VerifyDeleteHookWasCalled(); |
1041 | 1078 |
1042 p2 = new(std::nothrow) char; | 1079 p2 = new(std::nothrow) char; |
| 1080 CHECK(p2 != NULL); |
1043 VerifyNewHookWasCalled(); | 1081 VerifyNewHookWasCalled(); |
1044 delete p2; | 1082 delete p2; |
1045 VerifyDeleteHookWasCalled(); | 1083 VerifyDeleteHookWasCalled(); |
1046 | 1084 |
1047 p2 = new(std::nothrow) char[100]; | 1085 p2 = new(std::nothrow) char[100]; |
| 1086 CHECK(p2 != NULL); |
1048 VerifyNewHookWasCalled(); | 1087 VerifyNewHookWasCalled(); |
1049 delete[] p2; | 1088 delete[] p2; |
1050 VerifyDeleteHookWasCalled(); | 1089 VerifyDeleteHookWasCalled(); |
1051 | 1090 |
1052 // Another way of calling operator new | 1091 // Another way of calling operator new |
1053 p2 = static_cast<char*>(::operator new(100)); | 1092 p2 = static_cast<char*>(::operator new(100)); |
| 1093 CHECK(p2 != NULL); |
1054 VerifyNewHookWasCalled(); | 1094 VerifyNewHookWasCalled(); |
1055 ::operator delete(p2); | 1095 ::operator delete(p2); |
1056 VerifyDeleteHookWasCalled(); | 1096 VerifyDeleteHookWasCalled(); |
1057 | 1097 |
1058 // Try to call nothrow's delete too. Compilers use this. | 1098 // Try to call nothrow's delete too. Compilers use this. |
1059 p2 = static_cast<char*>(::operator new(100, std::nothrow)); | 1099 p2 = static_cast<char*>(::operator new(100, std::nothrow)); |
| 1100 CHECK(p2 != NULL); |
1060 VerifyNewHookWasCalled(); | 1101 VerifyNewHookWasCalled(); |
1061 ::operator delete(p2, std::nothrow); | 1102 ::operator delete(p2, std::nothrow); |
1062 VerifyDeleteHookWasCalled(); | 1103 VerifyDeleteHookWasCalled(); |
1063 | 1104 |
| 1105 // Try strdup(), which the system allocates but we must free. If |
| 1106 // all goes well, libc will use our malloc! |
| 1107 p2 = strdup("test"); |
| 1108 CHECK(p2 != NULL); |
| 1109 VerifyNewHookWasCalled(); |
| 1110 free(p2); |
| 1111 VerifyDeleteHookWasCalled(); |
| 1112 |
| 1113 |
1064 // Test mmap too: both anonymous mmap and mmap of a file | 1114 // Test mmap too: both anonymous mmap and mmap of a file |
1065 // Note that for right now we only override mmap on linux | 1115 // Note that for right now we only override mmap on linux |
1066 // systems, so those are the only ones for which we check. | 1116 // systems, so those are the only ones for which we check. |
1067 SetMmapHook(); | 1117 SetMmapHook(); |
1068 SetMremapHook(); | 1118 SetMremapHook(); |
1069 SetMunmapHook(); | 1119 SetMunmapHook(); |
1070 #if defined(HAVE_MMAP) && defined(__linux) && \ | 1120 #if defined(HAVE_MMAP) && defined(__linux) && \ |
1071 (defined(__i386__) || defined(__x86_64__)) | 1121 (defined(__i386__) || defined(__x86_64__)) |
1072 int size = 8192*2; | 1122 int size = 8192*2; |
1073 p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, | 1123 p1 = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, |
1074 -1, 0); | 1124 -1, 0); |
| 1125 CHECK(p1 != NULL); |
1075 VerifyMmapHookWasCalled(); | 1126 VerifyMmapHookWasCalled(); |
1076 p1 = mremap(p1, size, size/2, 0); | 1127 p1 = mremap(p1, size, size/2, 0); |
| 1128 CHECK(p1 != NULL); |
1077 VerifyMremapHookWasCalled(); | 1129 VerifyMremapHookWasCalled(); |
1078 size /= 2; | 1130 size /= 2; |
1079 munmap(p1, size); | 1131 munmap(p1, size); |
1080 VerifyMunmapHookWasCalled(); | 1132 VerifyMunmapHookWasCalled(); |
1081 | 1133 |
1082 int fd = open("/dev/zero", O_RDONLY); | 1134 int fd = open("/dev/zero", O_RDONLY); |
1083 CHECK_GE(fd, 0); // make sure the open succeeded | 1135 CHECK_GE(fd, 0); // make sure the open succeeded |
1084 p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0); | 1136 p1 = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0); |
| 1137 CHECK(p1 != NULL); |
1085 VerifyMmapHookWasCalled(); | 1138 VerifyMmapHookWasCalled(); |
1086 munmap(p1, 8192); | 1139 munmap(p1, 8192); |
1087 VerifyMunmapHookWasCalled(); | 1140 VerifyMunmapHookWasCalled(); |
1088 close(fd); | 1141 close(fd); |
1089 #else // this is just to quiet the compiler: make sure all fns are called | 1142 #else // this is just to quiet the compiler: make sure all fns are called |
1090 IncrementCallsToMmapHook(); | 1143 IncrementCallsToMmapHook(); |
1091 IncrementCallsToMunmapHook(); | 1144 IncrementCallsToMunmapHook(); |
1092 IncrementCallsToMremapHook(); | 1145 IncrementCallsToMremapHook(); |
1093 VerifyMmapHookWasCalled(); | 1146 VerifyMmapHookWasCalled(); |
1094 VerifyMremapHookWasCalled(); | 1147 VerifyMremapHookWasCalled(); |
1095 VerifyMunmapHookWasCalled(); | 1148 VerifyMunmapHookWasCalled(); |
1096 #endif | 1149 #endif |
1097 | 1150 |
1098 // Test sbrk | 1151 // Test sbrk |
1099 SetSbrkHook(); | 1152 SetSbrkHook(); |
1100 #if defined(HAVE_SBRK) && defined(__linux) && \ | 1153 #if defined(HAVE_SBRK) && defined(__linux) && \ |
1101 (defined(__i386__) || defined(__x86_64__)) | 1154 (defined(__i386__) || defined(__x86_64__)) |
1102 p1 = sbrk(8192); | 1155 p1 = sbrk(8192); |
| 1156 CHECK(p1 != NULL); |
1103 VerifySbrkHookWasCalled(); | 1157 VerifySbrkHookWasCalled(); |
1104 p1 = sbrk(-8192); | 1158 p1 = sbrk(-8192); |
| 1159 CHECK(p1 != NULL); |
1105 VerifySbrkHookWasCalled(); | 1160 VerifySbrkHookWasCalled(); |
1106 // However, sbrk hook should *not* be called with sbrk(0) | 1161 // However, sbrk hook should *not* be called with sbrk(0) |
1107 p1 = sbrk(0); | 1162 p1 = sbrk(0); |
| 1163 CHECK(p1 != NULL); |
1108 CHECK_EQ(g_SbrkHook_calls, 0); | 1164 CHECK_EQ(g_SbrkHook_calls, 0); |
1109 #else // this is just to quiet the compiler: make sure all fns are called | 1165 #else // this is just to quiet the compiler: make sure all fns are called |
1110 IncrementCallsToSbrkHook(); | 1166 IncrementCallsToSbrkHook(); |
1111 VerifySbrkHookWasCalled(); | 1167 VerifySbrkHookWasCalled(); |
1112 #endif | 1168 #endif |
1113 | 1169 |
1114 // Reset the hooks to what they used to be. These are all | 1170 // Reset the hooks to what they used to be. These are all |
1115 // defined as part of MAKE_HOOK_CALLBACK, above. | 1171 // defined as part of MAKE_HOOK_CALLBACK, above. |
1116 ResetNewHook(); | 1172 ResetNewHook(); |
1117 ResetDeleteHook(); | 1173 ResetDeleteHook(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 int minor; | 1277 int minor; |
1222 const char* patch; | 1278 const char* patch; |
1223 char mmp[64]; | 1279 char mmp[64]; |
1224 const char* human_version = tc_version(&major, &minor, &patch); | 1280 const char* human_version = tc_version(&major, &minor, &patch); |
1225 snprintf(mmp, sizeof(mmp), "%d.%d%s", major, minor, patch); | 1281 snprintf(mmp, sizeof(mmp), "%d.%d%s", major, minor, patch); |
1226 CHECK(!strcmp(PACKAGE_STRING, human_version)); | 1282 CHECK(!strcmp(PACKAGE_STRING, human_version)); |
1227 CHECK(!strcmp(PACKAGE_VERSION, mmp)); | 1283 CHECK(!strcmp(PACKAGE_VERSION, mmp)); |
1228 | 1284 |
1229 fprintf(LOGSTREAM, "PASS\n"); | 1285 fprintf(LOGSTREAM, "PASS\n"); |
1230 } | 1286 } |
OLD | NEW |