diff options
author | Jason Carey <jcarey@argv.me> | 2015-07-24 15:43:01 -0400 |
---|---|---|
committer | Jason Carey <jcarey@argv.me> | 2015-07-28 18:30:39 -0400 |
commit | 99103f65251459ea2fc8ad7e096284799702a234 (patch) | |
tree | 3098fabce8b8c871b0baf3e35c5d0c3add23e06a /src/mongo/scripting | |
parent | 4bc0ca5f2190f851c25bd09f33bedbe57b23f758 (diff) | |
download | mongo-99103f65251459ea2fc8ad7e096284799702a234.tar.gz |
SERVER-19641 cleanup the js scope in quit()
make leak sanitizer happy
Diffstat (limited to 'src/mongo/scripting')
-rw-r--r-- | src/mongo/scripting/mozjs/exception.cpp | 19 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/implscope.cpp | 17 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/implscope.h | 5 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/mongo.cpp | 12 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/mongo.h | 3 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/proxyscope.cpp | 7 |
6 files changed, 56 insertions, 7 deletions
diff --git a/src/mongo/scripting/mozjs/exception.cpp b/src/mongo/scripting/mozjs/exception.cpp index bae718c0b92..1d6880da05f 100644 --- a/src/mongo/scripting/mozjs/exception.cpp +++ b/src/mongo/scripting/mozjs/exception.cpp @@ -40,9 +40,14 @@ namespace mozjs { namespace { -JSErrorFormatString kFormatString = {"{0}", 1, JSEXN_ERR}; +JSErrorFormatString kErrorFormatString = {"{0}", 1, JSEXN_ERR}; const JSErrorFormatString* errorCallback(void* data, const unsigned code) { - return &kFormatString; + return &kErrorFormatString; +} + +JSErrorFormatString kUncatchableErrorFormatString = {"{0}", 1, JSEXN_NONE}; +const JSErrorFormatString* uncatchableErrorCallback(void* data, const unsigned code) { + return &kUncatchableErrorFormatString; } } // namespace @@ -50,11 +55,17 @@ const JSErrorFormatString* errorCallback(void* data, const unsigned code) { void mongoToJSException(JSContext* cx) { auto status = exceptionToStatus(); - JS_ReportErrorNumber(cx, errorCallback, nullptr, status.code(), status.reason().c_str()); + auto callback = + status.code() == ErrorCodes::JSUncatchableError ? uncatchableErrorCallback : errorCallback; + + JS_ReportErrorNumber(cx, callback, nullptr, status.code(), status.reason().c_str()); } void setJSException(JSContext* cx, ErrorCodes::Error code, StringData sd) { - JS_ReportErrorNumber(cx, errorCallback, nullptr, code, sd.rawData()); + auto callback = + code == ErrorCodes::JSUncatchableError ? uncatchableErrorCallback : errorCallback; + + JS_ReportErrorNumber(cx, callback, nullptr, code, sd.rawData()); } Status currentJSExceptionToStatus(JSContext* cx, ErrorCodes::Error altCode, StringData altReason) { diff --git a/src/mongo/scripting/mozjs/implscope.cpp b/src/mongo/scripting/mozjs/implscope.cpp index f7574aa48f2..e71fc973949 100644 --- a/src/mongo/scripting/mozjs/implscope.cpp +++ b/src/mongo/scripting/mozjs/implscope.cpp @@ -227,6 +227,7 @@ MozJSImplScope::MozJSImplScope(MozJSScriptEngine* engine) _pendingGC(false), _connectState(ConnectState::Not), _status(Status::OK()), + _quickExit(false), _binDataProto(_context), _bsonProto(_context), _countDownLatchProto(_context), @@ -707,6 +708,9 @@ bool MozJSImplScope::_checkErrorState(bool success, bool reportError, bool asser if (success) return false; + if (_quickExit) + return false; + if (_status.isOK()) { _status = Status(ErrorCodes::UnknownError, "Unknown Failure from JSInterpreter"); } @@ -736,6 +740,19 @@ MozJSImplScope* MozJSImplScope::getThreadScope() { return kCurrentScope; } +void MozJSImplScope::setQuickExit(int exitCode) { + _quickExit = true; + _exitCode = exitCode; +} + +bool MozJSImplScope::getQuickExit(int* exitCode) { + if (_quickExit) { + *exitCode = _exitCode; + } + + return _quickExit; +} + void MozJSImplScope::setOOM() { _status = Status(ErrorCodes::JSInterpreterFailure, "Out of memory"); } diff --git a/src/mongo/scripting/mozjs/implscope.h b/src/mongo/scripting/mozjs/implscope.h index 4bd29e76676..6bd0c6c7411 100644 --- a/src/mongo/scripting/mozjs/implscope.h +++ b/src/mongo/scripting/mozjs/implscope.h @@ -226,6 +226,9 @@ public: return _timestampProto; } + void setQuickExit(int exitCode); + bool getQuickExit(int* exitCode); + static const char* const kExecResult; static const char* const kInvokeResult; @@ -291,6 +294,8 @@ private: std::atomic<bool> _pendingGC; ConnectState _connectState; Status _status; + int _exitCode; + bool _quickExit; WrapType<BinDataInfo> _binDataProto; WrapType<BSONInfo> _bsonProto; diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp index f1f69d0d39c..fe937e359dd 100644 --- a/src/mongo/scripting/mozjs/mongo.cpp +++ b/src/mongo/scripting/mozjs/mongo.cpp @@ -63,8 +63,8 @@ const JSFunctionSpec MongoBase::methods[13] = { const char* const MongoBase::className = "Mongo"; -const JSFunctionSpec MongoExternalInfo::freeFunctions[2] = { - MONGO_ATTACH_JS_FUNCTION(load), JS_FS_END, +const JSFunctionSpec MongoExternalInfo::freeFunctions[3] = { + MONGO_ATTACH_JS_FUNCTION(load), MONGO_ATTACH_JS_FUNCTION(quit), JS_FS_END, }; namespace { @@ -561,5 +561,13 @@ void MongoExternalInfo::Functions::load(JSContext* cx, JS::CallArgs args) { args.rval().setBoolean(true); } +void MongoExternalInfo::Functions::quit(JSContext* cx, JS::CallArgs args) { + auto scope = getScope(cx); + + scope->setQuickExit(args.get(0).isNumber() ? args.get(0).toNumber() : 0); + + uasserted(ErrorCodes::JSUncatchableError, "Calling Quit"); +} + } // namespace mozjs } // namespace mongo diff --git a/src/mongo/scripting/mozjs/mongo.h b/src/mongo/scripting/mozjs/mongo.h index 35815da5455..e31e52fd14c 100644 --- a/src/mongo/scripting/mozjs/mongo.h +++ b/src/mongo/scripting/mozjs/mongo.h @@ -79,9 +79,10 @@ struct MongoExternalInfo : public MongoBase { struct Functions { MONGO_DEFINE_JS_FUNCTION(load); + MONGO_DEFINE_JS_FUNCTION(quit); }; - static const JSFunctionSpec freeFunctions[2]; + static const JSFunctionSpec freeFunctions[3]; }; } // namespace mozjs diff --git a/src/mongo/scripting/mozjs/proxyscope.cpp b/src/mongo/scripting/mozjs/proxyscope.cpp index 665d249f4c5..73e0a26d6f5 100644 --- a/src/mongo/scripting/mozjs/proxyscope.cpp +++ b/src/mongo/scripting/mozjs/proxyscope.cpp @@ -34,6 +34,7 @@ #include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/scripting/mozjs/implscope.h" +#include "mongo/util/quick_exit.h" namespace mongo { namespace mozjs { @@ -308,6 +309,12 @@ void MozJSProxyScope::implThread() { _status = exceptionToStatus(); } + int exitCode; + if (_implScope && _implScope->getQuickExit(&exitCode)) { + scope.reset(); + quickExit(exitCode); + } + _state = State::ImplResponse; _condvar.notify_one(); |