diff options
Diffstat (limited to 'src/mongo/util')
-rw-r--r-- | src/mongo/util/allocator.cpp | 54 | ||||
-rw-r--r-- | src/mongo/util/allocator.h | 33 | ||||
-rw-r--r-- | src/mongo/util/intrusive_counter.h | 3 | ||||
-rw-r--r-- | src/mongo/util/logfile.cpp | 3 | ||||
-rw-r--r-- | src/mongo/util/mmap_mm.cpp | 4 | ||||
-rw-r--r-- | src/mongo/util/net/message.h | 5 | ||||
-rw-r--r-- | src/mongo/util/net/message_port.cpp | 3 | ||||
-rw-r--r-- | src/mongo/util/signal_handlers_synchronous.cpp | 17 | ||||
-rw-r--r-- | src/mongo/util/signal_handlers_synchronous.h | 10 | ||||
-rw-r--r-- | src/mongo/util/text.cpp | 5 |
10 files changed, 99 insertions, 38 deletions
diff --git a/src/mongo/util/allocator.cpp b/src/mongo/util/allocator.cpp new file mode 100644 index 00000000000..1bc7c69ef73 --- /dev/null +++ b/src/mongo/util/allocator.cpp @@ -0,0 +1,54 @@ +// allocator.cpp + +/* Copyright 2014 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include <cstdlib> + +#include "mongo/util/signal_handlers_synchronous.h" + +namespace mongo { + + void* mongoMalloc(size_t size) { + void* x = std::malloc(size); + if (x == NULL) { + reportOutOfMemoryErrorAndExit(); + } + return x; + } + + void* mongoRealloc(void *ptr, size_t size) { + void* x = std::realloc(ptr, size); + if (x == NULL) { + reportOutOfMemoryErrorAndExit(); + } + return x; + } + +} // namespace mongo diff --git a/src/mongo/util/allocator.h b/src/mongo/util/allocator.h index 3851f2a5184..ee3edf05b80 100644 --- a/src/mongo/util/allocator.h +++ b/src/mongo/util/allocator.h @@ -29,29 +29,20 @@ #pragma once -#include <stdlib.h> - -// we need the "real" malloc here -#include "mongo/client/undef_macros.h" +#include <cstddef> namespace mongo { - inline void * ourmalloc(size_t size) { - void *x = malloc(size); - if ( x == 0 ) abort(); - return x; - } - - inline void * ourrealloc(void *ptr, size_t size) { - void *x = realloc(ptr, size); - if ( x == 0 ) abort(); - return x; - } - -#define MONGO_malloc ::mongo::ourmalloc -#define MONGO_realloc ::mongo::ourrealloc - -// this redefines 'malloc' to 'MONGO_malloc', etc -#include "mongo/client/redef_macros.h" + /** + * Wrapper around std::malloc(). + * If std::malloc() fails, reports error with stack trace and exit. + */ + void* mongoMalloc(size_t size); + + /** + * Wrapper around std::realloc(). + * If std::realloc() fails, reports error with stack trace and exit. + */ + void* mongoRealloc(void* ptr, size_t size); } // namespace mongo diff --git a/src/mongo/util/intrusive_counter.h b/src/mongo/util/intrusive_counter.h index 911203085d1..7b9fac3b7b1 100644 --- a/src/mongo/util/intrusive_counter.h +++ b/src/mongo/util/intrusive_counter.h @@ -32,6 +32,7 @@ #include <boost/noncopyable.hpp> #include "mongo/platform/atomic_word.h" #include "mongo/base/string_data.h" +#include "mongo/util/allocator.h" namespace mongo { @@ -128,7 +129,7 @@ namespace mongo { private: // these can only be created by calling create() RCString() {}; - void* operator new (size_t objSize, size_t realSize) { return malloc(realSize); } + void* operator new (size_t objSize, size_t realSize) { return mongoMalloc(realSize); } int _size; // does NOT include trailing NUL byte. // char[_size+1] array allocated past end of class diff --git a/src/mongo/util/logfile.cpp b/src/mongo/util/logfile.cpp index b8d28e3cfa7..a6ca4c267d4 100644 --- a/src/mongo/util/logfile.cpp +++ b/src/mongo/util/logfile.cpp @@ -33,6 +33,7 @@ #include "mongo/util/logfile.h" #include "mongo/platform/posix_fadvise.h" +#include "mongo/util/allocator.h" #include "mongo/util/log.h" #include "mongo/util/mmap.h" #include "mongo/util/mongoutils/str.h" @@ -49,7 +50,7 @@ namespace mongo { if( 0 && debug ) { try { LogFile f("logfile_test"); - void *p = malloc(16384); + void *p = mongoMalloc(16384); char *buf = (char*) p; buf += 4095; buf = (char*) (((size_t)buf)&(~0xfff)); diff --git a/src/mongo/util/mmap_mm.cpp b/src/mongo/util/mmap_mm.cpp index 0b300ee313b..480bb21f62b 100644 --- a/src/mongo/util/mmap_mm.cpp +++ b/src/mongo/util/mmap_mm.cpp @@ -31,6 +31,8 @@ #include "mongo/util/mmap.h" +#include "mongo/util/allocator.h" + /* in memory (no file) version */ namespace mongo { @@ -51,7 +53,7 @@ namespace mongo { void* MemoryMappedFile::map(const char *filename, long& length , int options ) { verify( length ); - view = malloc( length ); + view = mongoMalloc( length ); return view; } diff --git a/src/mongo/util/net/message.h b/src/mongo/util/net/message.h index 3c7bffa7654..0fd7ac22312 100644 --- a/src/mongo/util/net/message.h +++ b/src/mongo/util/net/message.h @@ -35,6 +35,7 @@ #include "mongo/platform/cstdint.h" #include "mongo/base/data_view.h" #include "mongo/base/encoded_value_storage.h" +#include "mongo/util/allocator.h" #include "mongo/util/goodies.h" #include "mongo/util/mongoutils/str.h" #include "mongo/util/net/hostandport.h" @@ -379,7 +380,7 @@ namespace mongo { i != _data.end(); ++i) { totalSize += i->second; } - char *buf = (char*)malloc( totalSize ); + char *buf = (char*)mongoMalloc( totalSize ); char *p = buf; for (std::vector< std::pair< char *, int > >::const_iterator i = _data.begin(); i != _data.end(); ++i) { @@ -451,7 +452,7 @@ namespace mongo { void setData(int operation, const char *msgdata, size_t len) { verify( empty() ); size_t dataLen = len + sizeof(MsgData::Value) - 4; - MsgData::View d = reinterpret_cast<char *>(malloc(dataLen)); + MsgData::View d = reinterpret_cast<char *>(mongoMalloc(dataLen)); memcpy(d.data(), msgdata, len); d.setLen(dataLen); d.setOperation(operation); diff --git a/src/mongo/util/net/message_port.cpp b/src/mongo/util/net/message_port.cpp index 15d0a626a1b..ab1742f55af 100644 --- a/src/mongo/util/net/message_port.cpp +++ b/src/mongo/util/net/message_port.cpp @@ -36,6 +36,7 @@ #include <fcntl.h> #include <time.h> +#include "mongo/util/allocator.h" #include "mongo/util/background.h" #include "mongo/util/goodies.h" #include "mongo/util/log.h" @@ -228,7 +229,7 @@ again: psock->setHandshakeReceived(); int z = (len+1023)&0xfffffc00; verify(z>=len); - MsgData::View md = reinterpret_cast<char *>(malloc(z)); + MsgData::View md = reinterpret_cast<char *>(mongoMalloc(z)); ScopeGuard guard = MakeGuard(free, md.view2ptr()); verify(md.view2ptr()); diff --git a/src/mongo/util/signal_handlers_synchronous.cpp b/src/mongo/util/signal_handlers_synchronous.cpp index 9453e64801d..a666ab1a150 100644 --- a/src/mongo/util/signal_handlers_synchronous.cpp +++ b/src/mongo/util/signal_handlers_synchronous.cpp @@ -135,14 +135,6 @@ namespace { ::_exit(EXIT_ABRUPT); } - // this gets called when new fails to allocate memory - void myNewHandler() { - boost::mutex::scoped_lock lk(streamMutex); - printStackTrace(mallocFreeOStream << "out of memory.\n"); - writeMallocFreeStreamToLog(); - ::_exit(EXIT_ABRUPT); - } - void abruptQuit(int signalNum) { boost::mutex::scoped_lock lk(streamMutex); printSignalAndBacktrace(signalNum); @@ -203,7 +195,7 @@ namespace { void setupSynchronousSignalHandlers() { std::set_terminate(myTerminate); - std::set_new_handler(myNewHandler); + std::set_new_handler(reportOutOfMemoryErrorAndExit); // SIGABRT is the only signal we want handled by signal handlers on both windows and posix. invariant(signal(SIGABRT, abruptQuit) != SIG_ERR); @@ -231,4 +223,11 @@ namespace { setupSIGTRAPforGDB(); #endif } + + void reportOutOfMemoryErrorAndExit() { + boost::mutex::scoped_lock lk(streamMutex); + printStackTrace(mallocFreeOStream << "out of memory.\n"); + writeMallocFreeStreamToLog(); + ::_exit(EXIT_ABRUPT); + } } // namespace mongo diff --git a/src/mongo/util/signal_handlers_synchronous.h b/src/mongo/util/signal_handlers_synchronous.h index 516e1d3acca..518fce03156 100644 --- a/src/mongo/util/signal_handlers_synchronous.h +++ b/src/mongo/util/signal_handlers_synchronous.h @@ -40,4 +40,14 @@ namespace mongo { */ void setupSynchronousSignalHandlers(); + /** + * Report out of memory error with a stack trace and exit. + * + * Called when any of the following functions fails to allocate memory: + * operator new + * mongoMalloc + * mongoRealloc + */ + void reportOutOfMemoryErrorAndExit(); + } // namespace mongo diff --git a/src/mongo/util/text.cpp b/src/mongo/util/text.cpp index 5c3693901d1..1a11222613d 100644 --- a/src/mongo/util/text.cpp +++ b/src/mongo/util/text.cpp @@ -39,6 +39,7 @@ #endif #include "mongo/platform/basic.h" +#include "mongo/util/allocator.h" #include "mongo/util/mongoutils/str.h" using namespace std; @@ -303,7 +304,7 @@ namespace mongo { utf8argLength.push_back(argLength); blockSize += argLength; } - _argv = static_cast<char**>(malloc(blockSize)); + _argv = static_cast<char**>(mongoMalloc(blockSize)); for (int i = 0; i < argc; ++i) { _argv[i] = reinterpret_cast<char*>(_argv) + blockPtr; strcpy_s(_argv[i], utf8argLength[i], utf8args[i].c_str()); @@ -326,7 +327,7 @@ namespace mongo { utf8envLength.push_back(envLength); blockSize += envLength; } - _envp = static_cast<char**>(malloc(blockSize)); + _envp = static_cast<char**>(mongoMalloc(blockSize)); size_t i; for (i = 0; i < envCount; ++i) { _envp[i] = reinterpret_cast<char*>(_envp) + blockPtr; |