Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.6 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1992 - 1999
  5. *
  6. * File: stddbg.cpp
  7. *
  8. * Contents: Implementation file for CDebugLeakDetector
  9. *
  10. * History: 26-Oct-98 jeffro Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #ifdef DBG
  14. #include "windows.h"
  15. #include "stddbg.h"
  16. #include "tstring.h"
  17. #include <map>
  18. #include "atlbase.h" // USES_CONVERSION
  19. //############################################################################
  20. //############################################################################
  21. //
  22. // The safer string handling routines
  23. //
  24. //############################################################################
  25. //############################################################################
  26. #include <strsafe.h>
  27. DECLARE_INFOLEVEL(AMCCore);
  28. DECLARE_HEAPCHECKING;
  29. class CDebugLeakDetector : public CDebugLeakDetectorBase
  30. {
  31. public:
  32. CDebugLeakDetector()
  33. {}
  34. virtual ~CDebugLeakDetector()
  35. {
  36. DumpLeaks();
  37. }
  38. virtual void DumpLeaks()
  39. {
  40. RefCountsMap::iterator it;
  41. std::string strError;
  42. for (it = m_RefCounts.begin(); it != m_RefCounts.end(); ++it)
  43. {
  44. const std::string& strClass = it->first;
  45. int cRefs = it->second;
  46. if (cRefs != 0)
  47. {
  48. if (!strError.empty())
  49. strError += "\n";
  50. char szMessage[512];
  51. int cchMessage = 512;
  52. StringCchPrintfA (szMessage, cchMessage, "%s has %d instances left over",
  53. strClass.data(), cRefs);
  54. strError += szMessage;
  55. }
  56. }
  57. if (!strError.empty())
  58. ::MessageBoxA(NULL, strError.data(), "MMC: Memory Leaks!!!", MB_OK | MB_SERVICE_NOTIFICATION);
  59. }
  60. virtual int AddRef(const std::string& strClass)
  61. {
  62. return (++m_RefCounts[strClass]);
  63. }
  64. virtual int Release(const std::string& strClass)
  65. {
  66. /*
  67. * if this assert fails, you're releasing something that
  68. * hasn't been addref'd -- check the spelling in your
  69. * DEBUG_DECREMENT_INSTANCE_COUNTER macro usage
  70. */
  71. ASSERT (m_RefCounts.find (strClass) != m_RefCounts.end());
  72. /*
  73. * If this assert fails, you have excessive releases.
  74. * One possible cause of this is you might be using a
  75. * compiler-generated copy constructor for your object,
  76. * which won't call DEBUG_INCREMENT_INSTANCE_COUNTER.
  77. * Define your own copy constructor.
  78. */
  79. ASSERT (m_RefCounts[strClass] > 0);
  80. return (--m_RefCounts[strClass]);
  81. }
  82. private:
  83. class RefCounter
  84. {
  85. public:
  86. RefCounter() : m_cRefs(0) {}
  87. operator int()
  88. {
  89. return (m_cRefs);
  90. }
  91. int operator++() // pre-increment
  92. {
  93. return (++m_cRefs);
  94. }
  95. int operator++(int) // post-increment
  96. {
  97. int t = m_cRefs++;
  98. return (t);
  99. }
  100. operator--() // pre-decrement
  101. {
  102. return (--m_cRefs);
  103. }
  104. int operator--(int) // post-decrement
  105. {
  106. int t = m_cRefs--;
  107. return (t);
  108. }
  109. private:
  110. int m_cRefs;
  111. };
  112. typedef std::map<std::string, RefCounter> RefCountsMap;
  113. RefCountsMap m_RefCounts;
  114. };
  115. CDebugLeakDetectorBase& GetLeakDetector()
  116. {
  117. static CDebugLeakDetector detector;
  118. return (detector);
  119. }
  120. DBG_PersistTraceData::DBG_PersistTraceData() :
  121. bIComponent(false),
  122. bIComponentData(false),
  123. pTraceFN(NULL)
  124. {
  125. }
  126. void DBG_PersistTraceData::SetTraceInfo(DBG_PersistTraceData::PTraceErrorFn pFn, bool bComponent, const tstring& owner)
  127. {
  128. ASSERT(pFn);
  129. pTraceFN = pFn;
  130. bIComponent = bComponent;
  131. bIComponentData = !bComponent;
  132. strSnapin = owner;
  133. }
  134. void DBG_PersistTraceData::TraceErr(LPCTSTR strInterface, LPCTSTR msg)
  135. {
  136. if (!pTraceFN)
  137. return;
  138. tstring formatted;
  139. formatted += tstring(_T("\"")) + (strSnapin) + _T("\"");
  140. formatted += tstring(_T(" Interface ")) + strInterface;
  141. if (bIComponent)
  142. formatted += _T("[IComponent]");
  143. else if (bIComponentData)
  144. formatted += _T("[IComponentData]");
  145. formatted += _T(" - ");
  146. formatted += msg;
  147. pTraceFN(formatted.c_str());
  148. }
  149. #endif // DBG