PDNS_ENABLE_COVERAGE
PDNS_ENABLE_SANITIZERS
+PDNS_ENABLE_MALLOC_TRACE
AC_SUBST(LIBS)
--- /dev/null
+AC_DEFUN([PDNS_ENABLE_MALLOC_TRACE], [
+ AC_MSG_CHECKING([whether to enable code malloc-trace])
+ AC_ARG_ENABLE([malloc-trace],
+ AS_HELP_STRING([--enable-malloc-trace],
+ [enable malloc-trace @<:@default=no@:>@]),
+ [enable_malloc_trace=$enableval],
+ [enable_malloc_trace=no]
+ )
+ AC_MSG_RESULT([$enable_malloc_trace])
+ AM_CONDITIONAL([MALLOC_TRACE], [test "x$enable_malloc_trace" = "xyes"])
+ AS_IF([test "x$enable_malloc_trace" = "xyes"],
+ AC_DEFINE([MALLOC_TRACE], [1], [Define to 1 if you want to benefit from malloc trace]) )
+])
pdns_recursor_LDADD += $(P11KIT1_LIBS)
endif
+if MALLOC_TRACE
+pdns_recursor_SOURCES += malloctrace.cc malloctrace.hh
+pdns_recursor_LDFLAGS = $(AM_LDFLAGS) -rdynamic
+endif
if LUA
pdns_recursor_LDADD += $(LUA_LIBS)
return str;
}
-/*
-char **strings;
- size_t i;
- strings = backtrace_symbols (array, size); //Need -rdynamic gcc (linker) flag for this to work
-
- for (i = 0; i < size; i++) //skip useless functions
- ret+=strings[i]+string("\n");
- return ret;
-*/
+void MallocTracer::clearAllocators()
+{
+ l_active=true;
+ std::lock_guard<std::mutex> lock(d_mut);
+ d_stats.clear();
+ l_active=false;
+}
uint64_t getAllocs(const std::string& = std::string()) const { return d_allocs; }
uint64_t getAllocFlux(const std::string& = std::string()) const { return d_allocflux; }
uint64_t getTotAllocated(const std::string& = std::string()) const { return d_totAllocated; }
-
+ uint64_t getNumOut() { std::lock_guard<std::mutex> lock(d_mut); return d_sizes.size(); }
struct AllocStats
{
int count;
std::vector<void*> > > allocators_t;
allocators_t topAllocators(int num=-1);
std::string topAllocatorsString(int num=-1);
+ void clearAllocators();
+
private:
static std::vector<void*> makeBacktrace();
std::atomic<uint64_t> d_allocs{0}, d_allocflux{0}, d_totAllocated{0};
#include <boost/lexical_cast.hpp>
#include <boost/function.hpp>
#include <boost/algorithm/string.hpp>
+#ifdef MALLOC_TRACE
+#include "malloctrace.hh"
+#endif
#include <netinet/tcp.h>
#include "dnsparser.hh"
#include "dnswriter.hh"
tracedQuery=true;
}
+
if(!g_quiet || tracedQuery)
L<<Logger::Warning<<t_id<<" ["<<MT->getTid()<<"/"<<MT->numProcesses()<<"] " << (dc->d_tcp ? "TCP " : "") << "question for '"<<dc->d_mdp.d_qname<<"|"
<<DNSRecordContent::NumberToType(dc->d_mdp.d_qtype)<<"' from "<<dc->getRemote()<<endl;
string response;
try {
uint32_t age;
+#ifdef MALLOC_TRACE
+ /*
+ static uint64_t last=0;
+ if(!last)
+ g_mtracer->clearAllocators();
+ cout<<g_mtracer->getAllocs()-last<<" "<<g_mtracer->getNumOut()<<" -- BEGIN TRACE"<<endl;
+ last=g_mtracer->getAllocs();
+ cout<<g_mtracer->topAllocatorsString()<<endl;
+ g_mtracer->clearAllocators();
+ */
+#endif
+
if(!SyncRes::s_nopacketcache && t_packetCache->getResponsePacket(question, g_now.tv_sec, &response, &age)) {
if(!g_quiet)
L<<Logger::Notice<<t_id<< " question answered from packet cache from "<<fromaddr.toString()<<endl;
// t_queryring->push_back("packetcached");
+
+
g_stats.packetCacheHits++;
SyncRes::s_queries++;
ageDNSPacket(response, age);
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <vector>
-
+#ifdef MALLOC_TRACE
+#include "malloctrace.hh"
+#endif
#include "misc.hh"
#include "recursor_cache.hh"
#include "syncres.hh"
// addGetStat("query-rate", getQueryRate);
addGetStat("user-msec", getUserTimeMsec);
addGetStat("sys-msec", getSysTimeMsec);
+
+#ifdef MALLOC_TRACE
+ addGetStat("memory-allocs", boost::bind(&MallocTracer::getAllocs, g_mtracer, string()));
+ addGetStat("memory-alloc-flux", boost::bind(&MallocTracer::getAllocFlux, g_mtracer, string()));
+ addGetStat("memory-allocated", boost::bind(&MallocTracer::getTotAllocated, g_mtracer, string()));
+#endif
}
static void doExitGeneric(bool nicely)