int _sg_mc_checkpoint=0;
char* _sg_mc_property_file=NULL;
int _sg_mc_timeout=0;
+int _sg_mc_hash=0;
int _sg_mc_max_depth=1000;
int _sg_mc_visited=0;
char *_sg_mc_dot_output_file = NULL;
+int _sg_mc_comms_determinism=0;
int user_max_depth_reached = 0;
_sg_mc_timeout= xbt_cfg_get_boolean(_sg_cfg_set, name);
}
+void _mc_cfg_cb_hash(const char *name, int pos) {
+ if (_sg_cfg_init_status && !_sg_do_model_check) {
+ xbt_die("You are specifying a value to enable/disable the use of global hash to speedup state comparaison, but model-checking was not activated at config time (through --cfg=model-check:1). This won't work, sorry.");
+ }
+ _sg_mc_hash= xbt_cfg_get_boolean(_sg_cfg_set, name);
+}
+
void _mc_cfg_cb_max_depth(const char *name, int pos) {
if (_sg_cfg_init_status && !_sg_do_model_check) {
xbt_die("You are specifying a max depth value 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);
}
+void _mc_cfg_cb_comms_determinism(const char *name, int pos) {
+ if (_sg_cfg_init_status && !_sg_do_model_check) {
+ xbt_die("You are specifying a value to enable/disable the detection of determinism in the communications schemes 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_comms_determinism= xbt_cfg_get_boolean(_sg_cfg_set, name);
+}
+
/* MC global data structures */
mc_state_t mc_current_state = NULL;
char mc_replay_mode = FALSE;
xbt_free(v->name);
xbt_free(v->type_origin);
if(!v->global)
- dw_location_free(v->address.location);
+ dw_location_free(v->location);
xbt_free(v);
}
}
dw_variable_free((dw_variable_t) * (void **) t);
}
-// object_info
+// ***** object_info
mc_object_info_t MC_new_object_info(void) {
mc_object_info_t res = xbt_new0(s_mc_object_info_t, 1);
return res;
}
+
void MC_free_object_info(mc_object_info_t* info) {
xbt_free(&(*info)->file_name);
xbt_dict_free(&(*info)->local_variables);
xbt_dict_free(&(*info)->types);
xbt_dict_free(&(*info)->types_by_name);
xbt_free(info);
+ xbt_dynar_free(&(*info)->functions_index);
*info = NULL;
}
+// ***** Helpers
+
+void* MC_object_base_address(mc_object_info_t info) {
+ void* result = info->start_exec;
+ if(info->start_rw!=NULL && result > (void*) info->start_rw) result = info->start_rw;
+ if(info->start_ro!=NULL && result > (void*) info->start_ro) result = info->start_ro;
+ return result;
+}
+
+// ***** Functions index
+
+static int MC_compare_frame_index_items(mc_function_index_item_t a, mc_function_index_item_t b) {
+ if(a->low_pc < b->low_pc)
+ return -1;
+ else if(a->low_pc == b->low_pc)
+ return 0;
+ else
+ return 1;
+}
+
+static void MC_make_functions_index(mc_object_info_t info) {
+ xbt_dynar_t index = xbt_dynar_new(sizeof(s_mc_function_index_item_t), NULL);
+
+ // Populate the array:
+ dw_frame_t frame = NULL;
+ xbt_dict_cursor_t cursor = NULL;
+ const char* name = NULL;
+ xbt_dict_foreach(info->local_variables, cursor, name, frame) {
+ if(frame->low_pc==NULL)
+ continue;
+ s_mc_function_index_item_t entry;
+ entry.low_pc = frame->low_pc;
+ entry.high_pc = frame->high_pc;
+ entry.function = frame;
+ xbt_dynar_push(index, &entry);
+ }
+
+ mc_function_index_item_t base = (mc_function_index_item_t) xbt_dynar_get_ptr(index, 0);
+
+ // Sort the array by low_pc:
+ qsort(base,
+ xbt_dynar_length(index),
+ sizeof(s_mc_function_index_item_t),
+ (int (*)(const void *, const void *))MC_compare_frame_index_items);
+
+ info->functions_index = index;
+}
+
+mc_object_info_t MC_ip_find_object_info(void* ip) {
+ mc_object_info_t infos[2] = { mc_binary_info, mc_libsimgrid_info };
+ size_t n = 2;
+ size_t i;
+ for(i=0; i!=n; ++i) {
+ if(ip >= (void*)infos[i]->start_exec && ip <= (void*)infos[i]->end_exec) {
+ return infos[i];
+ }
+ }
+ return NULL;
+}
+
+static dw_frame_t MC_find_function_by_ip_and_object(void* ip, mc_object_info_t info) {
+ xbt_dynar_t dynar = info->functions_index;
+ mc_function_index_item_t base = (mc_function_index_item_t) xbt_dynar_get_ptr(dynar, 0);
+ int i = 0;
+ int j = xbt_dynar_length(dynar) - 1;
+ while(j>=i) {
+ int k = i + ((j-i)/2);
+ if(ip < base[k].low_pc) {
+ j = k-1;
+ } else if(ip > base[k].high_pc) {
+ i = k+1;
+ } else {
+ return base[k].function;
+ }
+ }
+ return NULL;
+}
+
+dw_frame_t MC_find_function_by_ip(void* ip) {
+ mc_object_info_t info = MC_ip_find_object_info(ip);
+ if(info==NULL)
+ return NULL;
+ else
+ return MC_find_function_by_ip_and_object(ip, info);
+}
+
+static void MC_post_process_variables(mc_object_info_t info) {
+ unsigned cursor = 0;
+ dw_variable_t variable = NULL;
+ xbt_dynar_foreach(info->global_variables, cursor, variable) {
+ if(variable->type_origin) {
+ variable->type = xbt_dict_get_or_null(info->types, variable->type_origin);
+ }
+ }
+}
+
+static void MC_post_process_functions(mc_object_info_t info) {
+ xbt_dict_cursor_t cursor = NULL;
+ char* key = NULL;
+ dw_frame_t function = NULL;
+ xbt_dict_foreach(info->local_variables, cursor, key, function) {
+ unsigned cursor2 = 0;
+ dw_variable_t variable = NULL;
+ xbt_dynar_foreach(function->variables, cursor2, variable) {
+ if(variable->type_origin) {
+ variable->type = xbt_dict_get_or_null(info->types, variable->type_origin);
+ }
+ }
+ }
+}
+
+/** \brief Finds informations about a given shared object/executable */
+mc_object_info_t MC_find_object_info(memory_map_t maps, char* name, int executable) {
+ mc_object_info_t result = MC_new_object_info();
+ if(executable)
+ result->flags |= MC_OBJECT_INFO_EXECUTABLE;
+ result->file_name = xbt_strdup(name);
+ MC_find_object_address(maps, result);
+ MC_dwarf_get_variables(result);
+ MC_post_process_types(result);
+ MC_post_process_variables(result);
+ MC_post_process_functions(result);
+ MC_make_functions_index(result);
+ return result;
+}
+
/*************************************************************************/
static dw_location_t MC_dwarf_get_location(xbt_dict_t location_list, char *expr){
end = cursor - 1;
}else{
if(address){ /* global variable */
- if(var_test->address.address == address)
+ if(var_test->address == address)
return -1;
- if(var_test->address.address > address)
+ if(var_test->address > address)
end = cursor - 1;
else
start = cursor + 1;
}
if(strcmp(var_test->name, var) == 0){
- if(address && var_test->address.address < address)
+ if(address && var_test->address < address)
return cursor+1;
else
return cursor;
}
void MC_dwarf_register_global_variable(mc_object_info_t info, dw_variable_t variable) {
- int index = MC_dwarf_get_variable_index(info->global_variables, variable->name, variable->address.address);
+ int index = MC_dwarf_get_variable_index(info->global_variables, variable->name, variable->address);
if (index != -1)
xbt_dynar_insert_at(info->global_variables, index, &variable);
// TODO, else ?
/******************************* Initialisation of MC *******************************/
/*********************************************************************************/
-static void MC_init_debug_info();
-static void MC_init_debug_info() {
+static void MC_post_process_object_info(mc_object_info_t info) {
+ mc_object_info_t other_info = info == mc_binary_info ? mc_libsimgrid_info : mc_binary_info;
+ xbt_dict_cursor_t cursor = NULL;
+ char* key = NULL;
+ dw_type_t type = NULL;
+ xbt_dict_foreach(info->types, cursor, key, type){
+ if(type->name && type->byte_size == 0) {
+ type->other_object_same_type = xbt_dict_get_or_null(other_info->types_by_name, type->name);
+ }
+ }
+}
+
+static void MC_init_debug_info(void) {
XBT_INFO("Get debug information ...");
memory_map_t maps = MC_get_memory_map();
/* Get local variables for state equality detection */
- mc_binary_info = MC_find_object_info(maps, xbt_binary_name);
- mc_libsimgrid_info = MC_find_object_info(maps, libsimgrid_path);
+ mc_binary_info = MC_find_object_info(maps, xbt_binary_name, 1);
+ mc_libsimgrid_info = MC_find_object_info(maps, libsimgrid_path, 0);
+
+ // Use information of the other objects:
+ MC_post_process_object_info(mc_binary_info);
+ MC_post_process_object_info(mc_libsimgrid_info);
MC_free_memory_map(maps);
XBT_INFO("Get debug information done !");
xbt_free(key);
}
}
- xbt_dynar_reset(communications_pattern);
+ if(_sg_mc_comms_determinism)
+ xbt_dynar_reset(communications_pattern);
MC_UNSET_RAW_MEM;
}
}
- if(req->call == SIMCALL_COMM_ISEND)
- comm_pattern = 1;
- else if(req->call == SIMCALL_COMM_IRECV)
+ if(_sg_mc_comms_determinism){
+ if(req->call == SIMCALL_COMM_ISEND)
+ comm_pattern = 1;
+ else if(req->call == SIMCALL_COMM_IRECV)
comm_pattern = 2;
-
+ }
+
SIMIX_simcall_pre(req, value);
- MC_SET_RAW_MEM;
- if(comm_pattern != 0){
- get_comm_pattern(communications_pattern, req, comm_pattern);
+ if(_sg_mc_comms_determinism){
+ MC_SET_RAW_MEM;
+ if(comm_pattern != 0){
+ get_comm_pattern(communications_pattern, req, comm_pattern);
+ }
+ MC_UNSET_RAW_MEM;
+ comm_pattern = 0;
}
- MC_UNSET_RAW_MEM;
-
- comm_pattern = 0;
MC_wait_for_requests();
fprintf(dot_output, "}\n");
fclose(dot_output);
}
- if(initial_state_safety != NULL){
- // XBT_INFO("Communication-deterministic : %s", !initial_state_safety->comm_deterministic ? "No" : "Yes");
- // XBT_INFO("Send-deterministic : %s", !initial_state_safety->send_deterministic ? "No" : "Yes");
+ if(initial_state_safety != NULL && _sg_mc_comms_determinism){
+ XBT_INFO("Communication-deterministic : %s", !initial_state_safety->comm_deterministic ? "No" : "Yes");
+ XBT_INFO("Send-deterministic : %s", !initial_state_safety->send_deterministic ? "No" : "Yes");
}
MC_UNSET_RAW_MEM;
}