X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/d740fcc38174fbe1e9c5ec70ac3a15999fd62ac2..c41d2ffc9d4d4b5e15f98d5b4febc20ab9810aed:/src/simix/smx_global.c diff --git a/src/simix/smx_global.c b/src/simix/smx_global.c index d91c628130..2ce8738ec1 100644 --- a/src/simix/smx_global.c +++ b/src/simix/smx_global.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2013. The SimGrid Team. +/* Copyright (c) 2007-2014. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -13,6 +13,14 @@ #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, "Logging specific to SIMIX (kernel)"); @@ -24,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 @@ -33,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) @@ -99,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); @@ -109,6 +200,7 @@ 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); if (sg_cfg_get_boolean("clean_atexit")) atexit(SIMIX_clean); @@ -123,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); @@ -163,7 +257,7 @@ static void SIMIX_clean(void) #ifdef TIME_BENCH_AMDAHL xbt_os_cputimer_stop(simix_global->timer_seq); - XBT_INFO("Amdahl 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); @@ -214,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; @@ -301,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); } } } @@ -317,20 +410,23 @@ 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 = xbt_swag_extract(set))) - SIMIX_simcall_post((smx_action_t) action->data); + while ((action = surf_model_extract_failed_action_set(model))) + SIMIX_simcall_exit((smx_action_t) surf_action_get_data(action)); + + 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_exit((smx_action_t) surf_action_get_data(action)); } /* Autorestart all process */ @@ -346,6 +442,9 @@ void SIMIX_run(void) /* Clean processes to destroy */ SIMIX_process_empty_trash(); + + XBT_DEBUG("### time %f, empty %d", time, xbt_dynar_is_empty(simix_global->process_to_run)); + } while (time != -1.0 || !xbt_dynar_is_empty(simix_global->process_to_run)); if (xbt_swag_size(simix_global->process_list) != 0) { @@ -458,6 +557,10 @@ 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;