mmlr + bonefish:

* AllocationTrackingCallback::ProcessTrackingInfo(): Also pass the
  allocation pointer.
* "allocations_per_caller" KDL command: Add option "-d". When given,
  each allocation for the specified caller is printed, including the
  respective stack trace.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43087 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2011-11-01 22:26:23 +00:00
parent e32699b404
commit f606e8fd79
3 changed files with 68 additions and 6 deletions
+2 -1
View File
@@ -893,7 +893,8 @@ MemoryManager::AnalyzeAllocationCallers(AllocationTrackingCallback& callback)
size_t size = reference - chunkAddress + 1; size_t size = reference - chunkAddress + 1;
if (!callback.ProcessTrackingInfo( if (!callback.ProcessTrackingInfo(
_TrackingInfoFor((void*)chunkAddress, size), size)) { _TrackingInfoFor((void*)chunkAddress, size),
(void*)chunkAddress, size)) {
return false; return false;
} }
} }
+65 -5
View File
@@ -357,7 +357,7 @@ public:
} }
virtual bool ProcessTrackingInfo(AllocationTrackingInfo* info, virtual bool ProcessTrackingInfo(AllocationTrackingInfo* info,
size_t allocationSize) void* allocation, size_t allocationSize)
{ {
if (!info->IsInitialized()) if (!info->IsInitialized())
return true; return true;
@@ -390,6 +390,45 @@ private:
bool fResetInfos; bool fResetInfos;
}; };
class AllocationDetailPrinterCallback : public AllocationTrackingCallback {
public:
AllocationDetailPrinterCallback(addr_t caller)
:
fCaller(caller)
{
}
virtual bool ProcessTrackingInfo(AllocationTrackingInfo* info,
void* allocation, size_t allocationSize)
{
if (!info->IsInitialized())
return true;
addr_t caller = 0;
AbstractTraceEntryWithStackTrace* traceEntry = info->TraceEntry();
if (traceEntry != NULL && info->IsTraceEntryValid()) {
caller = tracing_find_caller_in_stack_trace(
traceEntry->StackTrace(), kSlabCodeAddressRanges,
kSlabCodeAddressRangeCount);
}
if (caller != fCaller)
return true;
kprintf("allocation %p, size: %" B_PRIuSIZE "\n", allocation,
allocationSize);
if (traceEntry != NULL)
tracing_print_stack_trace(traceEntry->StackTrace());
return true;
}
private:
addr_t fCaller;
};
} // unnamed namespace } // unnamed namespace
static caller_info* static caller_info*
@@ -442,7 +481,7 @@ analyze_allocation_callers(ObjectCache* cache, const SlabList& slabList,
slab* slab = it.Next();) { slab* slab = it.Next();) {
for (uint32 i = 0; i < slab->size; i++) { for (uint32 i = 0; i < slab->size; i++) {
if (!callback.ProcessTrackingInfo(&slab->tracking[i], if (!callback.ProcessTrackingInfo(&slab->tracking[i],
cache->object_size)) { cache->ObjectAtIndex(slab, i), cache->object_size)) {
return false; return false;
} }
} }
@@ -468,11 +507,23 @@ dump_allocations_per_caller(int argc, char **argv)
{ {
bool sortBySize = true; bool sortBySize = true;
bool resetAllocationInfos = false; bool resetAllocationInfos = false;
bool printDetails = false;
ObjectCache* cache = NULL; ObjectCache* cache = NULL;
addr_t caller = 0;
for (int32 i = 1; i < argc; i++) { for (int32 i = 1; i < argc; i++) {
if (strcmp(argv[i], "-c") == 0) { if (strcmp(argv[i], "-c") == 0) {
sortBySize = false; sortBySize = false;
} else if (strcmp(argv[i], "-d") == 0) {
uint64 callerAddress;
if (++i >= argc
|| !evaluate_debug_expression(argv[i], &callerAddress, true)) {
print_debugger_command_usage(argv[0]);
return 0;
}
caller = callerAddress;
printDetails = true;
} else if (strcmp(argv[i], "-o") == 0) { } else if (strcmp(argv[i], "-o") == 0) {
uint64 cacheAddress; uint64 cacheAddress;
if (++i >= argc if (++i >= argc
@@ -492,9 +543,14 @@ dump_allocations_per_caller(int argc, char **argv)
sCallerInfoCount = 0; sCallerInfoCount = 0;
AllocationCollectorCallback collectorCallback(resetAllocationInfos);
AllocationDetailPrinterCallback detailsCallback(caller);
AllocationTrackingCallback& callback = printDetails
? (AllocationTrackingCallback&)detailsCallback
: (AllocationTrackingCallback&)collectorCallback;
if (cache != NULL) { if (cache != NULL) {
#if SLAB_OBJECT_CACHE_ALLOCATION_TRACKING #if SLAB_OBJECT_CACHE_ALLOCATION_TRACKING
AllocationCollectorCallback callback(resetAllocationInfos);
if (!analyze_allocation_callers(cache, callback)) if (!analyze_allocation_callers(cache, callback))
return 0; return 0;
#else #else
@@ -505,7 +561,6 @@ dump_allocations_per_caller(int argc, char **argv)
return 0; return 0;
#endif #endif
} else { } else {
AllocationCollectorCallback callback(resetAllocationInfos);
#if SLAB_OBJECT_CACHE_ALLOCATION_TRACKING #if SLAB_OBJECT_CACHE_ALLOCATION_TRACKING
for (ObjectCacheList::Iterator it = sObjectCaches.GetIterator(); for (ObjectCacheList::Iterator it = sObjectCaches.GetIterator();
@@ -521,6 +576,9 @@ dump_allocations_per_caller(int argc, char **argv)
#endif #endif
} }
if (printDetails)
return 0;
// sort the array // sort the array
qsort(sCallerInfoTable, sCallerInfoCount, sizeof(caller_info), qsort(sCallerInfoTable, sCallerInfoCount, sizeof(caller_info),
sortBySize ? &caller_info_compare_size : &caller_info_compare_count); sortBySize ? &caller_info_compare_size : &caller_info_compare_count);
@@ -1102,11 +1160,13 @@ slab_init_post_area()
add_debugger_command_etc("allocations_per_caller", add_debugger_command_etc("allocations_per_caller",
&dump_allocations_per_caller, &dump_allocations_per_caller,
"Dump current heap allocations summed up per caller", "Dump current heap allocations summed up per caller",
"[ -c ] [ -o <object cache> ] [ -r ]\n" "[ -c ] [ -d <caller> ] [ -o <object cache> ] [ -r ]\n"
"The current allocations will by summed up by caller (their count and\n" "The current allocations will by summed up by caller (their count and\n"
"size) printed in decreasing order by size or, if \"-c\" is\n" "size) printed in decreasing order by size or, if \"-c\" is\n"
"specified, by allocation count. If given <object cache> specifies\n" "specified, by allocation count. If given <object cache> specifies\n"
"the address of the object cache for which to print the allocations.\n" "the address of the object cache for which to print the allocations.\n"
"If \"-d\" is given, each allocation for caller <caller> is printed\n"
"including the respective stack trace.\n"
"If \"-r\" is given, the allocation infos are reset after gathering\n" "If \"-r\" is given, the allocation infos are reset after gathering\n"
"the information, so the next command invocation will only show the\n" "the information, so the next command invocation will only show the\n"
"allocations made after the reset.\n", 0); "allocations made after the reset.\n", 0);
+1
View File
@@ -95,6 +95,7 @@ public:
virtual bool ProcessTrackingInfo( virtual bool ProcessTrackingInfo(
AllocationTrackingInfo* info, AllocationTrackingInfo* info,
void* allocation,
size_t allocationSize) = 0; size_t allocationSize) = 0;
}; };