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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 | 74 |
75 | 75 |
76 #ifndef PATH_MAX | 76 #ifndef PATH_MAX |
77 #ifdef MAXPATHLEN | 77 #ifdef MAXPATHLEN |
78 #define PATH_MAX MAXPATHLEN | 78 #define PATH_MAX MAXPATHLEN |
79 #else | 79 #else |
80 #define PATH_MAX 4096 // seems conservative for max filename len! | 80 #define PATH_MAX 4096 // seems conservative for max filename len! |
81 #endif | 81 #endif |
82 #endif | 82 #endif |
83 | 83 |
| 84 #if defined(__ANDROID__) || defined(ANDROID) |
| 85 // On android, there are no environment variables. |
| 86 // Instead, we use system properties, set via: |
| 87 // adb shell setprop prop_name prop_value |
| 88 // From <sys/system_properties.h>, |
| 89 // PROP_NAME_MAX 32 |
| 90 // PROP_VALUE_MAX 92 |
| 91 #define HEAPPROFILE "heapprof" |
| 92 #define HEAP_PROFILE_ALLOCATION_INTERVAL "heapprof.allocation_interval" |
| 93 #define HEAP_PROFILE_DEALLOCATION_INTERVAL "heapprof.deallocation_interval" |
| 94 #define HEAP_PROFILE_INUSE_INTERVAL "heapprof.inuse_interval" |
| 95 #define HEAP_PROFILE_TIME_INTERVAL "heapprof.time_interval" |
| 96 #define HEAP_PROFILE_MMAP_LOG "heapprof.mmap_log" |
| 97 #define HEAP_PROFILE_MMAP "heapprof.mmap" |
| 98 #define HEAP_PROFILE_ONLY_MMAP "heapprof.only_mmap" |
| 99 #define DEEP_HEAP_PROFILE "heapprof.deep_heap_profile" |
| 100 #define HEAP_PROFILE_TYPE_STATISTICS "heapprof.type_statistics" |
| 101 #else // defined(__ANDROID__) || defined(ANDROID) |
| 102 #define HEAPPROFILE "HEAPPROFILE" |
| 103 #define HEAP_PROFILE_ALLOCATION_INTERVAL "HEAP_PROFILE_ALLOCATION_INTERVAL" |
| 104 #define HEAP_PROFILE_DEALLOCATION_INTERVAL "HEAP_PROFILE_DEALLOCATION_INTERVAL" |
| 105 #define HEAP_PROFILE_INUSE_INTERVAL "HEAP_PROFILE_INUSE_INTERVAL" |
| 106 #define HEAP_PROFILE_TIME_INTERVAL "HEAP_PROFILE_TIME_INTERVAL" |
| 107 #define HEAP_PROFILE_MMAP_LOG "HEAP_PROFILE_MMAP_LOG" |
| 108 #define HEAP_PROFILE_MMAP "HEAP_PROFILE_MMAP" |
| 109 #define HEAP_PROFILE_ONLY_MMAP "HEAP_PROFILE_ONLY_MMAP" |
| 110 #define DEEP_HEAP_PROFILE "DEEP_HEAP_PROFILE" |
| 111 #define HEAP_PROFILE_TYPE_STATISTICS "HEAP_PROFILE_TYPE_STATISTICS" |
| 112 #endif // defined(__ANDROID__) || defined(ANDROID) |
| 113 |
84 using STL_NAMESPACE::string; | 114 using STL_NAMESPACE::string; |
85 using STL_NAMESPACE::sort; | 115 using STL_NAMESPACE::sort; |
86 | 116 |
87 //---------------------------------------------------------------------- | 117 //---------------------------------------------------------------------- |
88 // Flags that control heap-profiling | 118 // Flags that control heap-profiling |
89 // | 119 // |
90 // The thread-safety of the profiler depends on these being immutable | 120 // The thread-safety of the profiler depends on these being immutable |
91 // after main starts, so don't change them. | 121 // after main starts, so don't change them. |
92 //---------------------------------------------------------------------- | 122 //---------------------------------------------------------------------- |
93 | 123 |
94 DEFINE_int64(heap_profile_allocation_interval, | 124 DEFINE_int64(heap_profile_allocation_interval, |
95 EnvToInt64("HEAP_PROFILE_ALLOCATION_INTERVAL", 1 << 30 /*1GB*/), | 125 EnvToInt64(HEAP_PROFILE_ALLOCATION_INTERVAL, 1 << 30 /*1GB*/), |
96 "If non-zero, dump heap profiling information once every " | 126 "If non-zero, dump heap profiling information once every " |
97 "specified number of bytes allocated by the program since " | 127 "specified number of bytes allocated by the program since " |
98 "the last dump."); | 128 "the last dump."); |
99 DEFINE_int64(heap_profile_deallocation_interval, | 129 DEFINE_int64(heap_profile_deallocation_interval, |
100 EnvToInt64("HEAP_PROFILE_DEALLOCATION_INTERVAL", 0), | 130 EnvToInt64(HEAP_PROFILE_DEALLOCATION_INTERVAL, 0), |
101 "If non-zero, dump heap profiling information once every " | 131 "If non-zero, dump heap profiling information once every " |
102 "specified number of bytes deallocated by the program " | 132 "specified number of bytes deallocated by the program " |
103 "since the last dump."); | 133 "since the last dump."); |
104 // We could also add flags that report whenever inuse_bytes changes by | 134 // We could also add flags that report whenever inuse_bytes changes by |
105 // X or -X, but there hasn't been a need for that yet, so we haven't. | 135 // X or -X, but there hasn't been a need for that yet, so we haven't. |
106 DEFINE_int64(heap_profile_inuse_interval, | 136 DEFINE_int64(heap_profile_inuse_interval, |
107 EnvToInt64("HEAP_PROFILE_INUSE_INTERVAL", 100 << 20 /*100MB*/), | 137 EnvToInt64(HEAP_PROFILE_INUSE_INTERVAL, 100 << 20 /*100MB*/), |
108 "If non-zero, dump heap profiling information whenever " | 138 "If non-zero, dump heap profiling information whenever " |
109 "the high-water memory usage mark increases by the specified " | 139 "the high-water memory usage mark increases by the specified " |
110 "number of bytes."); | 140 "number of bytes."); |
111 DEFINE_int64(heap_profile_time_interval, | 141 DEFINE_int64(heap_profile_time_interval, |
112 EnvToInt64("HEAP_PROFILE_TIME_INTERVAL", 0), | 142 EnvToInt64(HEAP_PROFILE_TIME_INTERVAL, 0), |
113 "If non-zero, dump heap profiling information once every " | 143 "If non-zero, dump heap profiling information once every " |
114 "specified number of seconds since the last dump."); | 144 "specified number of seconds since the last dump."); |
115 DEFINE_bool(mmap_log, | 145 DEFINE_bool(mmap_log, |
116 EnvToBool("HEAP_PROFILE_MMAP_LOG", false), | 146 EnvToBool(HEAP_PROFILE_MMAP_LOG, false), |
117 "Should mmap/munmap calls be logged?"); | 147 "Should mmap/munmap calls be logged?"); |
118 DEFINE_bool(mmap_profile, | 148 DEFINE_bool(mmap_profile, |
119 EnvToBool("HEAP_PROFILE_MMAP", false), | 149 EnvToBool(HEAP_PROFILE_MMAP, false), |
120 "If heap-profiling is on, also profile mmap, mremap, and sbrk)"); | 150 "If heap-profiling is on, also profile mmap, mremap, and sbrk)"); |
121 DEFINE_bool(only_mmap_profile, | 151 DEFINE_bool(only_mmap_profile, |
122 EnvToBool("HEAP_PROFILE_ONLY_MMAP", false), | 152 EnvToBool(HEAP_PROFILE_ONLY_MMAP, false), |
123 "If heap-profiling is on, only profile mmap, mremap, and sbrk; " | 153 "If heap-profiling is on, only profile mmap, mremap, and sbrk; " |
124 "do not profile malloc/new/etc"); | 154 "do not profile malloc/new/etc"); |
125 DEFINE_bool(deep_heap_profile, | 155 DEFINE_bool(deep_heap_profile, |
126 EnvToBool("DEEP_HEAP_PROFILE", false), | 156 EnvToBool(DEEP_HEAP_PROFILE, false), |
127 "If heap-profiling is on, profile deeper (only on Linux)"); | 157 "If heap-profiling is on, profile deeper (only on Linux)"); |
128 #if defined(TYPE_PROFILING) | 158 #if defined(TYPE_PROFILING) |
129 DEFINE_bool(heap_profile_type_statistics, | 159 DEFINE_bool(heap_profile_type_statistics, |
130 EnvToBool("HEAP_PROFILE_TYPE_STATISTICS", false), | 160 EnvToBool(HEAP_PROFILE_TYPE_STATISTICS, false), |
131 "If heap-profiling is on, dump type statistics."); | 161 "If heap-profiling is on, dump type statistics."); |
132 #endif // defined(TYPE_PROFILING) | 162 #endif // defined(TYPE_PROFILING) |
133 | 163 |
134 | 164 |
135 //---------------------------------------------------------------------- | 165 //---------------------------------------------------------------------- |
136 // Locking | 166 // Locking |
137 //---------------------------------------------------------------------- | 167 //---------------------------------------------------------------------- |
138 | 168 |
139 // A pthread_mutex has way too much lock contention to be used here. | 169 // A pthread_mutex has way too much lock contention to be used here. |
140 // | 170 // |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 } | 651 } |
622 | 652 |
623 //---------------------------------------------------------------------- | 653 //---------------------------------------------------------------------- |
624 // Initialization/finalization code | 654 // Initialization/finalization code |
625 //---------------------------------------------------------------------- | 655 //---------------------------------------------------------------------- |
626 | 656 |
627 // Initialization code | 657 // Initialization code |
628 static void HeapProfilerInit() { | 658 static void HeapProfilerInit() { |
629 // Everything after this point is for setting up the profiler based on envvar | 659 // Everything after this point is for setting up the profiler based on envvar |
630 char fname[PATH_MAX]; | 660 char fname[PATH_MAX]; |
631 if (!GetUniquePathFromEnv("HEAPPROFILE", fname)) { | 661 if (!GetUniquePathFromEnv(HEAPPROFILE, fname)) { |
632 return; | 662 return; |
633 } | 663 } |
634 // We do a uid check so we don't write out files in a setuid executable. | 664 // We do a uid check so we don't write out files in a setuid executable. |
635 #ifdef HAVE_GETEUID | 665 #ifdef HAVE_GETEUID |
636 if (getuid() != geteuid()) { | 666 if (getuid() != geteuid()) { |
637 RAW_LOG(WARNING, ("HeapProfiler: ignoring HEAPPROFILE because " | 667 RAW_LOG(WARNING, ("HeapProfiler: ignoring " HEAPPROFILE " because " |
638 "program seems to be setuid\n")); | 668 "program seems to be setuid\n")); |
639 return; | 669 return; |
640 } | 670 } |
641 #endif | 671 #endif |
642 | 672 |
643 HeapProfileTable::CleanupOldProfiles(fname); | 673 HeapProfileTable::CleanupOldProfiles(fname); |
644 | 674 |
645 HeapProfilerStart(fname); | 675 HeapProfilerStart(fname); |
646 } | 676 } |
647 | 677 |
648 // class used for finalization -- dumps the heap-profile at program exit | 678 // class used for finalization -- dumps the heap-profile at program exit |
649 struct HeapProfileEndWriter { | 679 struct HeapProfileEndWriter { |
650 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } | 680 ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); } |
651 }; | 681 }; |
652 | 682 |
653 // We want to make sure tcmalloc is up and running before starting the profiler | 683 // We want to make sure tcmalloc is up and running before starting the profiler |
654 static const TCMallocGuard tcmalloc_initializer; | 684 static const TCMallocGuard tcmalloc_initializer; |
655 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); | 685 REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit()); |
656 static HeapProfileEndWriter heap_profile_end_writer; | 686 static HeapProfileEndWriter heap_profile_end_writer; |
OLD | NEW |