📄 erl_init.c
字号:
#endif#if defined(HIPE) hipe_signal_init(); /* must be done very early */#endif erl_sys_init();#ifdef ERTS_SMP { int ncpu = erts_no_of_cpus(); no_of_schedulers = (Uint) (ncpu > 0 ? ncpu : 1); }#endif erl_sys_args(argc, argv); erts_ets_realloc_always_moves = 0;}voiderl_start(int argc, char **argv){ int i = 1; char* arg=NULL; char* Parg = NULL; int have_break_handler = 1; char* tmpenvbuf; int async_max_threads = erts_async_max_threads; early_init(&argc, argv); tmpenvbuf = getenv(ERL_MAX_ETS_TABLES_ENV); if (tmpenvbuf != NULL) user_requested_db_max_tabs = atoi(tmpenvbuf); else user_requested_db_max_tabs = 0; tmpenvbuf = getenv("ERL_FULLSWEEP_AFTER"); if (tmpenvbuf != NULL) { Uint16 max_gen_gcs = atoi(tmpenvbuf); erts_smp_atomic_set(&erts_max_gen_gcs, (long) max_gen_gcs); } tmpenvbuf = getenv("ERL_THREAD_POOL_SIZE"); if (tmpenvbuf != NULL) { async_max_threads = atoi(tmpenvbuf); } #ifdef DEBUG verbose = DEBUG_DEFAULT;#endif erts_error_logger_warnings = am_error; while (i < argc) { if (argv[i][0] != '-') { erts_usage(); } if (strcmp(argv[i], "--") == 0) { /* end of emulator options */ i++; break; } switch (argv[i][1]) { /* * NOTE: -M flags are handled (and removed from argv) by * erts_alloc_init(). * * The -d, -m, -S, -t, and -T flags was removed in * Erlang 5.3/OTP R9C. * * -S, and -T has been reused in Erlang 5.5/OTP R11B. */ case '#' : arg = get_arg(argv[i]+2, argv[i+1], &i); if ((display_items = atoi(arg)) == 0) { erts_fprintf(stderr, "bad display items%s\n", arg); erts_usage(); } VERBOSE(DEBUG_SYSTEM, ("using display items %d\n",display_items)); break; case 'l': display_loads++; break; case 'v':#ifdef DEBUG if (argv[i][2] == '\0') { verbose |= DEBUG_SYSTEM; } else { char *ch; for (ch = argv[i]+2; *ch != '\0'; ch++) { switch (*ch) { case 's': verbose |= DEBUG_SYSTEM; break; case 'g': verbose |= DEBUG_PRIVATE_GC; break; case 'h': verbose |= DEBUG_HYBRID_GC; break; case 'M': verbose |= DEBUG_MEMORY; break; case 'a': verbose |= DEBUG_ALLOCATION; break; case 't': verbose |= DEBUG_THREADS; break; case 'p': verbose |= DEBUG_PROCESSES; break; case 'm': verbose |= DEBUG_MESSAGES; break; default : erts_fprintf(stderr,"Unknown verbose option: %c\n",*ch); } } } erts_printf("Verbose level: "); if (verbose & DEBUG_SYSTEM) erts_printf("SYSTEM "); if (verbose & DEBUG_PRIVATE_GC) erts_printf("PRIVATE_GC "); if (verbose & DEBUG_HYBRID_GC) erts_printf("HYBRID_GC "); if (verbose & DEBUG_MEMORY) erts_printf("PARANOID_MEMORY "); if (verbose & DEBUG_ALLOCATION) erts_printf("ALLOCATION "); if (verbose & DEBUG_THREADS) erts_printf("THREADS "); if (verbose & DEBUG_PROCESSES) erts_printf("PROCESSES "); if (verbose & DEBUG_MESSAGES) erts_printf("MESSAGES "); erts_printf("\n");#else erts_fprintf(stderr, "warning: -v (only in debug compiled code)\n");#endif break; case 'V' : { char tmp[256]; tmp[0] = tmp[1] = '\0';#ifdef DEBUG strcat(tmp, ",DEBUG");#endif#ifdef ERTS_SMP strcat(tmp, ",SMP");#endif#ifdef USE_THREADS strcat(tmp, ",ASYNC_THREADS");#endif#ifdef HIPE strcat(tmp, ",HIPE");#endif#ifdef INCREMENTAL strcat(tmp, ",INCREMENTAL_GC");#endif#ifdef HYBRID strcat(tmp, ",HYBRID");#endif erts_fprintf(stderr, "Erlang "); if (tmp[1]) { erts_fprintf(stderr, "(%s) ", tmp+1); } erts_fprintf(stderr, "(" EMULATOR ") emulator version " ERLANG_VERSION "\n"); erl_exit(0, ""); } break; case 'H': /* undocumented */ fprintf(stderr, "The undocumented +H option has been removed (R10B-6).\n\n"); break; case 'h': /* set default heap size */ arg = get_arg(argv[i]+2, argv[i+1], &i); if ((H_MIN_SIZE = atoi(arg)) <= 0) { erts_fprintf(stderr, "bad heap size %s\n", arg); erts_usage(); } VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n",H_MIN_SIZE)); break; case 'e': /* set maximum number of ets tables */ arg = get_arg(argv[i]+2, argv[i+1], &i); if (( user_requested_db_max_tabs = atoi(arg) ) < 0) { erts_fprintf(stderr, "bad maximum number of ets tables %s\n", arg); erts_usage(); } VERBOSE(DEBUG_SYSTEM, ("using maximum number of ets tables %d\n", user_requested_db_max_tabs)); break; case 'i': /* define name of module for initial function */ init = get_arg(argv[i]+2, argv[i+1], &i); break; case 'b': /* define name of initial function */ boot = get_arg(argv[i]+2, argv[i+1], &i); break; case 'B': if (argv[i][2] == 'i') /* +Bi */ ignore_break = 1; else if (argv[i][2] == 'c') /* +Bc */ replace_intr = 1; else if (argv[i][2] == 'd') /* +Bd */ have_break_handler = 0; else if (argv[i+1][0] == 'i') { /* +B i */ get_arg(argv[i]+2, argv[i+1], &i); ignore_break = 1; } else if (argv[i+1][0] == 'c') { /* +B c */ get_arg(argv[i]+2, argv[i+1], &i); replace_intr = 1; } else if (argv[i+1][0] == 'd') { /* +B d */ get_arg(argv[i]+2, argv[i+1], &i); have_break_handler = 0; } else /* +B */ have_break_handler = 0; break; case 'K': /* If kernel poll support is present, erl_sys_args() will remove the K parameter and value */ get_arg(argv[i]+2, argv[i+1], &i); erts_fprintf(stderr, "kernel-poll not supported; \"K\" parameter ignored\n", arg); break; case 'P': /* set maximum number of processes */ Parg = get_arg(argv[i]+2, argv[i+1], &i); erts_max_processes = atoi(Parg); /* Check of result is delayed until later. This is because +R may be given after +P. */ break; case 'S' : { int no; arg = get_arg(argv[i]+2, argv[i+1], &i); no = atoi(arg); if (no < 1 || ERTS_MAX_NO_OF_SCHEDULERS < no) { erts_fprintf(stderr, "bad number of scheduler threads %s\n", arg); erts_usage(); } VERBOSE(DEBUG_SYSTEM, ("using %d scheduler(s)\n", no));#ifdef ERTS_SMP no_of_schedulers = (Uint) no;#endif break; } case 'T' : arg = get_arg(argv[i]+2, argv[i+1], &i); errno = 0; erts_modified_timing_level = atoi(arg); if ((erts_modified_timing_level == 0 && errno != 0) || erts_modified_timing_level < 0 || erts_modified_timing_level >= ERTS_MODIFIED_TIMING_LEVELS) { erts_fprintf(stderr, "bad modified timing level %s\n", arg); erts_usage(); } else { VERBOSE(DEBUG_SYSTEM, ("using modified timing level %d\n", erts_modified_timing_level)); } break; case 'R': { /* set compatibility release */ arg = get_arg(argv[i]+2, argv[i+1], &i); erts_compat_rel = atoi(arg); if (erts_compat_rel < ERTS_MIN_COMPAT_REL || erts_compat_rel > this_rel_num()) { erts_fprintf(stderr, "bad compatibility release number %s\n", arg); erts_usage(); } ASSERT(ERTS_MIN_COMPAT_REL >= 7); switch (erts_compat_rel) { case 7: case 8: case 9: erts_use_r9_pids_ports = 1; default: break; } break; } case 'A': /* set number of threads in thread pool */ arg = get_arg(argv[i]+2, argv[i+1], &i); if (((async_max_threads = atoi(arg)) < 0) || (async_max_threads > ERTS_MAX_NO_OF_ASYNC_THREADS)) { erts_fprintf(stderr, "bad number of async threads %s\n", arg); erts_usage(); } VERBOSE(DEBUG_SYSTEM, ("using %d async-threads\n", async_max_threads)); break; case 'a': /* suggested stack size (Kilo Words) for threads in thread pool */ arg = get_arg(argv[i]+2, argv[i+1], &i); erts_async_thread_suggested_stack_size = atoi(arg); if ((erts_async_thread_suggested_stack_size < ERTS_ASYNC_THREAD_MIN_STACK_SIZE) || (erts_async_thread_suggested_stack_size > ERTS_ASYNC_THREAD_MAX_STACK_SIZE)) { erts_fprintf(stderr, "bad stack size for async threads %s\n", arg); erts_usage(); } VERBOSE(DEBUG_SYSTEM, ("suggested async-thread stack size %d kilo words\n", erts_async_thread_suggested_stack_size)); break; case 'r': erts_ets_realloc_always_moves = 1; break; case 'n': /* XXX obsolete */ break; case 'c': if (argv[i][2] == 0) { /* -c: documented option */ erts_disable_tolerant_timeofday = 1; }#ifndef ERTS_SMP /* Not supported with smp emulator */ else if (argv[i][2] == 'i') { /* -ci: undcoumented option */ count_instructions = 1; }#endif break; case 'W': arg = get_arg(argv[i]+2, argv[i+1], &i); switch (arg[0]) { case 'i': erts_error_logger_warnings = am_info; break; case 'w': erts_error_logger_warnings = am_warning; break; case 'e': /* The default */ erts_error_logger_warnings = am_error; default: erts_fprintf(stderr, "unrecognized warning_map option %s\n", arg); erts_usage(); } break; default: erts_fprintf(stderr, "%s unknown flag %s\n", argv[0], argv[i]); erts_usage(); } i++; }#ifdef USE_THREADS erts_async_max_threads = async_max_threads;#endif /* Delayed check of +P flag */ if (erts_max_processes < ERTS_MIN_PROCESSES || erts_max_processes > ERTS_MAX_PROCESSES || (erts_use_r9_pids_ports && erts_max_processes > ERTS_MAX_R9_PROCESSES)) { erts_fprintf(stderr, "bad number of processes %s\n", Parg); erts_usage(); } /* Restart will not reinstall the break handler */#ifdef __WIN32__ if (ignore_break) erts_set_ignore_break(); else if (replace_intr) erts_replace_intr(); else init_break_handler();#else if (ignore_break) erts_set_ignore_break(); else if (have_break_handler) init_break_handler(); if (replace_intr) erts_replace_intr();#endif boot_argc = argc - i; /* Number of arguments to init */ boot_argv = &argv[i]; erl_init(); init_shared_memory(boot_argc, boot_argv); load_preloaded(); erts_initialized = 1; erl_first_process_otp("otp_ring0", NULL, 0, boot_argc, boot_argv);#ifdef ERTS_SMP erts_start_schedulers(no_of_schedulers); /* Let system specific code decide what to do with the main thread... */ erts_sys_main_thread(); /* May or may not return! */#else process_main();#endif}#ifdef USE_THREADSvoid erts_thr_fatal_error(int err, char *what){ char *errstr = err ? strerror(err) : NULL; erts_fprintf(stderr, "Failed to %s: %s%s(%d)\n", what, errstr ? errstr : "", errstr ? " " : "", err); abort();}#endifstatic voidsystem_cleanup(int exit_code){ /* No cleanup wanted if ... * 1. we are about to do an abnormal exit * 2. we haven't finished initializing, or * 3. another thread than the main thread is performing the exit * (in threaded non smp case). */ if (exit_code != 0 || !erts_initialized#if defined(USE_THREADS) && !defined(ERTS_SMP) || !erts_equal_tids(main_thread, erts_thr_self())#endif ) return;#ifdef ERTS_SMP#ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_check_exact(NULL, 0);#endif erts_smp_block_system(ERTS_BS_FLG_ALLOW_GC); /* We never release it... */#endif#ifdef HYBRID if (ma_src_stack) erts_free(ERTS_ALC_T_OBJECT_STACK, (void *)ma_src_stack); if (ma_dst_stack) erts_free(ERTS_ALC_T_OBJECT_STACK, (void *)ma_dst_stack); if (ma_offset_stack) erts_free(ERTS_ALC_T_OBJECT_STACK, (void *)ma_offset_stack); ma_src_stack = NULL; ma_dst_stack = NULL; ma_offset_stack = NULL; erts_cleanup_offheap(&erts_global_offheap);#endif#if defined(HYBRID) && !defined(INCREMENTAL) if (global_heap) { ERTS_HEAP_FREE(ERTS_ALC_T_HEAP, (void*) global_heap, sizeof(Eterm) * global_heap_sz); } global_heap = NULL;#endif#ifdef INCREMENTAL erts_cleanup_incgc();#endif#if defined(USE_THREADS) && !defined(ERTS_SMP) exit_async();#endif#if HAVE_ERTS_MSEG erts_mseg_exit();#endif /* * A lot more cleaning could/should have been done... */}/* * Common exit function, all exits from the system go through here. * n <= 0 -> normal exit with status n; * n = 127 -> Erlang crash dump produced, exit with status 1; * other positive n -> Erlang crash dump and core dump produced. */void erl_exit0(char *file, int line, int n, char *fmt,...){ unsigned int an; va_list args; va_start(args, fmt); save_statistics(); system_cleanup(n); an = abs(n); if (erts_mtrace_enabled) erts_mtrace_exit((Uint32) an); /* Produce an Erlang core dump if error */ if(n > 0 && erts_initialized) erl_crash_dump_v(file,line,fmt,args); /* need to reinitialize va_args thing */ va_end(args); va_start(args, fmt); if (fmt != NULL && *fmt != '\0') erl_error(fmt, args); /* Print error message. */ va_end(args);#ifdef __WIN32__ if(n > 0) ConWaitForExit(); else ConNormalExit();#endif#if !defined(__WIN32__) && !defined(VXWORKS) && !defined(_OSE_) sys_tty_reset();#endif if (n == ERTS_INTR_EXIT) exit(0); else if (n == 127) ERTS_EXIT_AFTER_DUMP(1); else if (n > 0 || n == ERTS_ABORT_EXIT) abort(); exit(an);}void erl_exit(int n, char *fmt,...){ unsigned int an; va_list args; va_start(args, fmt); save_statistics(); system_cleanup(n); an = abs(n); if (erts_mtrace_enabled) erts_mtrace_exit((Uint32) an); /* Produce an Erlang core dump if error */ if(n > 0 && erts_initialized) erl_crash_dump_v((char*) NULL,0,fmt,args); /* need to reinitialize va_args thing */ va_end(args); va_start(args, fmt); if (fmt != NULL && *fmt != '\0') erl_error(fmt, args); /* Print error message. */ va_end(args);#ifdef __WIN32__ if(n > 0) ConWaitForExit(); else ConNormalExit();#endif#if !defined(__WIN32__) && !defined(VXWORKS) && !defined(_OSE_) sys_tty_reset();#endif if (n == ERTS_INTR_EXIT) exit(0); else if (n == ERTS_DUMP_EXIT) ERTS_EXIT_AFTER_DUMP(1); else if (n > 0 || n == ERTS_ABORT_EXIT) abort(); exit(an);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -