You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2020/01/06 19:18:30 UTC
[couchdb] 01/01: Make all OOM errors fatal in couchjs
This is an automated email from the ASF dual-hosted git repository.
davisp pushed a commit to branch couchjs-oom-errors-are-fatal
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit fbe262afe289b4e0e4e952241baf533a3f7241f9
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Mon Jan 6 11:06:40 2020 -0600
Make all OOM errors fatal in couchjs
---
src/couch/priv/couch_js/60/main.cpp | 1 +
src/couch/priv/couch_js/60/util.cpp | 8 ++++++
src/couch/priv/couch_js/60/util.h | 1 +
src/couch/test/eunit/couch_js_tests.erl | 45 +++++++++++++++++++++++++++++++++
test/javascript/tests/view_errors.js | 4 +--
5 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/src/couch/priv/couch_js/60/main.cpp b/src/couch/priv/couch_js/60/main.cpp
index ecedfbd..0486722 100644
--- a/src/couch/priv/couch_js/60/main.cpp
+++ b/src/couch/priv/couch_js/60/main.cpp
@@ -420,6 +420,7 @@ main(int argc, const char* argv[])
return 1;
JS::SetWarningReporter(cx, couch_error);
+ JS::SetOutOfMemoryCallback(cx, couch_handle_oom, NULL);
JS_SetContextPrivate(cx, args);
JS_SetSecurityCallbacks(cx, &security_callbacks);
diff --git a/src/couch/priv/couch_js/60/util.cpp b/src/couch/priv/couch_js/60/util.cpp
index 894b425..bba342d 100644
--- a/src/couch/priv/couch_js/60/util.cpp
+++ b/src/couch/priv/couch_js/60/util.cpp
@@ -309,6 +309,14 @@ couch_error(JSContext* cx, JSErrorReport* report)
}
+void
+couch_handle_oom(JSContext* cx, void* data)
+{
+ fprintf(stdout, "[\"fatal\",\"oom\",\"out of memory\"]\n");
+ exit(37);
+}
+
+
bool
couch_load_funcs(JSContext* cx, JS::HandleObject obj, JSFunctionSpec* funcs)
{
diff --git a/src/couch/priv/couch_js/60/util.h b/src/couch/priv/couch_js/60/util.h
index 45caa34..50f9af7 100644
--- a/src/couch/priv/couch_js/60/util.h
+++ b/src/couch/priv/couch_js/60/util.h
@@ -35,6 +35,7 @@ JSString* couch_readline(JSContext* cx, FILE* fp);
size_t couch_readfile(const char* file, char** outbuf_p);
void couch_print(JSContext* cx, unsigned int argc, JS::CallArgs argv);
void couch_error(JSContext* cx, JSErrorReport* report);
+void couch_handle_oom(JSContext* cx, void* data);
bool couch_load_funcs(JSContext* cx, JS::HandleObject obj, JSFunctionSpec* funcs);
diff --git a/src/couch/test/eunit/couch_js_tests.erl b/src/couch/test/eunit/couch_js_tests.erl
new file mode 100644
index 0000000..0585a33
--- /dev/null
+++ b/src/couch/test/eunit/couch_js_tests.erl
@@ -0,0 +1,45 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(couch_js_tests).
+-include_lib("eunit/include/eunit.hrl").
+
+
+-define(FUNC, <<
+ "function(doc) {\n"
+ " var val = \"0123456789ABCDEF\";\n"
+ " while(true) {emit(val, val);}\n"
+ "}\n"
+>>).
+
+
+couch_js_test_() ->
+ {
+ "Test couchjs",
+ {
+ setup,
+ fun test_util:start_couch/0,
+ fun test_util:stop_couch/1,
+ [
+ fun should_recover_from_oom/0
+ ]
+ }
+ }.
+
+
+should_recover_from_oom() ->
+ Proc = couch_query_servers:get_os_process(<<"javascript">>),
+ true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, ?FUNC]),
+ ?assertThrow(
+ {<<"oom">>, <<"out of memory">>},
+ couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, <<"{}">>])
+ ).
diff --git a/test/javascript/tests/view_errors.js b/test/javascript/tests/view_errors.js
index 7577b80..43db3c8 100644
--- a/test/javascript/tests/view_errors.js
+++ b/test/javascript/tests/view_errors.js
@@ -145,7 +145,7 @@ couchTests.view_errors = function(debug) {
_id:"_design/infinite",
language: "javascript",
views: {
- "infinite_loop" :{map:"function(doc) {while(true){emit(doc,doc);}};"}
+ "infinite_loop" :{map:"function(doc) {while(true){};}"}
}
};
T(db.save(designDoc3).ok);
@@ -154,7 +154,7 @@ couchTests.view_errors = function(debug) {
db.view("infinite/infinite_loop");
T(0 == 1);
} catch(e) {
- T(e.error == "os_process_error" || e.error == "unnamed_error");
+ T(e.error == "os_process_error");
}
// Check error responses for invalid multi-get bodies.