From bf32924282e38dddcb08d55af0a93825dc2720ed Mon Sep 17 00:00:00 2001 From: Christian Engwer <christi@dune-project.org> Date: Fri, 5 Oct 2012 09:11:34 +0000 Subject: [PATCH] [DebugAllocator] - check result of mprotect - unprotect memory upon free [[Imported from SVN: r7007]] --- dune/common/debug_allocator.hh | 43 ++++++++++++++++++++++------ dune/common/test/test-debug-alloc.cc | 2 +- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/dune/common/debug_allocator.hh b/dune/common/debug_allocator.hh index 82e86d2dc..67a6ba2d0 100644 --- a/dune/common/debug_allocator.hh +++ b/dune/common/debug_allocator.hh @@ -9,6 +9,7 @@ #include <sys/mman.h> #include <vector> #include <iostream> +#include <cstring> namespace Dune { @@ -49,6 +50,28 @@ namespace Dune typedef std::vector<AllocationInfo> AllocationList; AllocationList allocation_list; + private: + void memprotect(void* from, difference_type len, int prot) + { + int result = mprotect(from, len, prot); + if (result == -1) + { + + std::cerr << "ERROR: (" << result << ": " << strerror(result) << ")" << std::endl; + std::cerr << " Failed to "; + if (prot == PROT_NONE) + std::cerr << "protect "; + else + std::cerr << "unprotect "; + std::cerr << "memory range: " + << from << ", " + << static_cast<void*>( + static_cast<char*>(from) + len) + << std::endl; + abort(); + } + } + public: ~AllocationManager () @@ -78,17 +101,17 @@ namespace Dune ai.capacity = n * sizeof(T); ai.pages = (ai.capacity) / page_size + 2; ai.not_free = true; - size_type skip = ai.capacity % page_size; + size_type overlap = ai.capacity % page_size; ai.page_ptr = memalign(page_size, ai.pages * page_size); if (0 == ai.page_ptr) { throw std::bad_alloc(); } - ai.ptr = static_cast<char*>(ai.page_ptr) + page_size - skip; + ai.ptr = static_cast<char*>(ai.page_ptr) + page_size - overlap; // write protect memory behind the actual data - mprotect(static_cast<char*>(ai.page_ptr) + (ai.pages-1) * page_size, - page_size, - PROT_NONE); + memprotect(static_cast<char*>(ai.page_ptr) + (ai.pages-1) * page_size, + page_size, + PROT_NONE); // remember the chunk allocation_list.push_back(ai); // return the ptr @@ -120,10 +143,14 @@ namespace Dune it->not_free = false; #if DEBUG_ALLOCATOR_KEEP // write protect old memory - mprotect(it->page_ptr, - it->pages * page_size, - PROT_NONE); + memprotect(it->page_ptr, + (it->pages) * page_size, + PROT_NONE); #else + // unprotect old memory + memprotect(it->page_ptr, + (it->pages) * page_size, + PROT_READ | PROT_WRITE); free(it->page_ptr); // remove chunk info allocation_list.erase(it); diff --git a/dune/common/test/test-debug-alloc.cc b/dune/common/test/test-debug-alloc.cc index 5a3f0d95c..59f802acb 100644 --- a/dune/common/test/test-debug-alloc.cc +++ b/dune/common/test/test-debug-alloc.cc @@ -4,7 +4,7 @@ #include "config.h" #endif -#define DEBUG_ALLOCATOR_KEEP 1 +// #define DEBUG_ALLOCATOR_KEEP 1 // #define DEBUG_NEW_DELETE 3 #include <dune/common/debug_allocator.hh> -- GitLab