Permalink
Browse files

Fix memory management crashes in debug mode.

This changeset only changes code inside #ifndef TPIE_NDEBUG-blocks.

Make the following memory_manager methods private:

void __register_pointer(void * p, size_t size, const std::type_info & t);
void __unregister_pointer(void * p, size_t size, const std::type_info & t);
void __assert_tpie_ptr(void * p);
void __complain_about_unfreed_memory();

Introduce non-doubly-underscored public counterparts that acquire the
memory manager mutex before calling the private methods.
  • Loading branch information...
1 parent 993ec7c commit 91b940b906f14fb8b05cd67483e619351b956d45 @Mortal Mortal committed Dec 4, 2012
Showing with 37 additions and 8 deletions.
  1. +21 −1 tpie/memory.cpp
  2. +16 −7 tpie/memory.h
View
@@ -180,6 +180,11 @@ std::pair<uint8_t *, size_t> memory_manager::__allocate_consecutive(size_t upper
#ifndef TPIE_NDEBUG
+void memory_manager::register_pointer(void * p, size_t size, const std::type_info & t) {
+ boost::mutex::scoped_lock lock(m_mutex);
+ __register_pointer(p, size, t);
+}
+
void memory_manager::__register_pointer(void * p, size_t size, const std::type_info & t) {
if (m_pointers.count(p) != 0) {
log_error() << "Trying to register pointer " << p << " of size "
@@ -189,6 +194,11 @@ void memory_manager::__register_pointer(void * p, size_t size, const std::type_i
m_pointers[p] = std::make_pair(size, &t);;
}
+void memory_manager::unregister_pointer(void * p, size_t size, const std::type_info & t) {
+ boost::mutex::scoped_lock lock(m_mutex);
+ __unregister_pointer(p, size, t);
+}
+
void memory_manager::__unregister_pointer(void * p, size_t size, const std::type_info & t) {
boost::unordered_map<void *, std::pair<size_t, const std::type_info *> >::const_iterator i=m_pointers.find(p);
if (i == m_pointers.end()) {
@@ -210,12 +220,22 @@ void memory_manager::__unregister_pointer(void * p, size_t size, const std::type
}
}
+void memory_manager::assert_tpie_ptr(void * p) {
+ boost::mutex::scoped_lock lock(m_mutex);
+ __assert_tpie_ptr(p);
+}
+
void memory_manager::__assert_tpie_ptr(void * p) {
if (!p || m_pointers.count(p)) return;
log_error() << p << " has not been allocated with tpie_new" << std::endl;
segfault();
}
+void memory_manager::complain_about_unfreed_memory() {
+ boost::mutex::scoped_lock lock(m_mutex);
+ __complain_about_unfreed_memory();
+}
+
void memory_manager::__complain_about_unfreed_memory() {
if(m_pointers.size() == 0) return;
log_error() << "The following pointers were either leaked or deleted with delete instead of tpie_delete" << std::endl << std::endl;
@@ -232,7 +252,7 @@ void init_memory_manager() {
void finish_memory_manager() {
#ifndef TPIE_NDEBUG
- mm->__complain_about_unfreed_memory();
+ mm->complain_about_unfreed_memory();
#endif
delete mm;
mm = 0;
View
@@ -127,10 +127,12 @@ class memory_manager {
std::pair<uint8_t *, size_t> __allocate_consecutive(size_t upper_bound, size_t granularity);
#ifndef TPIE_NDEBUG
- void __register_pointer(void * p, size_t size, const std::type_info & t);
- void __unregister_pointer(void * p, size_t size, const std::type_info & t);
- void __assert_tpie_ptr(void * p);
- void __complain_about_unfreed_memory();
+ // The following methods take the mutex before calling the private doubly
+ // underscored equivalent.
+ void register_pointer(void * p, size_t size, const std::type_info & t);
+ void unregister_pointer(void * p, size_t size, const std::type_info & t);
+ void assert_tpie_ptr(void * p);
+ void complain_about_unfreed_memory();
#endif
@@ -141,7 +143,14 @@ class memory_manager {
size_t m_nextWarning;
enforce_t m_enforce;
boost::mutex m_mutex;
+
#ifndef TPIE_NDEBUG
+ // Before calling these methods, you must have the mutex.
+ void __register_pointer(void * p, size_t size, const std::type_info & t);
+ void __unregister_pointer(void * p, size_t size, const std::type_info & t);
+ void __assert_tpie_ptr(void * p);
+ void __complain_about_unfreed_memory();
+
boost::unordered_map<void *, std::pair<size_t, const std::type_info *> > m_pointers;
#endif
};
@@ -169,7 +178,7 @@ memory_manager & get_memory_manager();
///////////////////////////////////////////////////////////////////////////////
inline void __register_pointer(void * p, size_t size, const std::type_info & t) {
#ifndef TPIE_NDEBUG
- get_memory_manager().__register_pointer(p, size, t);
+ get_memory_manager().register_pointer(p, size, t);
#else
unused(p);
unused(size);
@@ -183,7 +192,7 @@ inline void __register_pointer(void * p, size_t size, const std::type_info & t)
///////////////////////////////////////////////////////////////////////////////
inline void __unregister_pointer(void * p, size_t size, const std::type_info & t) {
#ifndef TPIE_NDEBUG
- get_memory_manager().__unregister_pointer(p, size, t);
+ get_memory_manager().unregister_pointer(p, size, t);
#else
unused(p);
unused(size);
@@ -198,7 +207,7 @@ inline void __unregister_pointer(void * p, size_t size, const std::type_info & t
inline void assert_tpie_ptr(void * p) {
#ifndef TPIE_NDEBUG
if (p)
- get_memory_manager().__assert_tpie_ptr(p);
+ get_memory_manager().assert_tpie_ptr(p);
#else
unused(p);
#endif

0 comments on commit 91b940b

Please sign in to comment.