Index: base/win_util.cc |
=================================================================== |
--- base/win_util.cc (revision 9063) |
+++ base/win_util.cc (working copy) |
@@ -4,12 +4,15 @@ |
#include "base/win_util.h" |
+#include <map> |
#include <sddl.h> |
#include "base/logging.h" |
#include "base/registry.h" |
#include "base/scoped_handle.h" |
+#include "base/singleton.h" |
#include "base/string_util.h" |
+#include "base/tracked.h" |
namespace win_util { |
@@ -361,6 +364,66 @@ |
return FormatMessage(GetLastError()); |
} |
+typedef std::map<HWND, tracked_objects::Location> HWNDInfoMap; |
+struct HWNDBirthMapTrait : public DefaultSingletonTraits<HWNDInfoMap> { |
+}; |
+struct HWNDDeathMapTrait : public DefaultSingletonTraits<HWNDInfoMap> { |
+}; |
+ |
+void NotifyHWNDCreation(const tracked_objects::Location& from_here, HWND hwnd) { |
+ HWNDInfoMap* birth_map = Singleton<HWNDInfoMap, HWNDBirthMapTrait>::get(); |
+ HWNDInfoMap::iterator birth_iter = birth_map->find(hwnd); |
+ if (birth_iter != birth_map->end()) { |
+ birth_map->erase(birth_iter); |
+ |
+ // We have already seen this HWND, was it destroyed? |
+ HWNDInfoMap* death_map = Singleton<HWNDInfoMap, HWNDDeathMapTrait>::get(); |
+ HWNDInfoMap::iterator death_iter = death_map->find(hwnd); |
+ if (death_iter == death_map->end()) { |
+ // We did not get a destruction notification. The code is probably not |
+ // calling NotifyHWNDDestruction for that HWND. |
+ NOTREACHED() << "Creation of HWND reported for already tracked HWND. The " |
+ "HWND destruction is probably not tracked properly. " |
+ "Fix it!"; |
+ } else { |
+ death_map->erase(death_iter); |
+ } |
+ } |
+ birth_map->insert(std::pair<HWND, tracked_objects::Location>(hwnd, |
+ from_here)); |
+} |
+ |
+void NotifyHWNDDestruction(const tracked_objects::Location& from_here, |
+ HWND hwnd) { |
+ HWNDInfoMap* death_map = Singleton<HWNDInfoMap, HWNDDeathMapTrait>::get(); |
+ HWNDInfoMap::iterator death_iter = death_map->find(hwnd); |
+ |
+ HWNDInfoMap* birth_map = Singleton<HWNDInfoMap, HWNDBirthMapTrait>::get(); |
+ HWNDInfoMap::iterator birth_iter = birth_map->find(hwnd); |
+ |
+ if (death_iter != death_map->end()) { |
+ std::string allocation, first_delete, second_delete; |
+ if (birth_iter != birth_map->end()) |
+ birth_iter->second.Write(true, true, &allocation); |
+ death_iter->second.Write(true, true, &first_delete); |
+ from_here.Write(true, true, &second_delete); |
+ NOTREACHED() << "Double delete of an HWND. Please file a bug with info on " |
+ "how you got that assertion and the following information:\n" |
+ "Double delete of HWND 0x" << hwnd << "\n" << |
sky
2009/02/03 20:37:24
will "<< hwnd" give you hex, or decimal?
|
+ "Allocated at " << allocation << "\n" << |
+ "Deleted first at " << first_delete << "\n" << |
+ "Deleted again at " << second_delete; |
+ death_map->erase(death_iter); |
+ } |
+ |
+ if (birth_iter == birth_map->end()) { |
+ NOTREACHED() << "Destruction of HWND reported for unknown HWND. The HWND " |
+ "construction is probably not tracked properly. Fix it!"; |
+ } |
+ death_map->insert(std::pair<HWND, tracked_objects::Location>(hwnd, |
+ from_here)); |
+} |
+ |
} // namespace win_util |
#ifdef _MSC_VER |