summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util')
-rw-r--r--src/mongo/util/allocator.cpp54
-rw-r--r--src/mongo/util/allocator.h33
-rw-r--r--src/mongo/util/intrusive_counter.h3
-rw-r--r--src/mongo/util/logfile.cpp3
-rw-r--r--src/mongo/util/mmap_mm.cpp4
-rw-r--r--src/mongo/util/net/message.h5
-rw-r--r--src/mongo/util/net/message_port.cpp3
-rw-r--r--src/mongo/util/signal_handlers_synchronous.cpp17
-rw-r--r--src/mongo/util/signal_handlers_synchronous.h10
-rw-r--r--src/mongo/util/text.cpp5
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;