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:29 UTC

[couchdb] branch couchjs-oom-errors-are-fatal created (now fbe262a)

This is an automated email from the ASF dual-hosted git repository.

davisp pushed a change to branch couchjs-oom-errors-are-fatal
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


      at fbe262a  Make all OOM errors fatal in couchjs

This branch includes the following new commits:

     new fbe262a  Make all OOM errors fatal in couchjs

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[couchdb] 01/01: Make all OOM errors fatal in couchjs

Posted by da...@apache.org.
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.