libfoedus-core
FOEDUS Core Library
foedus::assorted::ProtectedBoundary Struct Reference

A 4kb dummy data placed between separate memory regions so that we can check if/where a bogus memory access happens. More...

Detailed Description

A 4kb dummy data placed between separate memory regions so that we can check if/where a bogus memory access happens.

As a middleware, we often allocate a large chunk of memory and internally split it into smaller data regions. While it reduces overheads, that means a lack of memory boundary check. Instead, we place this dummy block to achieve it. When we shut down the system, we check if there happened any unexpected overrun between memory regions. In addition, we also use mprotect() to prohibit accesses to these dummy blocks, which would immediately fire up SIGSEGV for bogus access, making debugging easier.

mprotect() limit: max_map_count
mprotect() has one limitation: it could use up max_map_count. What you might observe is after around 64k mprotect() calls, it starts failing with ENOMEM. Moreover, all following memory allocations (eg mmap) also fail with ENOMEM once this starts happening. The issue goes away by increasing max_map_count : sudo sysctl -w vm.max_map_count=2147483647

Definition at line 56 of file protected_boundary.hpp.

#include <protected_boundary.hpp>

Public Types

enum  Constants { kByteSize = 1 << 12, kMaxBoundaryNameLength = 128, kWordCount = (kByteSize - kMaxBoundaryNameLength) / 8 }
 

Public Member Functions

ErrorCode acquire_protect ()
 Puts a strict access prohibition via mprotect(). More...
 
ErrorCode release_protect ()
 Removes all access restrictions via mprotect(). More...
 
void reset (const std::string &boundary_name)
 Fills the block with magic words. More...
 
void assert_boundary () const
 Called at shutdown to check whether these boundaries were not accessed. More...
 
std::string get_boundary_name () const
 

Public Attributes

char boundary_name_ [kMaxBoundaryNameLength]
 
uint64_t data_ [kWordCount]
 

Member Enumeration Documentation

Member Function Documentation

ErrorCode foedus::assorted::ProtectedBoundary::acquire_protect ( )

Puts a strict access prohibition via mprotect().

Attention
This method might cause severe performance degradation. Use in appropriate places. We use hugepages in most places, but mprotect() most likely splits the TLB entries to achieve the protection, throwing away the performance benefits of hugepages.
Note
this method is idempotent. safe to call multiple times
Returns
The only possible error is kErrorCodeOsMProtectFailed

Definition at line 25 of file protected_boundary.cpp.

References foedus::kErrorCodeOk, and foedus::kErrorCodeOsMProtectFailed.

Referenced by foedus::memory::PagePoolPimpl::initialize_once().

25  {
26  int ret = ::mprotect(this, sizeof(ProtectedBoundary), PROT_NONE);
27  if (ret != 0) {
29  }
30  return kErrorCodeOk;
31 }
0x000D : "GENERAL: OS: mprotect() failed." .
Definition: error_code.hpp:118
0 means no-error.
Definition: error_code.hpp:87

Here is the caller graph for this function:

void foedus::assorted::ProtectedBoundary::assert_boundary ( ) const
inline

Called at shutdown to check whether these boundaries were not accessed.

Attention
This must be invoked AFTER release_protect()

Definition at line 103 of file protected_boundary.hpp.

References ASSERT_ND, and kWordCount.

Referenced by foedus::soc::SharedMemoryRepo::deallocate_shared_memories(), and foedus::memory::PagePoolPimpl::uninitialize_once().

103  {
104  for (uint32_t i = 0; i < kWordCount; ++i) {
106  }
107  }
const uint64_t kProtectedBoundaryMagicWord
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72

Here is the caller graph for this function:

std::string foedus::assorted::ProtectedBoundary::get_boundary_name ( ) const
inline

Definition at line 109 of file protected_boundary.hpp.

References ASSERT_ND, and kMaxBoundaryNameLength.

Referenced by foedus::memory::PagePoolPimpl::uninitialize_once().

109  {
110  uint16_t len;
111  for (len = 0; len < kMaxBoundaryNameLength; ++len) {
112  if (boundary_name_[len] == 0) {
113  break;
114  }
115  }
116  ASSERT_ND(len < kMaxBoundaryNameLength);
117  return std::string(boundary_name_, len);
118  }
char boundary_name_[kMaxBoundaryNameLength]
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72

Here is the caller graph for this function:

ErrorCode foedus::assorted::ProtectedBoundary::release_protect ( )

Removes all access restrictions via mprotect().

Attention
This method might cause severe performance hit. Use in appropriate places.
Note
this method is idempotent. safe to call multiple times
Returns
The only possible error is kErrorCodeOsMProtectFailed

Definition at line 33 of file protected_boundary.cpp.

References foedus::kErrorCodeOk, and foedus::kErrorCodeOsMProtectFailed.

Referenced by foedus::soc::SharedMemoryRepo::deallocate_shared_memories(), and foedus::memory::PagePoolPimpl::uninitialize_once().

33  {
34  int ret = ::mprotect(this, sizeof(ProtectedBoundary), PROT_READ | PROT_WRITE);
35  if (ret != 0) {
37  }
38  return kErrorCodeOk;
39 }
0x000D : "GENERAL: OS: mprotect() failed." .
Definition: error_code.hpp:118
0 means no-error.
Definition: error_code.hpp:87

Here is the caller graph for this function:

void foedus::assorted::ProtectedBoundary::reset ( const std::string &  boundary_name)
inline

Fills the block with magic words.

Attention
This must be invoked BEFORE acquire_protect()

Definition at line 88 of file protected_boundary.hpp.

References kMaxBoundaryNameLength, foedus::assorted::kProtectedBoundaryMagicWord, and kWordCount.

Referenced by foedus::memory::PagePoolPimpl::initialize_once().

88  {
89  uint16_t copy_len = std::min<uint64_t>(boundary_name.length(), kMaxBoundaryNameLength);
90  boundary_name.copy(boundary_name_, copy_len, 0);
91  if (copy_len < kMaxBoundaryNameLength) {
92  std::memset(boundary_name_ + copy_len, 0, kMaxBoundaryNameLength- copy_len);
93  }
94  for (uint32_t i = 0; i < kWordCount; ++i) {
96  }
97  }
char boundary_name_[kMaxBoundaryNameLength]
const uint64_t kProtectedBoundaryMagicWord

Here is the caller graph for this function:

Member Data Documentation

char foedus::assorted::ProtectedBoundary::boundary_name_[kMaxBoundaryNameLength]

Definition at line 63 of file protected_boundary.hpp.

uint64_t foedus::assorted::ProtectedBoundary::data_[kWordCount]

Definition at line 64 of file protected_boundary.hpp.


The documentation for this struct was generated from the following files: