]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: Fail with out_of_memory() if mprotect returns ENOMEM.
authorDoug Coleman <doug.coleman@gmail.com>
Tue, 11 Nov 2014 06:23:38 +0000 (06:23 +0000)
committerDoug Coleman <doug.coleman@gmail.com>
Tue, 11 Nov 2014 06:26:55 +0000 (06:26 +0000)
Add a message to out_of_memory(msg) calls so we know which call caused the OOM.
Fixes #664.

vm/errors.cpp
vm/errors.hpp
vm/os-unix.cpp
vm/os-unix.hpp
vm/os-windows.cpp

index 6b2a108a2adac6b09ca477c88f17465acd238453..61364b5bcfec8e9f1996c3097057b51df14f4292 100644 (file)
@@ -30,8 +30,8 @@ void critical_error(const char* msg, cell tagged) {
   current_vm()->factorbug();
 }
 
-void out_of_memory() {
-  std::cout << "Out of memory\n\n";
+void out_of_memory(const char *msg) {
+  std::cout << "Out of memory: " << msg << "\n\n";
   current_vm()->dump_generations();
   abort();
 }
index e580fa12348b96d1bd0d133d6ecb6216494501d7..b43938e0a6551e7076947a92f8f2e76454f1b6ce 100644 (file)
@@ -29,7 +29,7 @@ enum vm_error_type {
 
 void fatal_error(const char* msg, cell tagged);
 void critical_error(const char* msg, cell tagged);
-void out_of_memory();
+void out_of_memory(const char* msg);
 void memory_signal_handler_impl();
 void fp_signal_handler_impl();
 void synchronous_signal_handler_impl();
index d5122545e99c6f79ab5f6ec2435174f859c9f090..2b6014c1484330b9c8d91c52af89efc19c6622bb 100644 (file)
@@ -75,6 +75,11 @@ void factor_vm::move_file(const vm_char* path1, const vm_char* path2) {
     general_error(ERROR_IO, tag_fixnum(errno), false_object);
 }
 
+void check_ENOMEM(const char* msg) {
+  if(errno == ENOMEM)
+    out_of_memory(msg);
+}
+
 segment::segment(cell size_, bool executable_p) {
   size = size_;
 
@@ -88,14 +93,19 @@ segment::segment(cell size_, bool executable_p) {
 
   char* array = (char*)mmap(NULL, pagesize + size + pagesize, prot,
                             MAP_ANON | MAP_PRIVATE, -1, 0);
+
   if (array == (char*)- 1)
-    out_of_memory();
+    out_of_memory("mmap");
 
-  if (mprotect(array, pagesize, PROT_NONE) == -1)
+  if (mprotect(array, pagesize, PROT_NONE) == -1) {
+    check_ENOMEM("mprotect low");
     fatal_error("Cannot protect low guard page", (cell)array);
+  }
 
-  if (mprotect(array + pagesize + size, pagesize, PROT_NONE) == -1)
+  if (mprotect(array + pagesize + size, pagesize, PROT_NONE) == -1) {
+    check_ENOMEM("mprotect high");
     fatal_error("Cannot protect high guard page", (cell)array);
+  }
 
   start = (cell)(array + pagesize);
   end = start + size;
index a08711dc447046b20f1844a60e85868f247f8449..26c6913f08ec36143399814b1a961296a9f7f4c9 100644 (file)
@@ -52,6 +52,7 @@ uint64_t nano_count();
 void sleep_nanos(uint64_t nsec);
 
 void move_file(const vm_char* path1, const vm_char* path2);
+void check_ENOMEM(const char* msg);
 
 static inline void breakpoint() { __builtin_trap(); }
 
index f83f67f91d6133e2a67bfa5dc6234dbb62e50b18..9ac677213247e3a1610650bf13bc5913f89b9de0 100644 (file)
@@ -101,7 +101,7 @@ segment::segment(cell size_, bool executable_p) {
            NULL, getpagesize() * 2 + size, MEM_COMMIT,
            executable_p ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE)) ==
       0)
-    out_of_memory();
+    out_of_memory("VirtualAlloc");
 
   if (!VirtualProtect(mem, getpagesize(), PAGE_NOACCESS, &ignore))
     fatal_error("Cannot allocate low guard page", (cell)mem);