X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/12c0f182635ed71b370d608b5b9a614153765cd4..cd69f8c66886ae218c6a9b38125b27fe157e6bb2:/src/simix/smx_global.c diff --git a/src/simix/smx_global.c b/src/simix/smx_global.c index e171cd787f..b9dedde4c4 100644 --- a/src/simix/smx_global.c +++ b/src/simix/smx_global.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2007-2012. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2007-2014. The SimGrid Team. + * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -10,6 +11,15 @@ #include "xbt/str.h" #include "xbt/ex.h" /* ex_backtrace_display */ #include "mc/mc.h" +#include "simgrid/sg_config.h" + +#ifdef HAVE_MC +#include "mc/mc_private.h" +#endif + +#ifdef HAVE_SMPI +#include "smpi/private.h" +#endif XBT_LOG_NEW_CATEGORY(simix, "All SIMIX categories"); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_kernel, simix, @@ -22,8 +32,6 @@ static void* SIMIX_action_mallocator_new_f(void); static void SIMIX_action_mallocator_free_f(void* action); static void SIMIX_action_mallocator_reset_f(void* action); -static void SIMIX_clean(void); - /* FIXME: Yeah, I'll do it in a portable maner one day [Mt] */ #include @@ -31,15 +39,96 @@ int _sg_do_verbose_exit = 1; static void _XBT_CALL inthandler(int ignored) { if ( _sg_do_verbose_exit ) { - XBT_INFO("CTRL-C pressed. Displaying status and bailing out"); + XBT_INFO("CTRL-C pressed. The current status will be displayed before exit (disable that behavior with option 'verbose-exit')."); SIMIX_display_process_status(); } else { - XBT_INFO("CTRL-C pressed. bailing out without displaying because verbose-exit is disabled"); + XBT_INFO("CTRL-C pressed, exiting. Hiding the current process status since 'verbose-exit' is set to false."); } exit(1); } +#ifndef WIN32 +static void _XBT_CALL segvhandler(int signum, siginfo_t *siginfo, void *context) +{ + if (siginfo->si_signo == SIGSEGV && siginfo->si_code == SEGV_ACCERR) { + fprintf(stderr, + "Access violation detected.\n" + "This can result from a programming error in your code or, although less likely,\n" + "from a bug in SimGrid itself. This can also be the sign of a bug in the OS or\n" + "in third-party libraries. Failing hardware can sometimes generate such errors\n" + "too.\n" + "Finally, if nothing of the above applies, this can result from a stack overflow.\n" + "Try to increase stack size with --cfg=contexts/stack_size (current size is %d KiB).\n", + smx_context_stack_size / 1024); + if (XBT_LOG_ISENABLED(simix_kernel, xbt_log_priority_debug)) { + fprintf(stderr, + "siginfo = {si_signo = %d, si_errno = %d, si_code = %d, si_addr = %p}\n", + siginfo->si_signo, siginfo->si_errno, siginfo->si_code, siginfo->si_addr); + } + } else if (siginfo->si_signo == SIGSEGV) { + fprintf(stderr, "Segmentation fault.\n"); +#ifdef HAVE_SMPI + if (smpi_enabled() && !smpi_privatize_global_variables) { + fprintf(stderr, + "Try to enable SMPI variable privatization with --cfg=smpi/privatize_global_variables:yes.\n"); + } +#endif + } +#ifdef HAVE_MC + if (MC_is_active()) { + if (mc_stack) { + MC_dump_stack_safety(mc_stack); + } + MC_print_statistics(mc_stats); + } +#endif + raise(signum); +} + +char sigsegv_stack[SIGSTKSZ]; /* alternate stack for SIGSEGV handler */ + +/** + * Install signal handler for SIGSEGV. Check that nobody has already installed + * its own handler. For example, the Java VM does this. + */ +static void install_segvhandler(void) +{ + stack_t stack, old_stack; + stack.ss_sp = sigsegv_stack; + stack.ss_size = sizeof sigsegv_stack; + stack.ss_flags = 0; + + if (sigaltstack(&stack, &old_stack) == -1) { + XBT_WARN("Failed to register alternate signal stack: %s", + strerror(errno)); + return; + } + if (!(old_stack.ss_flags & SS_DISABLE)) { + XBT_DEBUG("An alternate stack was already installed (sp=%p, size=%zd, flags=%x). Restore it.", + old_stack.ss_sp, old_stack.ss_size, old_stack.ss_flags); + sigaltstack(&old_stack, NULL); + } + + struct sigaction action, old_action; + action.sa_sigaction = segvhandler; + action.sa_flags = SA_ONSTACK | SA_RESETHAND | SA_SIGINFO; + sigemptyset(&action.sa_mask); + + if (sigaction(SIGSEGV, &action, &old_action) == -1) { + XBT_WARN("Failed to register signal handler for SIGSEGV: %s", + strerror(errno)); + return; + } + if ((old_action.sa_flags & SA_SIGINFO) || old_action.sa_handler != SIG_DFL) { + XBT_DEBUG("A signal handler was already installed for SIGSEGV (%p). Restore it.", + (old_action.sa_flags & SA_SIGINFO) ? + (void*)old_action.sa_sigaction : (void*)old_action.sa_handler); + sigaction(SIGSEGV, &old_action, NULL); + } +} + +#endif /********************************* SIMIX **************************************/ XBT_INLINE double SIMIX_timer_next(void) @@ -97,6 +186,10 @@ void SIMIX_global_init(int *argc, char **argv) /* Prepare to display some more info when dying on Ctrl-C pressing */ signal(SIGINT, inthandler); +#ifndef WIN32 + /* Install SEGV handler */ + install_segvhandler(); +#endif /* register a function to be called by SURF after the environment creation */ sg_platf_init(); sg_platf_postparse_add_cb(SIMIX_post_create_environment); @@ -107,8 +200,13 @@ void SIMIX_global_init(int *argc, char **argv) } SIMIX_HOST_LEVEL = xbt_lib_add_level(host_lib,SIMIX_host_destroy); + SIMIX_STORAGE_LEVEL = xbt_lib_add_level(storage_lib, SIMIX_storage_destroy); - atexit(SIMIX_clean); + if (sg_cfg_get_boolean("clean_atexit")) + atexit(SIMIX_clean); + + if (_sg_cfg_exit_asap) + exit(0); } /** @@ -117,12 +215,14 @@ void SIMIX_global_init(int *argc, char **argv) * * This functions remove the memory used by SIMIX */ -static void SIMIX_clean(void) +void SIMIX_clean(void) { + static int cleaned = 0; #ifdef TIME_BENCH_PER_SR smx_ctx_raw_new_sr(); #endif - + if (cleaned) return; // to avoid double cleaning by java and C + cleaned = 1; /* Kill everyone (except maestro) */ SIMIX_process_killall(simix_global->maestro_process, 1); @@ -157,7 +257,7 @@ static void SIMIX_clean(void) #ifdef TIME_BENCH_AMDAHL xbt_os_cputimer_stop(simix_global->timer_seq); - XBT_INFO("Amdhal timing informations. Sequential time: %lf; Parallel time: %lf", + XBT_INFO("Amdahl timing informations. Sequential time: %f; Parallel time: %f", xbt_os_timer_elapsed(simix_global->timer_seq), xbt_os_timer_elapsed(simix_global->timer_par)); xbt_os_timer_free(simix_global->timer_seq); @@ -208,7 +308,6 @@ void SIMIX_run(void) { double time = 0; smx_process_t process; - xbt_swag_t set; surf_action_t action; smx_timer_t timer; surf_model_t model; @@ -295,7 +394,7 @@ void SIMIX_run(void) xbt_dynar_foreach(simix_global->process_that_ran, iter, process) { if (process->simcall.call != SIMCALL_NONE) { - SIMIX_simcall_pre(&process->simcall, 0); + SIMIX_simcall_enter(&process->simcall, 0); } } } @@ -311,25 +410,33 @@ void SIMIX_run(void) /* Handle any pending timer */ while (xbt_heap_size(simix_timers) > 0 && SIMIX_get_clock() >= SIMIX_timer_next()) { //FIXME: make the timers being real callbacks - // (i.e. provide dispatchers that read and expand the args) + // (i.e. provide dispatchers that read and expand the args) timer = xbt_heap_pop(simix_timers); if (timer->func) ((void (*)(void*))timer->func)(timer->args); xbt_free(timer); } + /* Wake up all processes waiting for a Surf action to finish */ xbt_dynar_foreach(model_list, iter, model) { - set = model->states.failed_action_set; - while ((action = xbt_swag_extract(set))) - SIMIX_simcall_post((smx_action_t) action->data); - set = model->states.done_action_set; + while ((action = surf_model_extract_failed_action_set(model))) + SIMIX_simcall_exit((smx_action_t) surf_action_get_data(action)); - while ((action = xbt_swag_extract(set))) { - if (action->data == NULL) + while ((action = surf_model_extract_done_action_set(model))) + if (surf_action_get_data(action) == NULL) XBT_DEBUG("probably vcpu's action %p, skip", action); else - SIMIX_simcall_post((smx_action_t) action->data); + SIMIX_simcall_exit((smx_action_t) surf_action_get_data(action)); + } + + /* Autorestart all process */ + if(host_that_restart) { + char *hostname = NULL; + xbt_dynar_foreach(host_that_restart,iter,hostname) { + XBT_INFO("Restart processes on host: %s",hostname); + SIMIX_host_autorestart(SIMIX_host_get_by_name(hostname)); } + xbt_dynar_reset(host_that_restart); } /* Clean processes to destroy */ @@ -337,8 +444,6 @@ void SIMIX_run(void) XBT_DEBUG("### time %f, empty %d", time, xbt_dynar_is_empty(simix_global->process_to_run)); - // !(time == -1.0 && xbt_dynar_is_empty()) - } while (time != -1.0 || !xbt_dynar_is_empty(simix_global->process_to_run)); @@ -348,7 +453,7 @@ void SIMIX_run(void) TRACE_end(); #endif - XBT_WARN("Oops ! Deadlock or code not perfectly clean."); + XBT_CRITICAL("Oops ! Deadlock or code not perfectly clean."); SIMIX_display_process_status(); xbt_abort(); } @@ -452,19 +557,16 @@ void SIMIX_display_process_status(void) action_description = "sleeping"; break; + case SIMIX_ACTION_JOIN: + action_description = "joining"; + break; + case SIMIX_ACTION_SYNCHRO: action_description = "synchronization"; break; case SIMIX_ACTION_IO: action_description = "I/O"; - break; - /* **************************************/ - /* TUTORIAL: New API */ - case SIMIX_ACTION_NEW_API: - action_description = "NEW API"; - /* **************************************/ - break; } XBT_INFO("Process %lu (%s@%s): waiting for %s action %p (%s) in state %d to finish",