vm: Fail with out_of_memory() if mprotect returns ENOMEM.

Add a message to out_of_memory(msg) calls so we know which call caused the OOM.
Fixes #664.
db4
Doug Coleman 2014-11-11 06:23:38 +00:00
parent 114342a799
commit 53eac53626
5 changed files with 18 additions and 7 deletions

View 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();
}

View 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();

View 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;

View 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(); }

View 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);