diff options
author | Benety Goh <benety@mongodb.com> | 2014-08-13 16:02:17 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2014-08-15 01:44:41 -0400 |
commit | be05259d36ec5f44c821c8f2d103a4ee83ebaf53 (patch) | |
tree | 08564e54e580e6dde94b7a5e89e8c4021fa457ef /src/mongo | |
parent | 7a1a0ce4ca6bbdf047adc7528310078ef7ca08f8 (diff) | |
download | mongo-be05259d36ec5f44c821c8f2d103a4ee83ebaf53.tar.gz |
SERVER-14889 wrapped all malloc/realloc calls within src/mongo with mongoMalloc/mongoRealloc.
if memory allocation fails, report error and exit.
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/SConscript | 38 | ||||
-rw-r--r-- | src/mongo/bson/bsonobj.cpp | 3 | ||||
-rw-r--r-- | src/mongo/bson/util/builder.h | 11 | ||||
-rw-r--r-- | src/mongo/client/examples/mongoperf.cpp | 3 | ||||
-rw-r--r-- | src/mongo/client/redef_macros.h | 10 | ||||
-rw-r--r-- | src/mongo/client/sasl_client_session.cpp | 9 | ||||
-rw-r--r-- | src/mongo/client/undef_macros.h | 8 | ||||
-rw-r--r-- | src/mongo/db/auth/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp | 3 | ||||
-rw-r--r-- | src/mongo/dbtests/jsobjtests.cpp | 5 | ||||
-rw-r--r-- | src/mongo/dbtests/perftests.cpp | 3 | ||||
-rw-r--r-- | src/mongo/util/allocator.cpp (renamed from src/mongo/dbtests/macrotests.cpp) | 62 | ||||
-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 |
21 files changed, 123 insertions, 116 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index c3945e2b154..d9b6d20e92f 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -341,7 +341,10 @@ if env['MONGO_BUILD_SASL_CLIENT']: env.Library('sasl_client_session', ['client/sasl_client_session.cpp', 'client/sasl_sspi.cpp'], - LIBDEPS=['foundation'], + LIBDEPS = [ + 'foundation', + 'signal_handlers_synchronous', + ], SYSLIBDEPS=saslLibs) commonFiles.extend(['client/sasl_client_authenticate_impl.cpp']) extraCommonLibdeps.append('sasl_client_session') @@ -936,7 +939,8 @@ serveronlyEnv.Library("serveronly", serverOnlyFiles, env.Library("message_server_port", "util/net/message_server_port.cpp") env.Library("signal_handlers_synchronous", - ['util/signal_handlers_synchronous.cpp',], + ['util/signal_handlers_synchronous.cpp', + 'util/allocator.cpp',], LIBDEPS=["stacktrace", "foundation"] ) @@ -1031,7 +1035,10 @@ env.Library("mongofiles_options", ["tools/mongofiles_options.cpp"], env.Library("bsondump_options", ["tools/bsondump_options.cpp"], LIBDEPS=['tool_options']) env.Library("mongobridge_options", ["tools/mongobridge_options.cpp"], - LIBDEPS=['tool_options']) + LIBDEPS = [ + 'tool_options', + 'signal_handlers_synchronous', + ]) env.Install( '#/', [ env.Program( "mongofiles", ["tools/files.cpp", "tools/mongofiles_options_init.cpp"], @@ -1041,7 +1048,12 @@ env.Install( '#/', [ env.Program( "mongobridge", ["tools/bridge.cpp", "tools/mongobridge_options_init.cpp"], LIBDEPS=["serveronly", "coreserver", "coredb", "mongobridge_options"] ), env.Program( "mongoperf", "client/examples/mongoperf.cpp", - LIBDEPS=["serveronly", "coreserver", "coredb"] ), + LIBDEPS = [ + "serveronly", + "coreserver", + "coredb", + "signal_handlers_synchronous", + ] ), ] ) # mongos options @@ -1100,6 +1112,7 @@ test = env.Install( "coredb", "testframework", "gridfs", + "signal_handlers_synchronous", "s/upgrade", "s/cluster_ops", "s/cluster_ops_impl", @@ -1113,7 +1126,14 @@ test = env.Install( if len(env.subst('$PROGSUFFIX')): env.Alias( "dbtest", "#/${PROGPREFIX}dbtest${PROGSUFFIX}" ) -env.Install( '#/', env.Program( "perftest", [ "dbtests/perf/perftest.cpp" ], LIBDEPS=["serveronly", "coreserver", "coredb", "testframework" ] ) ) +env.Install( '#/', env.Program( "perftest", [ "dbtests/perf/perftest.cpp" ], + LIBDEPS = [ + "serveronly", + "coreserver", + "coredb", + "testframework", + "signal_handlers_synchronous", + ] ) ) # --- sniffer --- mongosniff_built = False @@ -1128,7 +1148,13 @@ if darwin or env["_HAVEPCAP"]: sniffEnv.Append( LIBS=[ "wpcap" ] ) sniffEnv.Install( '#/', sniffEnv.Program( "mongosniff", "tools/sniffer.cpp", - LIBDEPS=["gridfs", "serveronly", "coreserver", "coredb"])) + LIBDEPS = [ + "gridfs", + "serveronly", + "coreserver", + "coredb", + "signal_handlers_synchronous", + ] ) ) # --- shell --- diff --git a/src/mongo/bson/bsonobj.cpp b/src/mongo/bson/bsonobj.cpp index 95f93485d5c..f4f8bd06849 100644 --- a/src/mongo/bson/bsonobj.cpp +++ b/src/mongo/bson/bsonobj.cpp @@ -31,6 +31,7 @@ #include "mongo/bson/bson_validate.h" #include "mongo/db/json.h" +#include "mongo/util/allocator.h" #include "mongo/util/log.h" #include "mongo/util/md5.hpp" #include "mongo/util/mongoutils/str.h" @@ -69,7 +70,7 @@ namespace mongo { } BSONObj BSONObj::copy() const { - Holder *h = (Holder*) malloc(objsize() + sizeof(unsigned)); + Holder *h = (Holder*) mongoMalloc(objsize() + sizeof(unsigned)); h->zero(); memcpy(h->data, objdata(), objsize()); return BSONObj(h); diff --git a/src/mongo/bson/util/builder.h b/src/mongo/bson/util/builder.h index 00924458e7a..38e24b59d5f 100644 --- a/src/mongo/bson/util/builder.h +++ b/src/mongo/bson/util/builder.h @@ -38,6 +38,7 @@ #include "mongo/bson/inline_decls.h" #include "mongo/base/string_data.h" +#include "mongo/util/allocator.h" #include "mongo/util/assert_util.h" namespace mongo { @@ -74,8 +75,8 @@ namespace mongo { class TrivialAllocator { public: - void* Malloc(size_t sz) { return malloc(sz); } - void* Realloc(void *p, size_t sz) { return realloc(p, sz); } + void* Malloc(size_t sz) { return mongoMalloc(sz); } + void* Realloc(void *p, size_t sz) { return mongoRealloc(p, sz); } void Free(void *p) { free(p); } }; @@ -84,18 +85,18 @@ namespace mongo { enum { SZ = 512 }; void* Malloc(size_t sz) { if( sz <= SZ ) return buf; - return malloc(sz); + return mongoMalloc(sz); } void* Realloc(void *p, size_t sz) { if( p == buf ) { if( sz <= SZ ) return buf; - void *d = malloc(sz); + void *d = mongoMalloc(sz); if ( d == 0 ) msgasserted( 15912 , "out of memory StackAllocator::Realloc" ); memcpy(d, p, SZ); return d; } - return realloc(p, sz); + return mongoRealloc(p, sz); } void Free(void *p) { if( p != buf ) diff --git a/src/mongo/client/examples/mongoperf.cpp b/src/mongo/client/examples/mongoperf.cpp index 40def7265f1..d6d5bd00002 100644 --- a/src/mongo/client/examples/mongoperf.cpp +++ b/src/mongo/client/examples/mongoperf.cpp @@ -47,6 +47,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/json.h" #include "mongo/platform/atomic_word.h" +#include "mongo/util/allocator.h" #include "mongo/util/logfile.h" #include "mongo/util/mmap.h" #include "mongo/util/mongoutils/str.h" @@ -174,7 +175,7 @@ void go() { } lf = new LogFile(fname,true); const unsigned sz = 1024 * 1024 * 32; // needs to be big as we are using synchronousAppend. if we used a regular MongoFile it wouldn't have to be - char *buf = (char*) malloc(sz+4096); + char *buf = (char*) mongoMalloc(sz+4096); const char *p = round(buf); for( unsigned long long i = 0; i < len; i += sz ) { lf->synchronousAppend(p, sz); diff --git a/src/mongo/client/redef_macros.h b/src/mongo/client/redef_macros.h index b52f3e53a75..70eb992ff12 100644 --- a/src/mongo/client/redef_macros.h +++ b/src/mongo/client/redef_macros.h @@ -34,16 +34,6 @@ #define MONGO_MACROS_PUSHED 1 -// util/allocator.h -#ifdef MONGO_MALLOC -#pragma push_macro("malloc") -#undef malloc -#define malloc MONGO_malloc -#pragma push_macro("realloc") -#undef realloc -#define realloc MONGO_realloc -#endif - // util/assert_util.h #pragma push_macro("verify") #undef verify diff --git a/src/mongo/client/sasl_client_session.cpp b/src/mongo/client/sasl_client_session.cpp index ba7a8d93138..872c2043e18 100644 --- a/src/mongo/client/sasl_client_session.cpp +++ b/src/mongo/client/sasl_client_session.cpp @@ -32,6 +32,7 @@ #include "mongo/util/assert_util.h" #include "mongo/util/concurrency/mutex.h" #include "mongo/util/mongoutils/str.h" +#include "mongo/util/signal_handlers_synchronous.h" namespace mongo { namespace { @@ -51,17 +52,19 @@ namespace { typedef int(*SaslCallbackFn)(); void* saslOurMalloc(SaslAllocSize sz) { - return ourmalloc(sz); + return mongoMalloc(sz); } void* saslOurCalloc(SaslAllocSize count, SaslAllocSize size) { void* ptr = calloc(count, size); - if (!ptr) abort(); + if (!ptr) { + reportOutOfMemoryErrorAndExit(); + } return ptr; } void* saslOurRealloc(void* ptr, SaslAllocSize sz) { - return ourrealloc(ptr, sz); + return mongoRealloc(ptr, sz); } /* diff --git a/src/mongo/client/undef_macros.h b/src/mongo/client/undef_macros.h index 4a32928edcf..cf5350989db 100644 --- a/src/mongo/client/undef_macros.h +++ b/src/mongo/client/undef_macros.h @@ -33,14 +33,6 @@ #ifdef MONGO_MACROS_PUSHED -// util/allocator.h -#ifdef MONGO_MALLOC -#undef malloc -#pragma pop_macro("malloc") -#undef realloc -#pragma pop_macro("realloc") -#endif - // util/assert_util.h #undef dassert #pragma pop_macro("dassert") diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index 24f4c025abb..62664ad8ced 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -34,6 +34,7 @@ env.Library('authcore', ['action_set.cpp', '$BUILD_DIR/mongo/db/common', '$BUILD_DIR/mongo/db/ops/update_driver', '$BUILD_DIR/mongo/md5', + '$BUILD_DIR/mongo/signal_handlers_synchronous', '$BUILD_DIR/mongo/stringutils']) env.Library('authservercommon', diff --git a/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp b/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp index be5364ada69..58bac3e9a2b 100644 --- a/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp +++ b/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp @@ -38,6 +38,7 @@ #include "mongo/db/storage/mmap_v1/extent.h" #include "mongo/db/storage/mmap_v1/record.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/allocator.h" #include "mongo/util/log.h" namespace mongo { @@ -222,7 +223,7 @@ namespace mongo { size = quantizeExtentSize( size ); ExtentInfo info; - info.data = static_cast<char*>( malloc( size ) ); + info.data = static_cast<char*>( mongoMalloc( size ) ); info.length = size; DiskLoc loc( _extents.size(), 0 ); diff --git a/src/mongo/dbtests/jsobjtests.cpp b/src/mongo/dbtests/jsobjtests.cpp index 63bb0f18363..2b4e7918017 100644 --- a/src/mongo/dbtests/jsobjtests.cpp +++ b/src/mongo/dbtests/jsobjtests.cpp @@ -37,6 +37,7 @@ #include "mongo/db/storage/mmap_v1/btree/key.h" #include "mongo/dbtests/dbtests.h" #include "mongo/platform/float_utils.h" +#include "mongo/util/allocator.h" #include "mongo/util/embedded_builder.h" #include "mongo/util/log.h" #include "mongo/util/stringutils.h" @@ -2018,7 +2019,7 @@ namespace JsobjTests { void run() { BSONObj x = BSON( "_id" << 5 << "t" << 2 ); { - char * crap = (char*)malloc( x.objsize() ); + char * crap = (char*)mongoMalloc( x.objsize() ); memcpy( crap , x.objdata() , x.objsize() ); BSONObj y( crap ); ASSERT_EQUALS( x , y ); @@ -2026,7 +2027,7 @@ namespace JsobjTests { } { - char * crap = (char*)malloc( x.objsize() ); + char * crap = (char*)mongoMalloc( x.objsize() ); memcpy( crap , x.objdata() , x.objsize() ); int * foo = (int*)crap; foo[0] = 123123123; diff --git a/src/mongo/dbtests/perftests.cpp b/src/mongo/dbtests/perftests.cpp index 1acc5a4d805..6e3a2da3606 100644 --- a/src/mongo/dbtests/perftests.cpp +++ b/src/mongo/dbtests/perftests.cpp @@ -50,6 +50,7 @@ #include "mongo/db/lasterror.h" #include "mongo/dbtests/dbtests.h" #include "mongo/dbtests/framework_options.h" +#include "mongo/util/allocator.h" #include "mongo/util/checksum.h" #include "mongo/util/compress.h" #include "mongo/util/concurrency/qlock.h" @@ -896,7 +897,7 @@ namespace PerfTests { virtual bool showDurStats() { return false; } virtual int howLongMillis() { return 4000; } void prep() { - p = malloc(sz); + p = mongoMalloc(sz); // this isn't a fair test as it is mostly rands but we just want a rough perf check static int last; for (unsigned i = 0; i<sz; i++) { diff --git a/src/mongo/dbtests/macrotests.cpp b/src/mongo/util/allocator.cpp index 533b9ae7185..1bc7c69ef73 100644 --- a/src/mongo/dbtests/macrotests.cpp +++ b/src/mongo/util/allocator.cpp @@ -1,5 +1,6 @@ -/* - * Copyright 2010 10gen Inc. +// 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, @@ -26,47 +27,28 @@ * then also delete it in the license file. */ -#undef MONGO_EXPOSE_MACROS - -// pragma push_macro only works in gcc 4.3+ -// However, you had to define a special macro -// and build gcc yourself for it to work in 4.3. -// Version 4.4+ activate the feature by default. - -#define GCC_VERSION (__GNUC__ * 10000 \ - + __GNUC_MINOR__ * 100 \ - + __GNUC_PATCHLEVEL__) - -#if GCC_VERSION >= 40402 - -# define malloc 42 - -# include "mongo/client/redef_macros.h" -# include "mongo/client/undef_macros.h" - -# if malloc == 42 -# else -# error malloc macro molested -# endif - -# undef malloc - -#ifndef MONGO_MALLOC -#define MONGO_MALLOC 1 -#endif - -# define malloc 42 +#include "mongo/platform/basic.h" -# include "mongo/client/redef_macros.h" -# include "mongo/client/undef_macros.h" +#include <cstdlib> -# if malloc == 42 -# else -# error malloc macro molested -# endif +#include "mongo/util/signal_handlers_synchronous.h" -# undef malloc +namespace mongo { + void* mongoMalloc(size_t size) { + void* x = std::malloc(size); + if (x == NULL) { + reportOutOfMemoryErrorAndExit(); + } + return x; + } -#endif // gcc 4.3 + 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; |