Repository: trafficserver Updated Branches: refs/heads/master 340d9cb0e -> 61a05d5e8
TS-3877: Add a tracking ClassAllocator to keep track of where the allocation happened Updates to make it fast and able to use in production Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/61a05d5e Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/61a05d5e Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/61a05d5e Branch: refs/heads/master Commit: 61a05d5e84e30834cbdddd37ee501517a0e26475 Parents: 340d9cb Author: Bryan Call <[email protected]> Authored: Thu Sep 3 09:24:56 2015 -0700 Committer: Bryan Call <[email protected]> Committed: Thu Sep 3 09:24:56 2015 -0700 ---------------------------------------------------------------------- lib/ts/Allocator.h | 32 ++++++++++++++++---------- lib/ts/ink_resource.cc | 55 ++++++++++++++++++++++++++++++++++++++++----- lib/ts/ink_resource.h | 3 ++- 3 files changed, 72 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/61a05d5e/lib/ts/Allocator.h ---------------------------------------------------------------------- diff --git a/lib/ts/Allocator.h b/lib/ts/Allocator.h index 63695a9..3b489a7 100644 --- a/lib/ts/Allocator.h +++ b/lib/ts/Allocator.h @@ -206,41 +206,49 @@ template <class C> class TrackerClassAllocator : public ClassAllocator<C> { public: TrackerClassAllocator(const char *name, unsigned int chunk_size = 128, unsigned int alignment = 16) - : ClassAllocator<C>(name, chunk_size, alignment) + : ClassAllocator<C>(name, chunk_size, alignment), allocations(0), trackerLock(PTHREAD_MUTEX_INITIALIZER) { } C * alloc() { - void *callstack[128]; - int frames = backtrace(callstack, 128); - char **strs = backtrace_symbols(callstack, frames); - char name[128]; - snprintf(name, sizeof(name), "%s/%s", this->fl->name, strs[1]); - tracker.increment((char *)strs[1], (int64_t)sizeof(C)); + void *callstack[3]; + int frames = backtrace(callstack, 3); C *ptr = ClassAllocator<C>::alloc(); - reverse_lookup[ptr] = strs[1]; + + const void *symbol = NULL; + if (frames == 3 && callstack[2] != NULL) { + symbol = callstack[2]; + } + + tracker.increment(symbol, (int64_t)sizeof(C), this->fl->name); + ink_mutex_acquire(&trackerLock); + reverse_lookup[ptr] = symbol; ++allocations; - ::free(strs); + ink_mutex_release(&trackerLock); + return ptr; } void free(C *ptr) { - std::map<void *, std::string>::iterator it = reverse_lookup.find(ptr); + ink_mutex_acquire(&trackerLock); + std::map<void *, const void *>::iterator it = reverse_lookup.find(ptr); if (it != reverse_lookup.end()) { - tracker.increment(it->second.c_str(), (int64_t)sizeof(C) * -1); + tracker.increment((const void *)it->second, (int64_t)sizeof(C) * -1, NULL); reverse_lookup.erase(it); } + ink_mutex_release(&trackerLock); ClassAllocator<C>::free(ptr); } private: ResourceTracker tracker; - std::map<void *, std::string> reverse_lookup; + std::map<void *, const void *> reverse_lookup; uint64_t allocations; + ink_mutex trackerLock; }; #endif // _Allocator_h_ http://git-wip-us.apache.org/repos/asf/trafficserver/blob/61a05d5e/lib/ts/ink_resource.cc ---------------------------------------------------------------------- diff --git a/lib/ts/ink_resource.cc b/lib/ts/ink_resource.cc index ac272fe..59d23b5 100644 --- a/lib/ts/ink_resource.cc +++ b/lib/ts/ink_resource.cc @@ -28,7 +28,7 @@ volatile int res_track_memory = 0; // Disabled by default -std::map<std::string, Resource *> ResourceTracker::_resourceMap; +std::map<const char *, Resource *> ResourceTracker::_resourceMap; ink_mutex ResourceTracker::resourceLock = PTHREAD_MUTEX_INITIALIZER; /** @@ -37,7 +37,7 @@ ink_mutex ResourceTracker::resourceLock = PTHREAD_MUTEX_INITIALIZER; class Resource { public: - Resource() : _incrementCount(0), _decrementCount(0), _value(0) {} + Resource() : _incrementCount(0), _decrementCount(0), _value(0), _symbol(NULL), _name("") {} void increment(const int64_t size); int64_t getValue() const @@ -54,11 +54,41 @@ public: { return _decrementCount; } + void + setSymbol(const void *symbol) + { + _symbol = symbol; + } + void + setName(const char *name) + { + strncpy(_name, name, sizeof(_name)); + _name[sizeof(_name)] = '\0'; + } + void + setName(const void *symbol, const char *name) + { + Dl_info info; + dladdr(symbol, &info); + snprintf(_name, sizeof(_name), "%s/%s", name, info.dli_sname); + } + const char * + getName() const + { + return _name; + } + const void * + getSymbol() const + { + return _symbol; + } private: int64_t _incrementCount; int64_t _decrementCount; int64_t _value; + const void *_symbol; + char _name[128]; }; void @@ -76,6 +106,21 @@ void ResourceTracker::increment(const char *name, const int64_t size) { Resource &resource = lookup(name); + const char *lookup_name = resource.getName(); + if (lookup_name[0] == '\0') { + resource.setName(name); + } + resource.increment(size); +} + +void +ResourceTracker::increment(const void *symbol, const int64_t size, const char *name) +{ + Resource &resource = lookup((const char *)symbol); + if (resource.getSymbol() == NULL && name != NULL) { + resource.setName(symbol, name); + resource.setSymbol(symbol); + } resource.increment(size); } @@ -84,7 +129,7 @@ ResourceTracker::lookup(const char *name) { Resource *resource = NULL; ink_mutex_acquire(&resourceLock); - std::map<std::string, Resource *>::iterator it = _resourceMap.find(name); + std::map<const char *, Resource *>::iterator it = _resourceMap.find(name); if (it != _resourceMap.end()) { resource = it->second; } else { @@ -110,12 +155,12 @@ ResourceTracker::dump(FILE *fd) fprintf(fd, "\n%-10s | %-10s | %-20s | %-10s | %-50s\n", "Allocs", "Frees", "Size In-use", "Avg Size", "Location"); fprintf(fd, "-----------|------------|----------------------|------------|" "--------------------------------------------------------------------\n"); - for (std::map<std::string, Resource *>::const_iterator it = _resourceMap.begin(); it != _resourceMap.end(); ++it) { + for (std::map<const char *, Resource *>::const_iterator it = _resourceMap.begin(); it != _resourceMap.end(); ++it) { const Resource &resource = *it->second; if (resource.getIncrement() - resource.getDecrement()) { fprintf(fd, "%10" PRId64 " | %10" PRId64 " | %20" PRId64 " | %10" PRId64 " | %-50s\n", resource.getIncrement(), resource.getDecrement(), resource.getValue(), - resource.getValue() / (resource.getIncrement() - resource.getDecrement()), it->first.c_str()); + resource.getValue() / (resource.getIncrement() - resource.getDecrement()), resource.getName()); total += resource.getValue(); } } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/61a05d5e/lib/ts/ink_resource.h ---------------------------------------------------------------------- diff --git a/lib/ts/ink_resource.h b/lib/ts/ink_resource.h index 4e579cd..27bce50 100644 --- a/lib/ts/ink_resource.h +++ b/lib/ts/ink_resource.h @@ -45,11 +45,12 @@ class ResourceTracker public: ResourceTracker(){}; static void increment(const char *name, const int64_t size); + static void increment(const void *symbol, const int64_t size, const char *name); static void dump(FILE *fd); private: static Resource &lookup(const char *name); - static std::map<std::string, Resource *> _resourceMap; + static std::map<const char *, Resource *> _resourceMap; static ink_mutex resourceLock; };
