static void *alloc_sigstack(size_t size) { size_t pagesz = jl_getpagesize(); // Add one guard page to catch stack overflow in the signal handler size = LLT_ALIGN(size, pagesz) + pagesz; void *stackbuff = mmap(0, size, PROT_READ | PROT_WRITE, MAP_NORESERVE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (stackbuff == MAP_FAILED) jl_errorf("fatal error allocating signal stack: mmap: %s", strerror(errno)); mprotect(stackbuff, pagesz, PROT_NONE); return (void*)((char*)stackbuff + pagesz); }
void jl_safepoint_init(void) { // jl_page_size isn't available yet. size_t pgsz = jl_getpagesize(); #ifdef _OS_WINDOWS_ char *addr = (char*)VirtualAlloc(NULL, pgsz * 3, MEM_COMMIT, PAGE_READONLY); #else char *addr = (char*)mmap(0, pgsz * 3, PROT_READ, MAP_NORESERVE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (addr == MAP_FAILED) addr = NULL; #endif if (addr == NULL) { jl_printf(JL_STDERR, "could not allocate GC synchronization page\n"); gc_debug_critical_error(); abort(); } // The signal page is for the gc safepoint. // The page before it is the sigint pending flag. jl_safepoint_pages = addr; }
void julia_init(char *imageFile) { jl_page_size = jl_getpagesize(); jl_find_stack_bottom(); jl_dl_handle = jl_load_dynamic_library(NULL, JL_RTLD_DEFAULT); #ifdef __WIN32__ uv_dlopen("ntdll.dll",jl_ntdll_handle); //bypass julia's pathchecking for system dlls uv_dlopen("Kernel32.dll",jl_kernel32_handle); uv_dlopen("msvcrt.dll",jl_crtdll_handle); uv_dlopen("Ws2_32.dll",jl_winsock_handle); _jl_exe_handle.handle = GetModuleHandleA(NULL); #endif jl_io_loop = uv_default_loop(); //this loop will internal events (spawining process etc.) init_stdio(); #if defined(__linux__) int ncores = jl_cpu_cores(); if (ncores > 1) { cpu_set_t cpumask; CPU_ZERO(&cpumask); for(int i=0; i < ncores; i++) { CPU_SET(i, &cpumask); } sched_setaffinity(0, sizeof(cpu_set_t), &cpumask); } #endif #ifdef JL_GC_MARKSWEEP jl_gc_init(); jl_gc_disable(); #endif jl_init_frontend(); jl_init_types(); jl_init_tasks(jl_stack_lo, jl_stack_hi-jl_stack_lo); jl_init_codegen(); jl_an_empty_cell = (jl_value_t*)jl_alloc_cell_1d(0); jl_init_serializer(); if (!imageFile) { jl_main_module = jl_new_module(jl_symbol("Main")); jl_main_module->parent = jl_main_module; jl_core_module = jl_new_module(jl_symbol("Core")); jl_core_module->parent = jl_main_module; jl_set_const(jl_main_module, jl_symbol("Core"), (jl_value_t*)jl_core_module); jl_module_using(jl_main_module, jl_core_module); jl_current_module = jl_core_module; jl_init_intrinsic_functions(); jl_init_primitives(); jl_load("boot.jl"); jl_get_builtin_hooks(); jl_boot_file_loaded = 1; jl_init_box_caches(); } if (imageFile) { JL_TRY { jl_restore_system_image(imageFile); } JL_CATCH { JL_PRINTF(JL_STDERR, "error during init:\n"); jl_show(jl_stderr_obj(), jl_exception_in_transit); JL_PRINTF(JL_STDOUT, "\n"); jl_exit(1); } } // set module field of primitive types int i; void **table = jl_core_module->bindings.table; for(i=1; i < jl_core_module->bindings.size; i+=2) { if (table[i] != HT_NOTFOUND) { jl_binding_t *b = (jl_binding_t*)table[i]; if (b->value && jl_is_datatype(b->value)) { jl_datatype_t *tt = (jl_datatype_t*)b->value; tt->name->module = jl_core_module; } } } // the Main module is the one which is always open, and set as the // current module for bare (non-module-wrapped) toplevel expressions. // it does "using Base" if Base is available. if (jl_base_module != NULL) { jl_add_standard_imports(jl_main_module); } // eval() uses Main by default, so Main.eval === Core.eval jl_module_import(jl_main_module, jl_core_module, jl_symbol("eval")); jl_current_module = jl_main_module; #ifndef __WIN32__ struct sigaction actf; memset(&actf, 0, sizeof(struct sigaction)); sigemptyset(&actf.sa_mask); actf.sa_handler = fpe_handler; actf.sa_flags = 0; if (sigaction(SIGFPE, &actf, NULL) < 0) { JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno)); jl_exit(1); } stack_t ss; ss.ss_flags = 0; ss.ss_size = SIGSTKSZ; ss.ss_sp = malloc(ss.ss_size); if (sigaltstack(&ss, NULL) < 0) { JL_PRINTF(JL_STDERR, "sigaltstack: %s\n", strerror(errno)); jl_exit(1); } struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); sigemptyset(&act.sa_mask); act.sa_sigaction = segv_handler; act.sa_flags = SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGSEGV, &act, NULL) < 0) { JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno)); jl_exit(1); } #else if (signal(SIGFPE, (void (__cdecl *)(int))fpe_handler) == SIG_ERR) { JL_PRINTF(JL_STDERR, "Couldn't set SIGFPE\n"); jl_exit(1); } #endif #ifdef JL_GC_MARKSWEEP jl_gc_enable(); #endif }
void julia_init(char *imageFile) { jl_page_size = jl_getpagesize(); jl_find_stack_bottom(); jl_dl_handle = jl_load_dynamic_library(NULL, JL_RTLD_DEFAULT); #ifdef _OS_WINDOWS_ uv_dlopen("ntdll.dll",jl_ntdll_handle); //bypass julia's pathchecking for system dlls uv_dlopen("Kernel32.dll",jl_kernel32_handle); uv_dlopen("msvcrt.dll",jl_crtdll_handle); uv_dlopen("Ws2_32.dll",jl_winsock_handle); _jl_exe_handle.handle = GetModuleHandleA(NULL); if (!DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), (PHANDLE)&hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS )) { JL_PRINTF(JL_STDERR, "Couldn't access handle to main thread\n"); } #if defined(_CPU_X86_64_) SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); SymInitialize(GetCurrentProcess(), NULL, 1); needsSymRefreshModuleList = 0; #endif #endif jl_io_loop = uv_default_loop(); //this loop will internal events (spawining process etc.) init_stdio(); #if defined(__linux__) int ncores = jl_cpu_cores(); if (ncores > 1) { cpu_set_t cpumask; CPU_ZERO(&cpumask); for(int i=0; i < ncores; i++) { CPU_SET(i, &cpumask); } sched_setaffinity(0, sizeof(cpu_set_t), &cpumask); } #endif #ifdef JL_GC_MARKSWEEP jl_gc_init(); jl_gc_disable(); #endif jl_init_frontend(); jl_init_types(); jl_init_tasks(jl_stack_lo, jl_stack_hi-jl_stack_lo); jl_init_codegen(); jl_an_empty_cell = (jl_value_t*)jl_alloc_cell_1d(0); jl_init_serializer(); if (!imageFile) { jl_main_module = jl_new_module(jl_symbol("Main")); jl_main_module->parent = jl_main_module; jl_core_module = jl_new_module(jl_symbol("Core")); jl_core_module->parent = jl_main_module; jl_set_const(jl_main_module, jl_symbol("Core"), (jl_value_t*)jl_core_module); jl_module_using(jl_main_module, jl_core_module); jl_current_module = jl_core_module; jl_init_intrinsic_functions(); jl_init_primitives(); jl_load("boot.jl"); jl_get_builtin_hooks(); jl_boot_file_loaded = 1; jl_init_box_caches(); } if (imageFile) { JL_TRY { jl_restore_system_image(imageFile); } JL_CATCH { JL_PRINTF(JL_STDERR, "error during init:\n"); jl_show(jl_stderr_obj(), jl_exception_in_transit); JL_PRINTF(JL_STDERR, "\n"); jl_exit(1); } } // set module field of primitive types int i; void **table = jl_core_module->bindings.table; for(i=1; i < jl_core_module->bindings.size; i+=2) { if (table[i] != HT_NOTFOUND) { jl_binding_t *b = (jl_binding_t*)table[i]; if (b->value && jl_is_datatype(b->value)) { jl_datatype_t *tt = (jl_datatype_t*)b->value; tt->name->module = jl_core_module; } } } // the Main module is the one which is always open, and set as the // current module for bare (non-module-wrapped) toplevel expressions. // it does "using Base" if Base is available. if (jl_base_module != NULL) { jl_add_standard_imports(jl_main_module); } // eval() uses Main by default, so Main.eval === Core.eval jl_module_import(jl_main_module, jl_core_module, jl_symbol("eval")); jl_current_module = jl_main_module; #ifndef _OS_WINDOWS_ signal_stack = malloc(SIGSTKSZ); struct sigaction actf; memset(&actf, 0, sizeof(struct sigaction)); sigemptyset(&actf.sa_mask); actf.sa_handler = fpe_handler; actf.sa_flags = 0; if (sigaction(SIGFPE, &actf, NULL) < 0) { JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno)); jl_exit(1); } #if defined(_OS_LINUX_) stack_t ss; ss.ss_flags = 0; ss.ss_size = SIGSTKSZ; ss.ss_sp = signal_stack; if (sigaltstack(&ss, NULL) < 0) { JL_PRINTF(JL_STDERR, "sigaltstack: %s\n", strerror(errno)); jl_exit(1); } struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); sigemptyset(&act.sa_mask); act.sa_sigaction = segv_handler; act.sa_flags = SA_ONSTACK | SA_SIGINFO; if (sigaction(SIGSEGV, &act, NULL) < 0) { JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno)); jl_exit(1); } if (signal(SIGPIPE,SIG_IGN) == SIG_ERR) { JL_PRINTF(JL_STDERR, "Couldn't set SIGPIPE\n"); jl_exit(1); } #elif defined (_OS_DARWIN_) kern_return_t ret; mach_port_t self = mach_task_self(); ret = mach_port_allocate(self,MACH_PORT_RIGHT_RECEIVE,&segv_port); HANDLE_MACH_ERROR("mach_port_allocate",ret); ret = mach_port_insert_right(self,segv_port,segv_port,MACH_MSG_TYPE_MAKE_SEND); HANDLE_MACH_ERROR("mach_port_insert_right",ret); // Alright, create a thread to serve as the listener for exceptions pthread_t thread; pthread_attr_t attr; if (pthread_attr_init(&attr) != 0) { JL_PRINTF(JL_STDERR, "pthread_attr_init failed"); jl_exit(1); } pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); if (pthread_create(&thread,&attr,mach_segv_listener,NULL) != 0) { JL_PRINTF(JL_STDERR, "pthread_create failed"); jl_exit(1); } pthread_attr_destroy(&attr); ret = task_set_exception_ports(self,EXC_MASK_BAD_ACCESS,segv_port,EXCEPTION_DEFAULT,MACHINE_THREAD_STATE); HANDLE_MACH_ERROR("task_set_exception_ports",ret); #endif #else if (signal(SIGFPE, (void (__cdecl *)(int))fpe_handler) == SIG_ERR) { JL_PRINTF(JL_STDERR, "Couldn't set SIGFPE\n"); jl_exit(1); } #endif #ifdef JL_GC_MARKSWEEP jl_gc_enable(); #endif }
JL_DLLEXPORT long jl_getallocationgranularity(void) { return jl_getpagesize(); }