X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fruntime.c;h=e49d7d15052c900e11959430b21e8135577d6157;hb=0e3c4b4db102bd204a30402d7e5a0de44aea57ce;hp=59cead9c4c6f5a98d35383675efa25b5a3299656;hpb=bd93f052f95371f613fb913c1cac2b01c8ff2a5c;p=sbcl.git diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 59cead9..e49d7d1 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -17,6 +17,7 @@ #include #include +#include #ifndef LISP_FEATURE_WIN32 #include #endif @@ -29,18 +30,21 @@ #include #include #include -#include +#include "runtime.h" #ifndef LISP_FEATURE_WIN32 #include #endif #include #include +#include #if defined(SVR4) || defined(__linux__) #include #endif +#if !(defined(LISP_FEATURE_WIN32) && defined(LISP_FEATURE_SB_THREAD)) #include "signal.h" +#endif #include "runtime.h" #include "vars.h" @@ -67,7 +71,7 @@ #endif #ifndef SBCL_HOME -#define SBCL_HOME "/usr/local/lib/sbcl/" +#define SBCL_HOME SBCL_PREFIX"/lib/sbcl/" #endif #ifdef LISP_FEATURE_HPUX @@ -91,7 +95,7 @@ void sigint_init(void) { SHOW("entering sigint_init()"); - install_handler(SIGINT, sigint_handler); + install_handler(SIGINT, sigint_handler, 1); SHOW("leaving sigint_init()"); } @@ -178,6 +182,14 @@ Common toplevel options:\n\ --userinit Per-user init-file to use instead of default.\n\ --no-sysinit Inhibit processing of any system-wide init-file.\n\ --no-userinit Inhibit processing of any per-user init-file.\n\ + --disable-debugger Invoke sb-ext:disable-debugger.\n\ + --noprint Run a Read-Eval Loop without printing results.\n\ + --script [] Skip #! line, disable debugger, avoid verbosity.\n\ + --quit Exit with code 0 after option processing.\n\ + --non-interactive Sets both --quit and --disable-debugger.\n\ +Common toplevel options that are processed in order:\n\ + --eval
Form to eval when processing this option.\n\ + --load File to load when processing this option.\n\ \n\ User options are not processed by SBCL. All runtime options must\n\ appear before toplevel options, and all toplevel options must\n\ @@ -205,7 +217,15 @@ SBCL is free software, provided as is, with absolutely no warranty.\n\ It is mostly in the public domain; some portions are provided under\n\ BSD-style licenses. See the CREDITS and COPYING files in the\n\ distribution for more information.\n\ -", SBCL_VERSION_STRING); +" +#ifdef LISP_FEATURE_WIN32 +"\n\ +WARNING: the Windows port is fragile, particularly for multithreaded\n\ +code. Unfortunately, the development team currently lacks the time\n\ +and resources this platform demands.\n\ +" +#endif +, SBCL_VERSION_STRING); } /* Look for a core file to load, first in the directory named by the @@ -275,6 +295,18 @@ search_for_executable(const char *argv0) return search; } } + /* The above for-loop fails to process the last part of PATH if PATH does + * not end with ':'. We may consider appending an extra ':' to the end of + * SEARCH. -- houjingyi 2013-05-24 */ + if (start != NULL && *start != '\0') { + snprintf(buf, PATH_MAX + 1, "%s/%s", start, argv0); + if (access(buf, F_OK) == 0) { + free(search); + search = copied_realpath(buf); + free(buf); + return search; + } + } free(search); free(buf); @@ -282,12 +314,103 @@ search_for_executable(const char *argv0) } #endif /* LISP_FEATURE_WIN32 */ +size_t +parse_size_arg(char *arg, char *arg_name) +{ + char *tail, *power_name; + size_t power, res; + + res = strtoul(arg, &tail, 0); + + if (arg == tail) { + lose("%s argument is not a number: %s", arg_name, arg); + } else if (tail[0]) { + int i, size; + power_name = copied_string(tail); + size = strlen(power_name); + for (i=0; i= (SIZE_MAX >> power))) { + lose("%s argument is out of range: %s", arg_name, arg); + } + res <<= power; + return res; +} + char **posix_argv; char *core_string; struct runtime_options *runtime_options; char *saved_runtime_path = NULL; +#if defined(LISP_FEATURE_WIN32) && defined(LISP_FEATURE_SB_THREAD) +void pthreads_win32_init(); +#endif + +void print_locale_variable(const char *name) +{ + char *value = getenv(name); + + if (value) { + fprintf(stderr, "\n %s=%s", name, value); + } +} + +void setup_locale() +{ + if(setlocale(LC_ALL, "") == NULL) { +#ifndef LISP_FEATURE_WIN32 + + fprintf(stderr, "WARNING: Setting locale failed.\n"); + fprintf(stderr, " Check the following variables for correct values:"); + + if (setlocale(LC_CTYPE, "") == NULL) { + print_locale_variable("LC_ALL"); + print_locale_variable("LC_CTYPE"); + print_locale_variable("LANG"); + } + + if (setlocale(LC_MESSAGES, "") == NULL) { + print_locale_variable("LC_MESSAGES"); + } + if (setlocale(LC_COLLATE, "") == NULL) { + print_locale_variable("LC_COLLATE"); + } + if (setlocale(LC_MONETARY, "") == NULL) { + print_locale_variable("LC_MONETARY"); + } + if (setlocale(LC_NUMERIC, "") == NULL) { + print_locale_variable("LC_NUMERIC"); + } + if (setlocale(LC_TIME, "") == NULL) { + print_locale_variable("LC_TIME"); + } + fprintf(stderr, "\n"); + +#endif + } +} + int main(int argc, char *argv[], char *envp[]) @@ -312,11 +435,14 @@ main(int argc, char *argv[], char *envp[]) lispobj initial_function; const char *sbcl_home = getenv("SBCL_HOME"); +#if defined(LISP_FEATURE_WIN32) && defined(LISP_FEATURE_SB_THREAD) + os_preinit(); + pthreads_win32_init(); +#endif + interrupt_init(); block_blockable_signals(0, 0); - setlocale(LC_ALL, ""); - runtime_options = NULL; /* Save the argv[0] derived runtime path in case @@ -336,7 +462,8 @@ main(int argc, char *argv[], char *envp[]) core = (runtime_path ? runtime_path : copied_string(saved_runtime_path)); } else { - free(runtime_path); + if (runtime_path) + free(runtime_path); } } @@ -392,25 +519,29 @@ main(int argc, char *argv[], char *envp[]) ++argi; if (argi >= argc) lose("missing argument for --dynamic-space-size"); - errno = 0; - dynamic_space_size = strtol(argv[argi++], 0, 0) << 20; - if (errno) - lose("argument to --dynamic-space-size is not a number"); + dynamic_space_size = parse_size_arg(argv[argi++], + "--dynamic-space-size"); # ifdef MAX_DYNAMIC_SPACE_END if (!((DYNAMIC_SPACE_START < DYNAMIC_SPACE_START+dynamic_space_size) && (DYNAMIC_SPACE_START+dynamic_space_size <= - MAX_DYNAMIC_SPACE_END))) - lose("specified --dynamic-space-size too large"); + MAX_DYNAMIC_SPACE_END))) { + char* suffix = ""; + char* size = argv[argi-1]; + if (!strchr(size, 'B') && !strchr(size, 'b')) { + suffix = " [MB]"; + } + lose("--dynamic-space-size argument %s%s is too large, max %lu KB", + size, suffix, + (MAX_DYNAMIC_SPACE_END-DYNAMIC_SPACE_START) / 1024); + } # endif } else if (0 == strcmp(arg, "--control-stack-size")) { ++argi; if (argi >= argc) lose("missing argument for --control-stack-size"); errno = 0; - thread_control_stack_size = strtol(argv[argi++], 0, 0) << 20; - if (errno) - lose("argument to --control-stack-size is not a number"); + thread_control_stack_size = parse_size_arg(argv[argi++], "--control-stack-size"); } else if (0 == strcmp(arg, "--debug-environment")) { int n = 0; printf("; Commandline arguments:\n"); @@ -435,6 +566,15 @@ main(int argc, char *argv[], char *envp[]) end_runtime_options = 1; ++argi; break; + } else if (0 == strcmp(arg, "--merge-core-pages")) { + ++argi; + merge_core_pages = 1; + } else if (0 == strcmp(arg, "--no-merge-core-pages")) { + ++argi; + merge_core_pages = 0; + } else if (0 == strcmp(arg, "--default-merge-core-pages")) { + ++argi; + merge_core_pages = -1; } else { /* This option was unrecognized as a runtime option, * so it must be a toplevel option or a user option, @@ -472,8 +612,11 @@ main(int argc, char *argv[], char *envp[]) /* Align down to multiple of page_table page size, and to the appropriate * stack alignment. */ - dynamic_space_size &= ~(PAGE_BYTES-1); - thread_control_stack_size &= ~(CONTROL_STACK_ALIGNMENT_BYTES-1); + dynamic_space_size &= ~(sword_t)(PAGE_BYTES-1); +#ifdef LISP_FEATURE_GENCGC + dynamic_space_size &= ~(sword_t)(GENCGC_CARD_BYTES-1); +#endif + thread_control_stack_size &= ~(sword_t)(CONTROL_STACK_ALIGNMENT_BYTES-1); /* Preserve the runtime options for possible future core saving */ runtime_options->dynamic_space_size = dynamic_space_size; @@ -483,10 +626,13 @@ main(int argc, char *argv[], char *envp[]) * systems (e.g. Alpha) arch_init() needs need os_vm_page_size, so * it must follow os_init(). -- WHN 2000-01-26 */ os_init(argv, envp); + dyndebug_init(); /* after os_init: do not print output before execve */ arch_init(); gc_init(); validate(); + setup_locale(); + /* If no core file was specified, look for one. */ if (!core) { core = search_for_core(); @@ -513,6 +659,19 @@ main(int argc, char *argv[], char *envp[]) fflush(stdout); } + if (embedded_core_offset == 0) { + /* Here we make a last attempt at recognizing an embedded core, + * so that a file with an embedded core is a valid argument to + * --core. We take care that any decisions on special behaviour + * (suppressed banner, embedded options) have already been made + * before we reach this block, so that there is no observable + * difference between "embedded" and "bare" images given to + * --core. */ + os_vm_offset_t offset = search_for_embedded_core(core); + if (offset != -1) + embedded_core_offset = offset; + } + #if defined(SVR4) || defined(__linux__) || defined(__NetBSD__) tzset(); #endif @@ -529,6 +688,9 @@ main(int argc, char *argv[], char *envp[]) if (initial_function == NIL) { lose("couldn't find initial function\n"); } +#ifdef LISP_FEATURE_SB_DYNAMIC_CORE + os_link_runtime(); +#endif #ifdef LISP_FEATURE_HPUX /* -1 = CLOSURE_FUN_OFFSET, 23 = SIMPLE_FUN_CODE_OFFSET, we are * not in LANGUAGE_ASSEMBLY so we cant reach them. */ @@ -554,14 +716,7 @@ main(int argc, char *argv[], char *envp[]) FSHOW((stderr, "/funcalling initial_function=0x%lx\n", (unsigned long)initial_function)); -#ifdef LISP_FEATURE_WIN32 - fprintf(stderr, "\n\ -This is experimental prerelease support for the Windows platform: use\n\ -at your own risk. \"Your Kitten of Death awaits!\"\n"); - fflush(stdout); - fflush(stderr); -#endif create_initial_thread(initial_function); - lose("CATS. CATS ARE NICE.\n"); + lose("unexpected return from initial thread in main()\n"); return 0; }