+ if(strncmp(node_type, "DW_AT_", 6) != 0){
+ member_end = 1;
+ break;
+ }
+
+ if(strcmp(node_type, "DW_AT_byte_size") == 0){
+ size = strtol(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL, 10);
+ }else if(strcmp(node_type, "DW_AT_name") == 0){
+ xbt_free(end);
+ end = xbt_str_join(split, " ");
+ xbt_dynar_free(&split);
+ split = xbt_str_split(end, "):");
+ xbt_str_ltrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL);
+ name = xbt_strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*));
+ }else if(strcmp(node_type, "DW_AT_type") == 0){
+ type_origin = xbt_strdup(xbt_dynar_get_as(split, 3, char *));
+ xbt_str_ltrim(type_origin, "<0x");
+ xbt_str_rtrim(type_origin, ">");
+ }else if(strcmp(node_type, "DW_AT_data_member_location:") == 0){
+ xbt_free(end);
+ end = xbt_str_join(split, " ");
+ xbt_dynar_free(&split);
+ split = xbt_str_split(end, "DW_OP_plus_uconst:");
+ xbt_str_ltrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), NULL);
+ xbt_str_rtrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), ")");
+ offset = strtol(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL, 10);
+ }
+
+ read = xbt_getline(&line, &n, fp);
+
+ }
+
+ if(member_end && type){
+ member_end = 0;
+
+ // Why are we not simply referencing, the DW_AT_type?
+ dw_type_t member_type = xbt_new0(s_dw_type_t, 1);
+ member_type->name = xbt_strdup(name);
+ member_type->byte_size = size;
+ member_type->element_count = -1;
+ member_type->is_pointer_type = is_pointer;
+ member_type->id = (void *)strtoul(origin, NULL, 16);
+ member_type->offset = offset;
+ if(type_origin)
+ member_type->dw_type_id = xbt_strdup(type_origin);
+
+ xbt_dynar_push(type->members, &member_type);
+
+ xbt_free(name);
+ name = NULL;
+ xbt_free(end);
+ end = NULL;
+ xbt_free(type_origin);
+ type_origin = NULL;
+ size = 0;
+ offset = 0;
+
+ xbt_free(origin);
+ origin = NULL;
+ strtok(xbt_dynar_get_as(split, 0, char *), "<");
+ origin = strdup(strtok(NULL, "<"));
+ xbt_str_rtrim(origin, ">:");
+
+ }
+
+ if(struct_decl || union_decl){
+ type = xbt_new0(s_dw_type_t, 1);
+ if(struct_decl)
+ type->type = DW_TAG_structure_type;
+ else
+ type->type = DW_TAG_union_type;
+ type->name = xbt_strdup(name);
+ type->byte_size = size;
+ type->element_count = -1;
+ type->is_pointer_type = is_pointer;
+ type->id = (void *)strtoul(origin, NULL, 16);
+ if(type_origin)
+ type->dw_type_id = xbt_strdup(type_origin);
+ type->members = xbt_dynar_new(sizeof(dw_type_t), dw_type_free_voidp);
+
+ xbt_dict_set(*types, origin, type, NULL);
+
+ xbt_free(name);
+ name = NULL;
+ xbt_free(end);
+ end = NULL;
+ xbt_free(type_origin);
+ type_origin = NULL;
+ size = 0;
+ struct_decl = 0;
+ union_decl = 0;
+
+ }
+
+ if(strcmp(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), "(DW_TAG_member)") != 0)
+ break;
+
+ read = xbt_getline(&line, &n, fp);
+
+ }
+
+ xbt_free(origin);
+ origin = NULL;
+
+ }else if(strcmp(node_type, "(DW_TAG_array_type)") == 0){
+
+ strtok(xbt_dynar_get_as(split, 0, char *), "<");
+ origin = strdup(strtok(NULL, "<"));
+ xbt_str_rtrim(origin, ">:");
+
+ read = xbt_getline(&line, &n, fp);
+
+ dw_type_t type = NULL;
+
+ // Read DW_TAG_subrange_type children:
+ while(read != -1){
+
+ // Read attributes of the DW_TAG_subrange_type:
+ while(read != -1){
+
+ /* Wipeout the new line character */
+ line[read - 1] = '\0';
+
+ if(n == 0 || strlen(line) == 0){
+ read = xbt_getline(&line, &n, fp);
+ continue;
+ }
+
+ xbt_dynar_free(&split);
+ xbt_str_rtrim(line, NULL);
+ xbt_str_strip_spaces(line);
+ split = xbt_str_split(line, " ");
+
+ node_type = xbt_dynar_get_as(split, 1, char *);
+
+ if(strncmp(node_type, "DW_AT_", 6) != 0)
+ break;
+
+ if(strcmp(node_type, "DW_AT_upper_bound") == 0){
+ size = strtol(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL, 10);
+ }else if(strcmp(node_type, "DW_AT_name") == 0){
+ end = xbt_str_join(split, " ");
+ xbt_dynar_free(&split);
+ split = xbt_str_split(end, "):");
+ xbt_str_ltrim(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*), NULL);
+ name = xbt_strdup(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char*));
+ }else if(strcmp(node_type, "DW_AT_type") == 0){
+ type_origin = xbt_strdup(xbt_dynar_get_as(split, 3, char *));
+ xbt_str_ltrim(type_origin, "<0x");
+ xbt_str_rtrim(type_origin, ">");
+ }
+
+ read = xbt_getline(&line, &n, fp);
+
+ }
+
+ if(strcmp(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), "(DW_TAG_subrange_type)") == 0){
+ subrange = 1;
+ }
+
+ if(subrange && type){
+ type->element_count = size;
+
+ xbt_free(name);
+ name = NULL;
+ xbt_free(end);
+ end = NULL;
+ xbt_free(type_origin);
+ type_origin = NULL;
+ size = 0;
+
+ xbt_free(origin);
+ origin = NULL;
+ strtok(xbt_dynar_get_as(split, 0, char *), "<");
+ origin = strdup(strtok(NULL, "<"));
+ xbt_str_rtrim(origin, ">:");
+
+ }else {
+
+ type = xbt_new0(s_dw_type_t, 1);
+ type->type = DW_TAG_array_type;
+ type->name = xbt_strdup(name);
+ type->is_pointer_type = is_pointer;
+ type->id = (void *)strtoul(origin, NULL, 16);
+ if(type_origin)
+ type->dw_type_id = xbt_strdup(type_origin);
+ type->members = NULL;
+
+ // Filled in a post processing step:
+ type-> byte_size = 0;
+
+ xbt_dict_set(*types, origin, type, NULL);
+
+ xbt_free(name);
+ name = NULL;
+ xbt_free(end);
+ end = NULL;
+ xbt_free(type_origin);
+ type_origin = NULL;
+ size = 0;
+ }
+
+ if(strcmp(xbt_dynar_get_as(split, xbt_dynar_length(split) - 1, char *), "(DW_TAG_subrange_type)") != 0)
+ break;
+
+ read = xbt_getline(&line, &n, fp);
+
+ }
+
+ xbt_free(origin);
+ origin = NULL;
+
+ }else{
+
+ read = xbt_getline(&line, &n, fp);
+
+ }
+
+ }
+
+ xbt_dynar_free(&split);
+ xbt_dict_free(&variables_origin);
+ xbt_dict_free(&subprograms_origin);
+ xbt_free(line);
+ xbt_free(command);
+ xbt_dict_free(&location_list);
+
+ pclose(fp);
+
+ MC_post_process_types(info);
+}
+
+static void MC_post_process_array_size(mc_object_info_t info, dw_type_t type) {
+ xbt_assert(type->dw_type_id, "No base type for array <%p>%s", type->id, type->name);
+ dw_type_t subtype = xbt_dict_get_or_null(info->types, type->dw_type_id);
+ xbt_assert(subtype, "Unkown base type <%s> for array <%p>%s", type->dw_type_id, type->id, type->name);
+ if(subtype->type==DW_TAG_array_type && type->byte_size==0) {
+ MC_post_process_array_size(info, subtype);
+ }
+ type->byte_size = type->element_count*subtype->byte_size;
+}
+
+static void MC_post_process_types(mc_object_info_t info) {
+ xbt_dict_cursor_t cursor;
+ char *origin;
+ dw_type_t type;
+ xbt_dict_foreach(info->types, cursor, origin, type){
+ if(type->type==DW_TAG_array_type && type->byte_size==0)
+ MC_post_process_array_size(info, type);
+ }
+}
+
+/******************************* Ignore mechanism *******************************/
+/*********************************************************************************/
+
+xbt_dynar_t mc_checkpoint_ignore;
+
+typedef struct s_mc_stack_ignore_variable{
+ char *var_name;
+ char *frame;
+}s_mc_stack_ignore_variable_t, *mc_stack_ignore_variable_t;
+
+typedef struct s_mc_data_bss_ignore_variable{
+ char *name;
+}s_mc_data_bss_ignore_variable_t, *mc_data_bss_ignore_variable_t;
+
+/**************************** Free functions ******************************/
+
+static void stack_ignore_variable_free(mc_stack_ignore_variable_t v){
+ xbt_free(v->var_name);
+ xbt_free(v->frame);
+ xbt_free(v);
+}
+
+static void stack_ignore_variable_free_voidp(void *v){
+ stack_ignore_variable_free((mc_stack_ignore_variable_t) * (void **) v);
+}
+
+void heap_ignore_region_free(mc_heap_ignore_region_t r){
+ xbt_free(r);
+}
+
+void heap_ignore_region_free_voidp(void *r){
+ heap_ignore_region_free((mc_heap_ignore_region_t) * (void **) r);
+}
+
+static void data_bss_ignore_variable_free(mc_data_bss_ignore_variable_t v){
+ xbt_free(v->name);
+ xbt_free(v);
+}
+
+static void data_bss_ignore_variable_free_voidp(void *v){
+ data_bss_ignore_variable_free((mc_data_bss_ignore_variable_t) * (void **) v);
+}
+
+static void checkpoint_ignore_region_free(mc_checkpoint_ignore_region_t r){
+ xbt_free(r);
+}
+
+static void checkpoint_ignore_region_free_voidp(void *r){
+ checkpoint_ignore_region_free((mc_checkpoint_ignore_region_t) * (void **) r);
+}
+
+/***********************************************************************/
+
+void MC_ignore_heap(void *address, size_t size){
+
+ int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+
+ MC_SET_RAW_MEM;
+
+ mc_heap_ignore_region_t region = NULL;
+ region = xbt_new0(s_mc_heap_ignore_region_t, 1);
+ region->address = address;
+ region->size = size;
+
+ region->block = ((char*)address - (char*)((xbt_mheap_t)std_heap)->heapbase) / BLOCKSIZE + 1;
+
+ if(((xbt_mheap_t)std_heap)->heapinfo[region->block].type == 0){
+ region->fragment = -1;
+ ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_block.ignore++;
+ }else{
+ region->fragment = ((uintptr_t) (ADDR2UINT (address) % (BLOCKSIZE))) >> ((xbt_mheap_t)std_heap)->heapinfo[region->block].type;
+ ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_frag.ignore[region->fragment]++;
+ }
+
+ if(mc_heap_comparison_ignore == NULL){
+ mc_heap_comparison_ignore = xbt_dynar_new(sizeof(mc_heap_ignore_region_t), heap_ignore_region_free_voidp);
+ xbt_dynar_push(mc_heap_comparison_ignore, ®ion);
+ if(!raw_mem_set)
+ MC_UNSET_RAW_MEM;
+ return;
+ }
+
+ unsigned int cursor = 0;
+ mc_heap_ignore_region_t current_region = NULL;
+ int start = 0;
+ int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
+
+ while(start <= end){
+ cursor = (start + end) / 2;
+ current_region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
+ if(current_region->address == address){