void __cdecl crt_sig_handler(int sig, int num) { jl_ptls_t ptls = jl_get_ptls_states(); CONTEXT Context; switch (sig) { case SIGFPE: fpreset(); signal(SIGFPE, (void (__cdecl *)(int))crt_sig_handler); switch(num) { case _FPE_INVALID: case _FPE_OVERFLOW: case _FPE_UNDERFLOW: default: jl_errorf("Unexpected FPE Error 0x%X", num); break; case _FPE_ZERODIVIDE: jl_throw(jl_diverror_exception); break; } break; case SIGINT: signal(SIGINT, (void (__cdecl *)(int))crt_sig_handler); if (exit_on_sigint) jl_exit(130); // 128 + SIGINT jl_try_throw_sigint(); break; default: // SIGSEGV, (SSIGTERM, IGILL) memset(&Context, 0, sizeof(Context)); RtlCaptureContext(&Context); jl_critical_error(sig, &Context, ptls->bt_data, &ptls->bt_size); raise(sig); } }
void jl_prep_terminal(int meta_flag) { FILE *rl_in = rl_instream; rl_instream = stdin; rl_prep_terminal(1); rl_instream = rl_in; #ifdef __WIN32__ if (jl_uv_stdin->type == UV_TTY) uv_tty_set_mode((uv_tty_t*)jl_uv_stdin,1); //raw (and libuv-processed) if (!repl_sigint_handler_installed) { if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)repl_sigint_handler,1)) repl_sigint_handler_installed = 1; } #else if (jl_sigint_act.sa_sigaction == NULL) { struct sigaction oldact, repl_sigint_act; memset(&repl_sigint_act, 0, sizeof(struct sigaction)); sigemptyset(&repl_sigint_act.sa_mask); repl_sigint_act.sa_sigaction = repl_sigint_handler; repl_sigint_act.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &repl_sigint_act, &oldact) < 0) { JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno)); jl_exit(1); } if (repl_sigint_act.sa_sigaction != oldact.sa_sigaction && jl_sigint_act.sa_sigaction != oldact.sa_sigaction) jl_sigint_act = oldact; } #endif }
void jl_write_compiler_output(void) { if (!jl_generating_output()) return; if (!jl_options.incremental) jl_precompile(jl_options.compile_enabled == JL_OPTIONS_COMPILE_ALL); if (!jl_module_init_order) { jl_printf(JL_STDERR, "WARNING: --output requested, but no modules defined during run\n"); return; } jl_array_t *worklist = jl_module_init_order; JL_GC_PUSH1(&worklist); jl_module_init_order = jl_alloc_vec_any(0); int i, l = jl_array_len(worklist); for (i = 0; i < l; i++) { jl_value_t *m = jl_arrayref(worklist, i); if (jl_get_global((jl_module_t*)m, jl_symbol("__init__"))) { jl_array_ptr_1d_push(jl_module_init_order, m); } } if (jl_options.incremental) { if (jl_options.outputji) if (jl_save_incremental(jl_options.outputji, worklist)) jl_exit(1); if (jl_options.outputbc || jl_options.outputunoptbc) jl_printf(JL_STDERR, "WARNING: incremental output to a .bc file is not implemented\n"); if (jl_options.outputo) jl_printf(JL_STDERR, "WARNING: incremental output to a .o file is not implemented\n"); } else { ios_t *s = NULL; if (jl_options.outputo || jl_options.outputbc || jl_options.outputunoptbc) s = jl_create_system_image(); if (jl_options.outputji) { if (s == NULL) { jl_save_system_image(jl_options.outputji); } else { ios_t f; if (ios_file(&f, jl_options.outputji, 1, 1, 1, 1) == NULL) jl_errorf("cannot open system image file \"%s\" for writing", jl_options.outputji); ios_write(&f, (const char*)s->buf, (size_t)s->size); ios_close(&f); } } if (jl_options.outputo || jl_options.outputbc || jl_options.outputunoptbc) jl_dump_native(jl_options.outputbc, jl_options.outputunoptbc, jl_options.outputo, (const char*)s->buf, (size_t)s->size); } JL_GC_POP(); }
void *mach_segv_listener(void *arg) { (void)arg; while (1) { int ret = mach_msg_server(exc_server,2048,segv_port,MACH_MSG_TIMEOUT_NONE); jl_safe_printf("mach_msg_server: %s\n", mach_error_string(ret)); jl_exit(128+SIGSEGV); } }
void jl_error(const char *str) { if (jl_errorexception_type == NULL) { JL_PRINTF(JL_STDERR, "%s", str); jl_exit(1); } jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str)); JL_GC_PUSH(&msg); jl_raise(jl_new_struct(jl_errorexception_type, msg)); }
JL_DLLEXPORT void JL_NORETURN jl_error(const char *str) { if (jl_errorexception_type == NULL) { jl_printf(JL_STDERR, "ERROR: %s\n", str); jl_exit(1); } jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str)); JL_GC_PUSH1(&msg); jl_throw(jl_new_struct(jl_errorexception_type, msg)); }
DLLEXPORT int jl_profile_start_timer(void) { kern_return_t ret; if (!profile_started) { mach_port_t self = mach_task_self(); main_thread = mach_thread_self(); ret = host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, (clock_serv_t *)&clk); HANDLE_MACH_ERROR("host_get_clock_service", ret); ret = mach_port_allocate(self,MACH_PORT_RIGHT_RECEIVE,&profile_port); HANDLE_MACH_ERROR("mach_port_allocate",ret); // Alright, create a thread to serve as the listener for exceptions 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(&profiler_thread,&attr,mach_profile_listener,NULL) != 0) { JL_PRINTF(JL_STDERR, "pthread_create failed"); jl_exit(1); } pthread_attr_destroy(&attr); profile_started = 1; } timerprof.tv_sec = nsecprof/GIGA; timerprof.tv_nsec = nsecprof%GIGA; running = 1; ret = clock_alarm(clk, TIME_RELATIVE, timerprof, profile_port); HANDLE_MACH_ERROR("clock_alarm",ret); return 0; }
void jl_errorf(const char *fmt, ...) { char buf[1024]; va_list args; va_start(args, fmt); int nc = vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); if (jl_errorexception_type == NULL) { JL_PRINTF(JL_STDERR, "%s", &buf); jl_exit(1); } jl_value_t *msg = jl_pchar_to_string(buf, nc); JL_GC_PUSH(&msg); jl_raise(jl_new_struct(jl_errorexception_type, msg)); }
static BOOL WINAPI sigint_handler(DWORD wsig) //This needs winapi types to guarantee __stdcall { int sig; //windows signals use different numbers from unix (raise) switch(wsig) { case CTRL_C_EVENT: sig = SIGINT; break; //case CTRL_BREAK_EVENT: sig = SIGTERM; break; // etc. default: sig = SIGTERM; break; } if (exit_on_sigint) jl_exit(128 + sig); // 128 + SIGINT jl_try_deliver_sigint(); return 1; }
static void jl_exit_thread0_cb(void) { // This can get stuck if it happens at an unfortunate spot // (unavoidable due to its async nature). // Try harder to exit each time if we get multiple exit requests. if (thread0_exit_count <= 1) { jl_exit(thread0_exit_state); } else if (thread0_exit_count == 2) { exit(thread0_exit_state); } else { _exit(thread0_exit_state); } }
void sigint_handler(int sig, siginfo_t *info, void *context) { if (exit_on_sigint) jl_exit(0); if (jl_defer_signal) { jl_signal_pending = sig; } else { jl_signal_pending = 0; sigset_t sset; sigemptyset(&sset); sigaddset(&sset, SIGINT); sigprocmask(SIG_UNBLOCK, &sset, NULL); jl_throw(jl_interrupt_exception); } }
void jl_errorf(const char *fmt, ...) { va_list args; ios_t buf; ios_mem(&buf, 0); va_start(args, fmt); ios_vprintf(&buf, fmt, args); va_end(args); if (jl_errorexception_type == NULL) { JL_PRINTF(JL_STDERR, "%s", buf.buf); jl_exit(1); } jl_value_t *msg = jl_takebuf_string(&buf); JL_GC_PUSH1(&msg); jl_throw(jl_new_struct(jl_errorexception_type, msg)); }
DLLEXPORT void jl_install_sigint_handler() { #ifdef _OS_WINDOWS_ SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigint_handler,1); #else struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); sigemptyset(&act.sa_mask); act.sa_sigaction = sigint_handler; act.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &act, NULL) < 0) { JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno)); jl_exit(1); } #endif //printf("sigint installed\n"); }
static BOOL WINAPI sigint_handler(DWORD wsig) //This needs winapi types to guarantee __stdcall { if (exit_on_sigint) jl_exit(0); int sig; //windows signals use different numbers from unix (raise) switch(wsig) { case CTRL_C_EVENT: sig = SIGINT; break; //case CTRL_BREAK_EVENT: sig = SIGTERM; break; // etc. default: sig = SIGTERM; break; } if (jl_defer_signal) { jl_signal_pending = sig; } else { jl_signal_pending = 0; if ((DWORD)-1 == SuspendThread(hMainThread)) { //error jl_safe_printf("error: SuspendThread failed\n"); return 0; } CONTEXT ctxThread; memset(&ctxThread,0,sizeof(CONTEXT)); ctxThread.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; if (!GetThreadContext(hMainThread, &ctxThread)) { //error jl_safe_printf("error: GetThreadContext failed\n"); return 0; } jl_throw_in_ctx(jl_interrupt_exception, &ctxThread, 1); ctxThread.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; if (!SetThreadContext(hMainThread,&ctxThread)) { jl_safe_printf("error: SetThreadContext failed\n"); //error return 0; } if ((DWORD)-1 == ResumeThread(hMainThread)) { jl_safe_printf("error: ResumeThread failed\n"); //error return 0; } } return 1; }
DLLEXPORT void jl_init_frontend(void) { fl_init(2*512*1024); value_t img = cvalue(iostreamtype, sizeof(ios_t)); ios_t *pi = value2c(ios_t*, img); ios_static_buffer(pi, flisp_system_image, sizeof(flisp_system_image)); if (fl_load_system_image(img)) { JL_PRINTF(JL_STDERR, "fatal error loading system image\n"); jl_exit(1); } fl_applyn(0, symbol_value(symbol("__init_globals"))); jvtype = define_opaque_type(symbol("julia_value"), sizeof(void*), NULL, NULL); assign_global_builtins(julia_flisp_ast_ext); }
DLLEXPORT void jl_install_sigint_handler() { #ifdef __WIN32__ DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), (PHANDLE)&hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS ); SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigint_handler,1); #else struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); sigemptyset(&act.sa_mask); act.sa_sigaction = sigint_handler; act.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &act, NULL) < 0) { JL_PRINTF(JL_STDERR, "sigaction: %s\n", strerror(errno)); jl_exit(1); } #endif //printf("sigint installed\n"); }
void __cdecl crt_sig_handler(int sig, int num) { switch (sig) { case SIGFPE: fpreset(); signal(SIGFPE, (void (__cdecl *)(int))crt_sig_handler); switch(num) { case _FPE_INVALID: case _FPE_OVERFLOW: case _FPE_UNDERFLOW: default: jl_errorf("Unexpected FPE Error 0x%X", num); break; case _FPE_ZERODIVIDE: jl_throw(jl_diverror_exception); break; } break; case SIGINT: signal(SIGINT, (void (__cdecl *)(int))crt_sig_handler); if (exit_on_sigint) jl_exit(0); if (jl_defer_signal) { jl_signal_pending = sig; } else { jl_signal_pending = 0; jl_throw(jl_interrupt_exception); } break; default: // SIGSEGV, (SSIGTERM, IGILL) ios_printf(ios_stderr,"\nsignal (%d): %s\n", sig, strsignal(sig)); bt_size = rec_backtrace(bt_data, MAX_BT_SIZE); jlbacktrace(); raise(sig); } }
static jl_value_t *jl_vexceptionf(jl_datatype_t *exception_type, const char *fmt, va_list args) { if (exception_type == NULL) { jl_printf(JL_STDERR, "ERROR: "); jl_vprintf(JL_STDERR, fmt, args); jl_printf(JL_STDERR, "\n"); jl_exit(1); } char *str = NULL; int ok = vasprintf(&str, fmt, args); jl_value_t *msg; if (ok < 0) { // vasprintf failed msg = jl_cstr_to_string("internal error: could not display error message"); } else { msg = jl_pchar_to_string(str, strlen(str)); free(str); } JL_GC_PUSH1(&msg); jl_value_t *e = jl_new_struct(exception_type, msg); JL_GC_POP(); return e; }
void julia_init(char *imageFile) { (void)uv_default_loop(); restore_signals(); //XXX: this needs to be early in load process jl_page_size = sysconf(_SC_PAGESIZE); jl_find_stack_bottom(); jl_dl_handle = jl_load_dynamic_library(NULL); #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_some_tag_type(b->value)) { jl_tag_type_t *tt = (jl_tag_type_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_module_using(jl_main_module, jl_base_module); 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); } #endif atexit(jl_atexit_hook); #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 __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 parse_opts(int *argcp, char ***argvp) { enum { opt_machinefile = 300, opt_color, opt_history_file, opt_no_history_file, opt_startup_file, opt_compile, opt_code_coverage, opt_track_allocation, opt_check_bounds, opt_dump_bitcode, opt_depwarn, opt_inline, opt_math_mode, opt_worker, opt_bind_to, opt_handle_signals }; static char* shortopts = "+vhqFfH:e:E:P:L:J:C:ip:Ob:"; static struct option longopts[] = { // exposed command line options // NOTE: This set of required arguments need to be kept in sync // with the required arguments defined in base/client.jl `process_options()` { "version", no_argument, 0, 'v' }, { "help", no_argument, 0, 'h' }, { "quiet", no_argument, 0, 'q' }, { "home", required_argument, 0, 'H' }, { "eval", required_argument, 0, 'e' }, { "print", required_argument, 0, 'E' }, { "post-boot", required_argument, 0, 'P' }, { "load", required_argument, 0, 'L' }, { "sysimage", required_argument, 0, 'J' }, { "cpu-target", required_argument, 0, 'C' }, { "procs", required_argument, 0, 'p' }, { "machinefile", required_argument, 0, opt_machinefile }, { "color", required_argument, 0, opt_color }, { "history-file", required_argument, 0, opt_history_file }, { "no-history-file", no_argument, 0, opt_no_history_file }, // deprecated { "startup-file", required_argument, 0, opt_startup_file }, { "no-startup", no_argument, 0, 'f' }, // deprecated { "compile", required_argument, 0, opt_compile }, { "code-coverage", optional_argument, 0, opt_code_coverage }, { "track-allocation",optional_argument, 0, opt_track_allocation }, { "optimize", no_argument, 0, 'O' }, { "check-bounds", required_argument, 0, opt_check_bounds }, { "dump-bitcode", required_argument, 0, opt_dump_bitcode }, { "depwarn", required_argument, 0, opt_depwarn }, { "inline", required_argument, 0, opt_inline }, { "math-mode", required_argument, 0, opt_math_mode }, { "handle-signals", required_argument, 0, opt_handle_signals }, // hidden command line options { "build", required_argument, 0, 'b' }, { "worker", no_argument, 0, opt_worker }, { "bind-to", required_argument, 0, opt_bind_to }, { "lisp", no_argument, &lisp_prompt, 1 }, { 0, 0, 0, 0 } }; // getopt handles argument parsing up to -- delineator int lastind = optind; int argc = *argcp; if (argc > 0) { for (int i=0; i < argc; i++) { if (!strcmp((*argvp)[i], "--")) { argc = i; break; } } } int c; char *endptr; opterr = 0; int skip = 0; while ((c = getopt_long(argc,*argvp,shortopts,longopts,0)) != -1) { switch (c) { case 0: break; case '?': if (optind != lastind) skip++; lastind = optind; break; case 'v': // version jl_printf(JL_STDOUT, "julia version %s\n", JULIA_VERSION_STRING); jl_exit(0); case 'h': // help jl_printf(JL_STDOUT, "%s%s", usage, opts); jl_exit(0); case 'q': // quiet jl_options.quiet = 1; break; case 'H': // home jl_options.julia_home = strdup(optarg); break; case 'e': // eval jl_options.eval = strdup(optarg); break; case 'E': // print jl_options.print = strdup(optarg); break; case 'P': // post-boot jl_options.postboot = strdup(optarg); break; case 'L': // load jl_options.load = strdup(optarg); break; case 'J': // sysimage jl_options.image_file = strdup(optarg); imagepathspecified = 1; break; case 'C': // cpu-target jl_options.cpu_target = strdup(optarg); break; case 'p': // procs errno = 0; if (!strcmp(optarg,"auto")) { jl_options.nprocs = jl_cpu_cores(); } else { long nprocs = strtol(optarg, &endptr, 10); if (errno != 0 || optarg == endptr || *endptr != 0 || nprocs < 1 || nprocs >= INT_MAX) jl_errorf("julia: -p,--procs=<n> must be an integer >= 1\n"); jl_options.nprocs = (int)nprocs; } break; case opt_machinefile: jl_options.machinefile = strdup(optarg); break; case opt_color: if (!strcmp(optarg,"yes")) jl_options.color = JL_OPTIONS_COLOR_ON; else if (!strcmp(optarg,"no")) jl_options.color = JL_OPTIONS_COLOR_OFF; else jl_errorf("julia: invalid argument to --color={yes|no} (%s)\n", optarg); break; case opt_history_file: if (!strcmp(optarg,"yes")) jl_options.historyfile = JL_OPTIONS_HISTORYFILE_ON; else if (!strcmp(optarg,"no")) jl_options.historyfile = JL_OPTIONS_HISTORYFILE_OFF; else jl_errorf("julia: invalid argument to --history-file={yes|no} (%s)\n", optarg); break; case opt_no_history_file: jl_options.historyfile = JL_OPTIONS_HISTORYFILE_OFF; break; case opt_startup_file: if (!strcmp(optarg,"yes")) jl_options.startupfile = JL_OPTIONS_STARTUPFILE_ON; else if (!strcmp(optarg,"no")) jl_options.startupfile = JL_OPTIONS_STARTUPFILE_OFF; else jl_errorf("julia: invalid argument to --startup-file={yes|no} (%s)\n", optarg); break; case 'f': jl_options.startupfile = JL_OPTIONS_STARTUPFILE_OFF; break; case 'F': jl_options.startupfile = JL_OPTIONS_STARTUPFILE_ON; break; case opt_compile: if (!strcmp(optarg,"yes")) jl_options.compile_enabled = JL_OPTIONS_COMPILE_ON; else if (!strcmp(optarg,"no")) jl_options.compile_enabled = JL_OPTIONS_COMPILE_OFF; else if (!strcmp(optarg,"all")) jl_options.compile_enabled = JL_OPTIONS_COMPILE_ALL; else jl_errorf("julia: invalid argument to --compile (%s)\n", optarg); break; case opt_code_coverage: if (optarg != NULL) { if (!strcmp(optarg,"user")) codecov = JL_LOG_USER; else if (!strcmp(optarg,"all")) codecov = JL_LOG_ALL; else if (!strcmp(optarg,"none")) codecov = JL_LOG_NONE; break; } else { codecov = JL_LOG_USER; } break; case opt_track_allocation: if (optarg != NULL) { if (!strcmp(optarg,"user")) malloclog = JL_LOG_USER; else if (!strcmp(optarg,"all")) malloclog = JL_LOG_ALL; else if (!strcmp(optarg,"none")) malloclog = JL_LOG_NONE; break; } else { malloclog = JL_LOG_USER; } break; case 'O': // optimize jl_options.opt_level = 1; break; case 'i': // isinteractive jl_options.isinteractive = 1; break; case opt_check_bounds: if (!strcmp(optarg,"yes")) jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_ON; else if (!strcmp(optarg,"no")) jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_OFF; else jl_errorf("julia: invalid argument to --check-bounds={yes|no} (%s)\n", optarg); break; case opt_dump_bitcode: if (!strcmp(optarg,"yes")) jl_options.dumpbitcode = JL_OPTIONS_DUMPBITCODE_ON; else if (!strcmp(optarg,"no")) jl_options.dumpbitcode = JL_OPTIONS_DUMPBITCODE_OFF; break; case opt_depwarn: if (!strcmp(optarg,"yes")) jl_options.depwarn = 1; else if (!strcmp(optarg,"no")) jl_options.depwarn = 0; else jl_errorf("julia: invalid argument to --depwarn={yes|no} (%s)\n", optarg); break; case opt_inline: if (!strcmp(optarg,"yes")) jl_options.can_inline = 1; else if (!strcmp(optarg,"no")) jl_options.can_inline = 0; else { jl_errorf("julia: invalid argument to --inline (%s)\n", optarg); } break; case opt_math_mode: if (!strcmp(optarg,"ieee")) jl_options.fast_math = JL_OPTIONS_FAST_MATH_OFF; else if (!strcmp(optarg,"fast")) jl_options.fast_math = JL_OPTIONS_FAST_MATH_ON; else if (!strcmp(optarg,"user")) jl_options.fast_math = JL_OPTIONS_FAST_MATH_DEFAULT; else jl_errorf("julia: invalid argument to --math-mode (%s)\n", optarg); break; case 'b': // build jl_options.build_path = strdup(optarg); if (!imagepathspecified) jl_options.image_file = NULL; break; case opt_worker: jl_options.worker = 1; break; case opt_bind_to: jl_options.bindto = strdup(optarg); break; case opt_handle_signals: if (!strcmp(optarg,"yes")) jl_options.handle_signals = JL_OPTIONS_HANDLE_SIGNALS_ON; else if (!strcmp(optarg,"no")) jl_options.handle_signals = JL_OPTIONS_HANDLE_SIGNALS_OFF; else jl_errorf("julia: invalid argument to --handle-signals (%s)\n", optarg); break; default: jl_errorf("julia: unhandled option -- %c\n" "This is a bug, please report it.\n", c); } } jl_options.code_coverage = codecov; jl_options.malloc_log = malloclog; optind -= skip; *argvp += optind; *argcp -= optind; }
static LONG WINAPI _exception_handler(struct _EXCEPTION_POINTERS *ExceptionInfo, int in_ctx) { jl_ptls_t ptls = jl_get_ptls_states(); if (ExceptionInfo->ExceptionRecord->ExceptionFlags == 0) { switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_INT_DIVIDE_BY_ZERO: fpreset(); jl_throw_in_ctx(jl_diverror_exception, ExceptionInfo->ContextRecord,in_ctx); return EXCEPTION_CONTINUE_EXECUTION; case EXCEPTION_STACK_OVERFLOW: jl_throw_in_ctx(jl_stackovf_exception, ExceptionInfo->ContextRecord,in_ctx&&pSetThreadStackGuarantee); return EXCEPTION_CONTINUE_EXECUTION; case EXCEPTION_ACCESS_VIOLATION: if (jl_addr_is_safepoint(ExceptionInfo->ExceptionRecord->ExceptionInformation[1])) { #ifdef JULIA_ENABLE_THREADING jl_set_gc_and_wait(); // Do not raise sigint on worker thread if (ptls->tid != 0) return EXCEPTION_CONTINUE_EXECUTION; #endif if (ptls->defer_signal) { jl_safepoint_defer_sigint(); } else if (jl_safepoint_consume_sigint()) { jl_clear_force_sigint(); jl_throw_in_ctx(jl_interrupt_exception, ExceptionInfo->ContextRecord, in_ctx); } return EXCEPTION_CONTINUE_EXECUTION; } if (ExceptionInfo->ExceptionRecord->ExceptionInformation[0] == 1) { // writing to read-only memory (e.g. mmap) jl_throw_in_ctx(jl_readonlymemory_exception, ExceptionInfo->ContextRecord,in_ctx); return EXCEPTION_CONTINUE_EXECUTION; } } jl_safe_printf("\nPlease submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.\nException: "); switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: jl_safe_printf("EXCEPTION_ACCESS_VIOLATION"); break; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: jl_safe_printf("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); break; case EXCEPTION_BREAKPOINT: jl_safe_printf("EXCEPTION_BREAKPOINT"); break; case EXCEPTION_DATATYPE_MISALIGNMENT: jl_safe_printf("EXCEPTION_DATATYPE_MISALIGNMENT"); break; case EXCEPTION_FLT_DENORMAL_OPERAND: jl_safe_printf("EXCEPTION_FLT_DENORMAL_OPERAND"); break; case EXCEPTION_FLT_DIVIDE_BY_ZERO: jl_safe_printf("EXCEPTION_FLT_DIVIDE_BY_ZERO"); break; case EXCEPTION_FLT_INEXACT_RESULT: jl_safe_printf("EXCEPTION_FLT_INEXACT_RESULT"); break; case EXCEPTION_FLT_INVALID_OPERATION: jl_safe_printf("EXCEPTION_FLT_INVALID_OPERATION"); break; case EXCEPTION_FLT_OVERFLOW: jl_safe_printf("EXCEPTION_FLT_OVERFLOW"); break; case EXCEPTION_FLT_STACK_CHECK: jl_safe_printf("EXCEPTION_FLT_STACK_CHECK"); break; case EXCEPTION_FLT_UNDERFLOW: jl_safe_printf("EXCEPTION_FLT_UNDERFLOW"); break; case EXCEPTION_ILLEGAL_INSTRUCTION: jl_safe_printf("EXCEPTION_ILLEGAL_INSTRUCTION"); break; case EXCEPTION_IN_PAGE_ERROR: jl_safe_printf("EXCEPTION_IN_PAGE_ERROR"); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: jl_safe_printf("EXCEPTION_INT_DIVIDE_BY_ZERO"); break; case EXCEPTION_INT_OVERFLOW: jl_safe_printf("EXCEPTION_INT_OVERFLOW"); break; case EXCEPTION_INVALID_DISPOSITION: jl_safe_printf("EXCEPTION_INVALID_DISPOSITION"); break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: jl_safe_printf("EXCEPTION_NONCONTINUABLE_EXCEPTION"); break; case EXCEPTION_PRIV_INSTRUCTION: jl_safe_printf("EXCEPTION_PRIV_INSTRUCTION"); break; case EXCEPTION_SINGLE_STEP: jl_safe_printf("EXCEPTION_SINGLE_STEP"); break; case EXCEPTION_STACK_OVERFLOW: jl_safe_printf("EXCEPTION_STACK_OVERFLOW"); break; default: jl_safe_printf("UNKNOWN"); break; } jl_safe_printf(" at 0x%Ix -- ", (size_t)ExceptionInfo->ExceptionRecord->ExceptionAddress); jl_gdblookup((uintptr_t)ExceptionInfo->ExceptionRecord->ExceptionAddress); jl_critical_error(0, ExceptionInfo->ContextRecord, ptls->bt_data, &ptls->bt_size); static int recursion = 0; if (recursion++) exit(1); else jl_exit(1); } return EXCEPTION_CONTINUE_SEARCH; }
void jl_write_compiler_output(void) { if (!jl_generating_output()) { if (jl_options.outputjitbc) jl_dump_native(NULL, jl_options.outputjitbc, NULL, NULL, 0); return; } if (!jl_options.incremental) jl_precompile(jl_options.compile_enabled == JL_OPTIONS_COMPILE_ALL); if (!jl_module_init_order) { jl_printf(JL_STDERR, "WARNING: --output requested, but no modules defined during run\n"); return; } if (jl_options.outputjitbc) { jl_printf(JL_STDERR, "WARNING: --output-jit-bc is meaningless with options for dumping sysimage data\n"); } jl_array_t *worklist = jl_module_init_order; JL_GC_PUSH1(&worklist); jl_module_init_order = jl_alloc_vec_any(0); int i, l = jl_array_len(worklist); for (i = 0; i < l; i++) { jl_value_t *m = jl_ptrarrayref(worklist, i); jl_value_t *f = jl_get_global((jl_module_t*)m, jl_symbol("__init__")); if (f) { jl_array_ptr_1d_push(jl_module_init_order, m); // TODO: this would be better handled if moved entirely to jl_precompile // since it's a slightly duplication of effort jl_value_t *tt = jl_is_type(f) ? (jl_value_t*)jl_wrap_Type(f) : jl_typeof(f); JL_GC_PUSH1(&tt); tt = (jl_value_t*)jl_apply_tuple_type_v(&tt, 1); jl_compile_hint((jl_tupletype_t*)tt); JL_GC_POP(); } } if (jl_options.incremental) { if (jl_options.outputji) if (jl_save_incremental(jl_options.outputji, worklist)) jl_exit(1); if (jl_options.outputbc || jl_options.outputunoptbc) jl_printf(JL_STDERR, "WARNING: incremental output to a .bc file is not implemented\n"); if (jl_options.outputo) jl_printf(JL_STDERR, "WARNING: incremental output to a .o file is not implemented\n"); } else { ios_t *s = NULL; if (jl_options.outputo || jl_options.outputbc || jl_options.outputunoptbc) s = jl_create_system_image(); if (jl_options.outputji) { if (s == NULL) { jl_save_system_image(jl_options.outputji); } else { ios_t f; if (ios_file(&f, jl_options.outputji, 1, 1, 1, 1) == NULL) jl_errorf("cannot open system image file \"%s\" for writing", jl_options.outputji); ios_write(&f, (const char*)s->buf, (size_t)s->size); ios_close(&f); } } if (jl_options.outputo || jl_options.outputbc || jl_options.outputunoptbc) { assert(s); jl_dump_native(jl_options.outputbc, jl_options.outputunoptbc, jl_options.outputo, (const char*)s->buf, (size_t)s->size); } } for (size_t i = 0; i < jl_current_modules.size; i += 2) { if (jl_current_modules.table[i + 1] != HT_NOTFOUND) { jl_printf(JL_STDERR, "\nWARNING: detected unclosed module: "); jl_static_show(JL_STDERR, (jl_value_t*)jl_current_modules.table[i]); jl_printf(JL_STDERR, "\n ** incremental compilation may be broken for this module **\n\n"); } } JL_GC_POP(); }
// what to do on SIGINT JL_DLLEXPORT void jl_sigint_action(void) { if (exit_on_sigint) jl_exit(130); // 128+SIGINT jl_throw(jl_interrupt_exception); }
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 }
static void *signal_listener(void *arg) { static uintptr_t bt_data[JL_MAX_BT_SIZE + 1]; static size_t bt_size = 0; sigset_t sset; unw_context_t *signal_context; int sig, critical, profile; int i; jl_sigsetset(&sset); while (1) { profile = 0; sigwait(&sset, &sig); #ifndef HAVE_MACH # ifdef HAVE_ITIMER profile = (sig == SIGPROF); # else profile = (sig == SIGUSR1); # endif #endif if (sig == SIGINT) { if (exit_on_sigint) { critical = 1; } else { jl_try_deliver_sigint(); continue; } } else { critical = 0; } critical |= (sig == SIGTERM); critical |= (sig == SIGABRT); critical |= (sig == SIGQUIT); #ifdef SIGINFO critical |= (sig == SIGINFO); #else critical |= (sig == SIGUSR1 && !profile); #endif bt_size = 0; // sample each thread, round-robin style in reverse order // (so that thread zero gets notified last) for (i = jl_n_threads; i-- > 0; ) { // notify thread to stop jl_thread_suspend_and_get_state(i, &signal_context); // do backtrace on thread contexts for critical signals // this part must be signal-handler safe if (critical) { bt_size += rec_backtrace_ctx(bt_data + bt_size, JL_MAX_BT_SIZE / jl_n_threads - 1, signal_context); bt_data[bt_size++] = 0; } // do backtrace for profiler if (profile && running) { if (bt_size_cur < bt_size_max - 1) { // Get backtrace data bt_size_cur += rec_backtrace_ctx((uintptr_t*)bt_data_prof + bt_size_cur, bt_size_max - bt_size_cur - 1, signal_context); // Mark the end of this block with 0 bt_data_prof[bt_size_cur++] = 0; } if (bt_size_cur >= bt_size_max - 1) { // Buffer full: Delete the timer jl_profile_stop_timer(); } } // notify thread to resume jl_thread_resume(i, sig); } // this part is async with the running of the rest of the program // and must be thread-safe, but not necessarily signal-handler safe if (critical) { jl_critical_error(sig, NULL, bt_data, &bt_size); // FIXME // It is unsafe to run the exit handler on this thread // (this thread is not managed and has a rather limited stack space) // try harder to run this on a managed thread. #ifdef SIGINFO if (sig != SIGINFO) #else if (sig != SIGUSR1) #endif jl_exit(128 + sig); } } }
static void *signal_listener(void *arg) { static intptr_t bt_data[JL_MAX_BT_SIZE + 1]; static size_t bt_size = 0; sigset_t sset; unw_context_t *signal_context; int sig, critical, profile; int i; jl_sigsetset(&sset); #ifdef HAVE_SIGTIMEDWAIT siginfo_t info; sigaddset(&sset, SIGUSR2); sigprocmask(SIG_SETMASK, &sset, 0); #endif while (1) { profile = 0; #ifdef HAVE_SIGTIMEDWAIT if (running) { sig = sigtimedwait(&sset, &info, &timeoutprof); } else { sig = sigwaitinfo(&sset, &info); } if (sig == -1) { int err = errno; if (err == EAGAIN) { // this was a timeout event profile = 1; } else { assert(err == EINTR); continue; } } else if (sig == SIGUSR2) { // notification to toggle profiler running = !running; continue; } #else sigwait(&sset, &sig); #ifndef HAVE_MACH #ifdef HAVE_ITIMER profile = (sig == SIGPROF); #else profile = (sig == SIGUSR1); #endif #endif #endif critical = (sig == SIGINT && exit_on_sigint); critical |= (sig == SIGTERM); critical |= (sig == SIGABRT); critical |= (sig == SIGQUIT); #ifdef SIGINFO critical |= (sig == SIGINFO); #else critical |= (sig == SIGUSR1 && !profile); #endif bt_size = 0; // sample each thread, round-robin style in reverse order // (so that thread zero gets notified last) for (i = jl_n_threads; i-- > 0; ) { // notify thread to stop jl_thread_suspend_and_get_state(i, &signal_context, sig); // do backtrace on thread contexts for critical signals // this part must be signal-handler safe if (critical) { bt_size += rec_backtrace_ctx(bt_data + bt_size, JL_MAX_BT_SIZE / jl_n_threads - 1, signal_context); bt_data[bt_size++] = 0; } // do backtrace for profiler if (profile && running) { if (bt_size_cur < bt_size_max - 1) { // Get backtrace data bt_size_cur += rec_backtrace_ctx((ptrint_t*)bt_data_prof + bt_size_cur, bt_size_max - bt_size_cur - 1, signal_context); // Mark the end of this block with 0 bt_data_prof[bt_size_cur++] = 0; } if (bt_size_cur >= bt_size_max - 1) { // Buffer full: Delete the timer jl_profile_stop_timer(); } } // notify thread to resume jl_thread_resume(i, sig); } // this part is async with the running of the rest of the program // and must be thread-safe, but not necessarily signal-handler safe if (critical) { jl_critical_error(sig, NULL, bt_data, &bt_size); #ifdef SIGINFO if (sig != SIGINFO) #else if (sig != SIGUSR1) #endif jl_exit(128 + sig); } } }
static LONG WINAPI _exception_handler(struct _EXCEPTION_POINTERS *ExceptionInfo, int in_ctx) { if (ExceptionInfo->ExceptionRecord->ExceptionFlags == 0) { switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_INT_DIVIDE_BY_ZERO: fpreset(); jl_throw_in_ctx(jl_diverror_exception, ExceptionInfo->ContextRecord,in_ctx); return EXCEPTION_CONTINUE_EXECUTION; case EXCEPTION_STACK_OVERFLOW: jl_throw_in_ctx(jl_stackovf_exception, ExceptionInfo->ContextRecord,in_ctx&&pSetThreadStackGuarantee); return EXCEPTION_CONTINUE_EXECUTION; } jl_safe_printf("\nPlease submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.\nException: "); switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: jl_safe_printf("EXCEPTION_ACCESS_VIOLATION"); break; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: jl_safe_printf("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); break; case EXCEPTION_BREAKPOINT: jl_safe_printf("EXCEPTION_BREAKPOINT"); break; case EXCEPTION_DATATYPE_MISALIGNMENT: jl_safe_printf("EXCEPTION_DATATYPE_MISALIGNMENT"); break; case EXCEPTION_FLT_DENORMAL_OPERAND: jl_safe_printf("EXCEPTION_FLT_DENORMAL_OPERAND"); break; case EXCEPTION_FLT_DIVIDE_BY_ZERO: jl_safe_printf("EXCEPTION_FLT_DIVIDE_BY_ZERO"); break; case EXCEPTION_FLT_INEXACT_RESULT: jl_safe_printf("EXCEPTION_FLT_INEXACT_RESULT"); break; case EXCEPTION_FLT_INVALID_OPERATION: jl_safe_printf("EXCEPTION_FLT_INVALID_OPERATION"); break; case EXCEPTION_FLT_OVERFLOW: jl_safe_printf("EXCEPTION_FLT_OVERFLOW"); break; case EXCEPTION_FLT_STACK_CHECK: jl_safe_printf("EXCEPTION_FLT_STACK_CHECK"); break; case EXCEPTION_FLT_UNDERFLOW: jl_safe_printf("EXCEPTION_FLT_UNDERFLOW"); break; case EXCEPTION_ILLEGAL_INSTRUCTION: jl_safe_printf("EXCEPTION_ILLEGAL_INSTRUCTION"); break; case EXCEPTION_IN_PAGE_ERROR: jl_safe_printf("EXCEPTION_IN_PAGE_ERROR"); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: jl_safe_printf("EXCEPTION_INT_DIVIDE_BY_ZERO"); break; case EXCEPTION_INT_OVERFLOW: jl_safe_printf("EXCEPTION_INT_OVERFLOW"); break; case EXCEPTION_INVALID_DISPOSITION: jl_safe_printf("EXCEPTION_INVALID_DISPOSITION"); break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: jl_safe_printf("EXCEPTION_NONCONTINUABLE_EXCEPTION"); break; case EXCEPTION_PRIV_INSTRUCTION: jl_safe_printf("EXCEPTION_PRIV_INSTRUCTION"); break; case EXCEPTION_SINGLE_STEP: jl_safe_printf("EXCEPTION_SINGLE_STEP"); break; case EXCEPTION_STACK_OVERFLOW: jl_safe_printf("EXCEPTION_STACK_OVERFLOW"); break; default: jl_safe_printf("UNKNOWN"); break; } jl_safe_printf(" at 0x%Ix -- ", (size_t)ExceptionInfo->ExceptionRecord->ExceptionAddress); gdblookup((ptrint_t)ExceptionInfo->ExceptionRecord->ExceptionAddress); bt_size = rec_backtrace_ctx(bt_data, MAX_BT_SIZE, ExceptionInfo->ContextRecord); jlbacktrace(); static int recursion = 0; if (recursion++) exit(1); else jl_exit(1); } return EXCEPTION_CONTINUE_SEARCH; }
void parse_opts(int *argcp, char ***argvp) { enum { opt_machinefile = 300, opt_color, opt_history_file, opt_no_history_file, opt_startup_file, opt_compile, opt_code_coverage, opt_track_allocation, opt_check_bounds, opt_output_bc, opt_depwarn, opt_inline, opt_math_mode, opt_worker, opt_bind_to, opt_handle_signals, opt_output_o, opt_output_ji, opt_use_precompiled, opt_use_compilecache, opt_incremental }; static char* shortopts = "+vhqFfH:e:E:P:L:J:C:ip:O:"; static struct option longopts[] = { // exposed command line options // NOTE: This set of required arguments need to be kept in sync // with the required arguments defined in base/client.jl `process_options()` { "version", no_argument, 0, 'v' }, { "help", no_argument, 0, 'h' }, { "quiet", no_argument, 0, 'q' }, { "home", required_argument, 0, 'H' }, { "eval", required_argument, 0, 'e' }, { "print", required_argument, 0, 'E' }, { "post-boot", required_argument, 0, 'P' }, { "load", required_argument, 0, 'L' }, { "sysimage", required_argument, 0, 'J' }, { "precompiled", required_argument, 0, opt_use_precompiled }, { "compilecache", required_argument, 0, opt_use_compilecache }, { "cpu-target", required_argument, 0, 'C' }, { "procs", required_argument, 0, 'p' }, { "machinefile", required_argument, 0, opt_machinefile }, { "color", required_argument, 0, opt_color }, { "history-file", required_argument, 0, opt_history_file }, { "no-history-file", no_argument, 0, opt_no_history_file }, // deprecated { "startup-file", required_argument, 0, opt_startup_file }, { "no-startup", no_argument, 0, 'f' }, // deprecated { "compile", required_argument, 0, opt_compile }, { "code-coverage", optional_argument, 0, opt_code_coverage }, { "track-allocation",optional_argument, 0, opt_track_allocation }, { "optimize", optional_argument, 0, 'O' }, { "check-bounds", required_argument, 0, opt_check_bounds }, { "output-bc", required_argument, 0, opt_output_bc }, { "output-o", required_argument, 0, opt_output_o }, { "output-ji", required_argument, 0, opt_output_ji }, { "output-incremental",required_argument, 0, opt_incremental }, { "depwarn", required_argument, 0, opt_depwarn }, { "inline", required_argument, 0, opt_inline }, { "math-mode", required_argument, 0, opt_math_mode }, { "handle-signals", required_argument, 0, opt_handle_signals }, // hidden command line options { "worker", no_argument, 0, opt_worker }, { "bind-to", required_argument, 0, opt_bind_to }, { "lisp", no_argument, &lisp_prompt, 1 }, { 0, 0, 0, 0 } }; // getopt handles argument parsing up to -- delineator int argc = *argcp; char **argv = *argvp; if (argc > 0) { for (int i=0; i < argc; i++) { if (!strcmp(argv[i], "--")) { argc = i; break; } } } char *endptr; opterr = 0; // suppress getopt warning messages while (1) { int lastind = optind; int c = getopt_long(argc, argv, shortopts, longopts, 0); if (c == -1) break; restart_switch: switch (c) { case 0: break; case '?': case ':': if (optopt) { for (struct option *o = longopts; o->val; o++) { if (optopt == o->val) { if (o->has_arg == optional_argument) { c = o->val; goto restart_switch; } else if (strchr(shortopts, o->val)) { jl_errorf("option `-%c/--%s` is missing an argument", o->val, o->name); } else { jl_errorf("option `--%s` is missing an argument", o->name); } } } jl_errorf("unknown option `-%c`", optopt); } else { jl_errorf("unknown option `%s`", argv[lastind]); } break; case 'v': // version jl_printf(JL_STDOUT, "julia version %s\n", JULIA_VERSION_STRING); jl_exit(0); case 'h': // help jl_printf(JL_STDOUT, "%s%s", usage, opts); jl_exit(0); case 'q': // quiet jl_options.quiet = 1; break; case 'H': // home jl_options.julia_home = strdup(optarg); break; case 'e': // eval jl_options.eval = strdup(optarg); break; case 'E': // print jl_options.print = strdup(optarg); break; case 'P': // post-boot jl_options.postboot = strdup(optarg); break; case 'L': // load jl_options.load = strdup(optarg); break; case 'J': // sysimage jl_options.image_file = strdup(optarg); imagepathspecified = 1; break; case opt_use_precompiled: if (!strcmp(optarg,"yes")) jl_options.use_precompiled = JL_OPTIONS_USE_PRECOMPILED_YES; else if (!strcmp(optarg,"no")) jl_options.use_precompiled = JL_OPTIONS_USE_PRECOMPILED_NO; else jl_errorf("julia: invalid argument to --precompiled={yes|no} (%s)", optarg); break; case opt_use_compilecache: if (!strcmp(optarg,"yes")) jl_options.use_compilecache = JL_OPTIONS_USE_COMPILECACHE_YES; else if (!strcmp(optarg,"no")) jl_options.use_compilecache = JL_OPTIONS_USE_COMPILECACHE_NO; else jl_errorf("julia: invalid argument to --compilecache={yes|no} (%s)", optarg); break; case 'C': // cpu-target jl_options.cpu_target = strdup(optarg); break; case 'p': // procs errno = 0; if (!strcmp(optarg,"auto")) { jl_options.nprocs = jl_cpu_cores(); } else { long nprocs = strtol(optarg, &endptr, 10); if (errno != 0 || optarg == endptr || *endptr != 0 || nprocs < 1 || nprocs >= INT_MAX) jl_errorf("julia: -p,--procs=<n> must be an integer >= 1"); jl_options.nprocs = (int)nprocs; } break; case opt_machinefile: jl_options.machinefile = strdup(optarg); break; case opt_color: if (!strcmp(optarg,"yes")) jl_options.color = JL_OPTIONS_COLOR_ON; else if (!strcmp(optarg,"no")) jl_options.color = JL_OPTIONS_COLOR_OFF; else jl_errorf("julia: invalid argument to --color={yes|no} (%s)", optarg); break; case opt_history_file: if (!strcmp(optarg,"yes")) jl_options.historyfile = JL_OPTIONS_HISTORYFILE_ON; else if (!strcmp(optarg,"no")) jl_options.historyfile = JL_OPTIONS_HISTORYFILE_OFF; else jl_errorf("julia: invalid argument to --history-file={yes|no} (%s)", optarg); break; case opt_no_history_file: jl_options.historyfile = JL_OPTIONS_HISTORYFILE_OFF; break; case opt_startup_file: if (!strcmp(optarg,"yes")) jl_options.startupfile = JL_OPTIONS_STARTUPFILE_ON; else if (!strcmp(optarg,"no")) jl_options.startupfile = JL_OPTIONS_STARTUPFILE_OFF; else jl_errorf("julia: invalid argument to --startup-file={yes|no} (%s)", optarg); break; case 'f': jl_options.startupfile = JL_OPTIONS_STARTUPFILE_OFF; break; case 'F': jl_options.startupfile = JL_OPTIONS_STARTUPFILE_ON; break; case opt_compile: if (!strcmp(optarg,"yes")) jl_options.compile_enabled = JL_OPTIONS_COMPILE_ON; else if (!strcmp(optarg,"no")) jl_options.compile_enabled = JL_OPTIONS_COMPILE_OFF; else if (!strcmp(optarg,"all")) jl_options.compile_enabled = JL_OPTIONS_COMPILE_ALL; else if (!strcmp(optarg,"min")) jl_options.compile_enabled = JL_OPTIONS_COMPILE_MIN; else jl_errorf("julia: invalid argument to --compile (%s)", optarg); break; case opt_code_coverage: if (optarg != NULL) { if (!strcmp(optarg,"user")) codecov = JL_LOG_USER; else if (!strcmp(optarg,"all")) codecov = JL_LOG_ALL; else if (!strcmp(optarg,"none")) codecov = JL_LOG_NONE; else jl_errorf("julia: invalid argument to --code-coverage (%s)", optarg); break; } else { codecov = JL_LOG_USER; } break; case opt_track_allocation: if (optarg != NULL) { if (!strcmp(optarg,"user")) malloclog = JL_LOG_USER; else if (!strcmp(optarg,"all")) malloclog = JL_LOG_ALL; else if (!strcmp(optarg,"none")) malloclog = JL_LOG_NONE; else jl_errorf("julia: invalid argument to --track-allocation (%s)", optarg); break; } else { malloclog = JL_LOG_USER; } break; case 'O': // optimize if (optarg != NULL) { if (!strcmp(optarg,"0")) jl_options.opt_level = 0; else if (!strcmp(optarg,"1")) jl_options.opt_level = 1; else if (!strcmp(optarg,"2")) jl_options.opt_level = 2; else if (!strcmp(optarg,"3")) jl_options.opt_level = 3; else jl_errorf("julia: invalid argument to -O (%s)", optarg); break; } else { jl_options.opt_level = 3; } break; case 'i': // isinteractive jl_options.isinteractive = 1; break; case opt_check_bounds: if (!strcmp(optarg,"yes")) jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_ON; else if (!strcmp(optarg,"no")) jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_OFF; else jl_errorf("julia: invalid argument to --check-bounds={yes|no} (%s)", optarg); break; case opt_output_bc: jl_options.outputbc = optarg; if (!imagepathspecified) jl_options.image_file = NULL; break; case opt_output_o: jl_options.outputo = optarg; if (!imagepathspecified) jl_options.image_file = NULL; break; case opt_output_ji: jl_options.outputji = optarg; if (!imagepathspecified) jl_options.image_file = NULL; break; case opt_incremental: if (!strcmp(optarg,"yes")) jl_options.incremental = 1; else if (!strcmp(optarg,"no")) jl_options.incremental = 0; else jl_errorf("julia: invalid argument to --output-incremental={yes|no} (%s)", optarg); break; case opt_depwarn: if (!strcmp(optarg,"yes")) jl_options.depwarn = JL_OPTIONS_DEPWARN_ON; else if (!strcmp(optarg,"no")) jl_options.depwarn = JL_OPTIONS_DEPWARN_OFF; else if (!strcmp(optarg,"error")) jl_options.depwarn = JL_OPTIONS_DEPWARN_ERROR; else jl_errorf("julia: invalid argument to --depwarn={yes|no|error} (%s)", optarg); break; case opt_inline: if (!strcmp(optarg,"yes")) jl_options.can_inline = 1; else if (!strcmp(optarg,"no")) jl_options.can_inline = 0; else { jl_errorf("julia: invalid argument to --inline (%s)", optarg); } break; case opt_math_mode: if (!strcmp(optarg,"ieee")) jl_options.fast_math = JL_OPTIONS_FAST_MATH_OFF; else if (!strcmp(optarg,"fast")) jl_options.fast_math = JL_OPTIONS_FAST_MATH_ON; else if (!strcmp(optarg,"user")) jl_options.fast_math = JL_OPTIONS_FAST_MATH_DEFAULT; else jl_errorf("julia: invalid argument to --math-mode (%s)", optarg); break; case opt_worker: jl_options.worker = 1; break; case opt_bind_to: jl_options.bindto = strdup(optarg); break; case opt_handle_signals: if (!strcmp(optarg,"yes")) jl_options.handle_signals = JL_OPTIONS_HANDLE_SIGNALS_ON; else if (!strcmp(optarg,"no")) jl_options.handle_signals = JL_OPTIONS_HANDLE_SIGNALS_OFF; else jl_errorf("julia: invalid argument to --handle-signals (%s)", optarg); break; default: jl_errorf("julia: unhandled option -- %c\n" "This is a bug, please report it.", c); } } jl_options.code_coverage = codecov; jl_options.malloc_log = malloclog; *argvp += optind; *argcp -= optind; }
DLLEXPORT void jl_restore_system_image(char *fname) { ios_t f; char *fpath = fname; if (ios_file(&f, fpath, 1, 0, 0, 0) == NULL) { JL_PRINTF(JL_STDERR, "system image file not found\n"); jl_exit(1); } #ifdef JL_GC_MARKSWEEP int en = jl_gc_is_enabled(); jl_gc_disable(); #endif tagtype_list = jl_alloc_cell_1d(0); jl_array_type->env = jl_deserialize_value(&f); jl_main_module = (jl_module_t*)jl_deserialize_value(&f); jl_core_module = (jl_module_t*)jl_get_global(jl_main_module, jl_symbol("Core")); jl_base_module = (jl_module_t*)jl_get_global(jl_main_module, jl_symbol("Base")); jl_current_module = jl_base_module; // run start_image in Base // cache builtin parametric types for(int i=0; i < jl_array_len(tagtype_list); i++) { jl_value_t *v = jl_cellref(tagtype_list, i); uint32_t uid=0; if (jl_is_struct_type(v)) uid = ((jl_struct_type_t*)v)->uid; else if (jl_is_bits_type(v)) uid = ((jl_bits_type_t*)v)->uid; jl_cache_type_((jl_tag_type_t*)v); if (jl_is_struct_type(v)) ((jl_struct_type_t*)v)->uid = uid; else if (jl_is_bits_type(v)) ((jl_bits_type_t*)v)->uid = uid; } jl_get_builtin_hooks(); jl_get_system_hooks(); jl_boot_file_loaded = 1; jl_typeinf_func = (jl_function_t*)jl_get_global(jl_base_module, jl_symbol("typeinf_ext")); jl_init_box_caches(); jl_set_t_uid_ctr(read_int32(&f)); jl_set_gs_ctr(read_int32(&f)); htable_reset(&backref_table, 0); ios_t ss; ios_mem(&ss, 0); ios_copyuntil(&ss, &f, '\0'); ios_close(&f); if (fpath != fname) free(fpath); #ifdef JL_GC_MARKSWEEP if (en) jl_gc_enable(); #endif // TODO: there is no exception handler here! jl_load_file_string(ss.buf); ios_close(&ss); }