summaryrefslogtreecommitdiff
path: root/src/shared/leaktrace.cpp
blob: 73786c6b724f6428954b64f147b142236c972397 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "leaktrace.h"
#include "stackdata.h"
#include <Windows.h>
#include <DbgHelp.h>
#include <set>
#include <map>
#include <vector>
#include <sstream>
#include <algorithm>


using namespace MOShared;


static struct __TraceData {
  void regTrace(void *pointer, const char *functionName, int line) {
    m_Traces[reinterpret_cast<unsigned long>(pointer)] = StackData(functionName, line);
  }
  void deregTrace(void *pointer) {
    auto iter = m_Traces.find(reinterpret_cast<unsigned long>(pointer));
    if (iter != m_Traces.end()) {
      m_Traces.erase(iter);
    }
  }

  ~__TraceData() {
    std::map<StackData, std::vector<unsigned long> > result;
    for (auto iter = m_Traces.begin(); iter != m_Traces.end(); ++iter) {
      result[iter->second].push_back(iter->first);
    }
    for (auto iter = result.begin(); iter != result.end(); ++iter) {
      printf("-----------------------------------\n"
             "%d objects not freed, allocated at:\n%s",
             iter->second.size(), iter->first.toString().c_str());
      printf("Addresses: ");
      for (int i = 0; i < (std::min<int>)(5, iter->second.size()); ++i) {
        printf("%p, ", reinterpret_cast<void*>(iter->second[i]));
      }
      printf("\n");
    }
  }

  std::map<unsigned long, StackData> m_Traces;

} __trace;


void LeakTrace::TraceAlloc(void *ptr, const char *functionName, int line)
{
  __trace.regTrace(ptr, functionName, line);
}

void LeakTrace::TraceDealloc(void *ptr)
{
  __trace.deregTrace(ptr);
}