From: Marion Guthmuller Date: Wed, 13 Mar 2013 16:04:20 +0000 (+0100) Subject: model-checker : new model-checker configuration model-check/dot_output=file_name... X-Git-Tag: v3_9_90~444 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/bdd25e7e320fa5d4f826cbb89bad6cfff45e0c21 model-checker : new model-checker configuration model-check/dot_output=file_name which generates a dot output of graph state explored during model checking --- diff --git a/src/include/mc/mc.h b/src/include/mc/mc.h index 8be2fd4e74..65c8212973 100644 --- a/src/include/mc/mc.h +++ b/src/include/mc/mc.h @@ -27,6 +27,7 @@ extern char* _sg_mc_property_file; extern int _sg_mc_timeout; extern int _sg_mc_max_depth; extern int _sg_mc_visited; +extern char* _sg_mc_dot_output_file; extern xbt_dynar_t mc_heap_comparison_ignore; extern xbt_dynar_t stacks_areas; @@ -40,6 +41,7 @@ void _mc_cfg_cb_property(const char *name, int pos); void _mc_cfg_cb_timeout(const char *name, int pos); void _mc_cfg_cb_max_depth(const char *name, int pos); void _mc_cfg_cb_visited(const char *name, int pos); +void _mc_cfg_cb_dot_output(const char *name, int pos); XBT_PUBLIC(void) MC_do_the_modelcheck_for_real(void); diff --git a/src/mc/mc_dpor.c b/src/mc/mc_dpor.c index aebfaa1d50..bab05aa5c4 100644 --- a/src/mc/mc_dpor.c +++ b/src/mc/mc_dpor.c @@ -249,6 +249,8 @@ void MC_dpor(void) XBT_DEBUG("Execute: %s", req_str); xbt_free(req_str); } + + req_str = MC_request_get_dot_output(req, value); MC_state_set_executed_request(state, req, value); mc_stats->executed_transitions++; @@ -310,11 +312,23 @@ void MC_dpor(void) next_state->system_state = MC_take_snapshot(); } + if(dot_output != NULL) + fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num, next_state->num, req_str); + + }else{ + + if(dot_output != NULL) + fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", state->num, visited_state, req_str); + } + + xbt_fifo_unshift(mc_stack_safety, next_state); MC_UNSET_RAW_MEM; + xbt_free(req_str); + /* Let's loop again */ /* The interleave set is empty or the maximum depth is reached, let's back-track */ diff --git a/src/mc/mc_global.c b/src/mc/mc_global.c index 672765afd7..b74447e645 100644 --- a/src/mc/mc_global.c +++ b/src/mc/mc_global.c @@ -30,6 +30,7 @@ char* _sg_mc_property_file=NULL; int _sg_mc_timeout=0; int _sg_mc_max_depth=1000; int _sg_mc_visited=0; +char *_sg_mc_dot_output_file = NULL; extern int _sg_init_status; void _mc_cfg_cb_reduce(const char *name, int pos) { @@ -80,6 +81,12 @@ void _mc_cfg_cb_visited(const char *name, int pos) { _sg_mc_visited= xbt_cfg_get_int(_sg_cfg_set, name); } +void _mc_cfg_cb_dot_output(const char *name, int pos) { + if (_sg_init_status && !_sg_do_model_check) { + xbt_die("You are specifying a file name for a dot output of graph state after the initialization (through MSG_config?), but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry."); + } + _sg_mc_dot_output_file= xbt_cfg_get_string(_sg_cfg_set, name); +} /* MC global data structures */ @@ -113,6 +120,9 @@ xbt_dynar_t mc_data_bss_comparison_ignore; extern xbt_dynar_t mc_heap_comparison_ignore; extern xbt_dynar_t stacks_areas; +FILE *dot_output = NULL; +const char* colors[10]; + xbt_automaton_t _mc_property_automaton = NULL; /* Static functions */ @@ -128,6 +138,9 @@ void MC_do_the_modelcheck_for_real() { MC_SET_RAW_MEM; mc_comp_times = xbt_new0(s_mc_comparison_times_t, 1); MC_UNSET_RAW_MEM; + + if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0')) + MC_init_dot_output(); if (!_sg_mc_property_file || _sg_mc_property_file[0]=='\0') { if (mc_reduce_kind==e_mc_reduce_unset) @@ -216,6 +229,28 @@ void MC_init(){ } +void MC_init_dot_output(){ + + colors[0] = "blue"; + colors[1] = "red"; + colors[2] = "green"; + colors[3] = "pink"; + colors[4] = "brown"; + colors[5] = "purple"; + colors[6] = "yellow"; + colors[7] = "orange"; + + dot_output = fopen(_sg_mc_dot_output_file, "w"); + + if(dot_output == NULL){ + perror("Error open dot output file"); + xbt_abort(); + } + + fprintf(dot_output, "digraph graphname{\n fixedsize=true; rankdir=TB; ranksep=.20; edge [fontsize=12]; node [fontsize=10, shape=circle,width=.5 ]; graph [resolution=20, fontsize=10];\n"); + +} + void MC_modelcheck_safety(void) { int raw_mem_set = (mmalloc_get_current_heap() == raw_heap); @@ -298,6 +333,13 @@ void MC_modelcheck_liveness(){ void MC_exit(void) { + MC_SET_RAW_MEM; + if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0')){ + fprintf(dot_output, "}\n"); + fclose(dot_output); + } + MC_UNSET_RAW_MEM; + xbt_free(mc_time); MC_memory_exit(); xbt_abort(); diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index 70b34dbd1f..b2f9a1b3eb 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -64,6 +64,8 @@ int is_stack_ignore_variable(char *frame, char *var_name); /********************************* MC Global **********************************/ extern double *mc_time; +extern FILE *dot_output; +extern const char* colors[10]; int MC_deadlock_check(void); void MC_replay(xbt_fifo_t stack, int start); @@ -73,6 +75,7 @@ void MC_show_deadlock(smx_simcall_t req); void MC_show_stack_safety(xbt_fifo_t stack); void MC_dump_stack_safety(xbt_fifo_t stack); void MC_init(void); +void MC_init_dot_output(void); int SIMIX_pre_mc_random(smx_simcall_t simcall); /********************************* Requests ***********************************/ @@ -84,6 +87,7 @@ int MC_request_is_visible(smx_simcall_t req); int MC_request_is_enabled(smx_simcall_t req); int MC_request_is_enabled_by_idx(smx_simcall_t req, unsigned int idx); int MC_process_is_enabled(smx_process_t process); +char *MC_request_get_dot_output(smx_simcall_t req, int value); /******************************** States **************************************/ @@ -112,6 +116,7 @@ typedef struct mc_state { int req_num; /* The request number (in the case of a multi-request like waitany ) */ mc_snapshot_t system_state; /* Snapshot of system state */ + int num; } s_mc_state_t, *mc_state_t; mc_state_t MC_state_new(void); diff --git a/src/mc/mc_request.c b/src/mc/mc_request.c index ea801b5974..2bf890d1b3 100644 --- a/src/mc/mc_request.c +++ b/src/mc/mc_request.c @@ -371,3 +371,57 @@ int MC_process_is_enabled(smx_process_t process) return FALSE; } + +char *MC_request_get_dot_output(smx_simcall_t req, int value){ + + char *str = NULL, *label = NULL; + smx_action_t act = NULL; + + switch(req->call){ + case SIMCALL_COMM_ISEND: + label = xbt_strdup("iSend"); + break; + + case SIMCALL_COMM_IRECV: + label = xbt_strdup("iRecv"); + break; + + case SIMCALL_COMM_WAIT: + if(value == -1) + label = xbt_strdup("WaitTimeout"); + else + label = xbt_strdup("Wait"); + break; + + case SIMCALL_COMM_TEST: + act = simcall_comm_test__get__comm(req); + if(act->comm.src_proc == NULL || act->comm.dst_proc == NULL) + label = xbt_strdup("Test FALSE"); + else + label = xbt_strdup("Test TRUE"); + break; + + case SIMCALL_MC_RANDOM: + if(value == 0) + label = xbt_strdup("MC_RANDOM (0)"); + else + label = xbt_strdup("MC_RANDOM (1)"); + break; + + case SIMCALL_MC_SNAPSHOT: + label = xbt_strdup("MC_SNAPSHOT"); + break; + + case SIMCALL_MC_COMPARE_SNAPSHOTS: + label = xbt_strdup("MC_COMPARE_SNAPSHOTS"); + break; + + default: + THROW_UNIMPLEMENTED; + } + + str = bprintf("label = \"%s\", color = %s", label, colors[req->issuer->pid-1]); + xbt_free(label); + return str; + +} diff --git a/src/mc/mc_state.c b/src/mc/mc_state.c index 29621f18fa..a78a72e8cf 100644 --- a/src/mc/mc_state.c +++ b/src/mc/mc_state.c @@ -18,8 +18,8 @@ mc_state_t MC_state_new() state->max_pid = simix_process_maxpid; state->proc_status = xbt_new0(s_mc_procstate_t, state->max_pid); state->system_state = NULL; - - mc_stats->expanded_states++; + state->num = ++mc_stats->expanded_states; + return state; } diff --git a/src/simgrid/sg_config.c b/src/simgrid/sg_config.c index b949dcf4b2..5f88dc9a5e 100644 --- a/src/simgrid/sg_config.c +++ b/src/simgrid/sg_config.c @@ -548,6 +548,13 @@ void sg_config_init(int *argc, char **argv) xbt_cfgelm_int, NULL, 0, 1, _mc_cfg_cb_visited, NULL); xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0); + + /* Set file name for dot output of graph state */ + xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output", + "Specify the name of dot file corresponding to graph state", + xbt_cfgelm_string, NULL, 0, 1, + _mc_cfg_cb_dot_output, NULL); + xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", ""); #endif /* do verbose-exit */