void mmalloc_set_current_heap(xbt_mheap_t new_heap);
xbt_mheap_t mmalloc_get_current_heap(void);
-int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t *stacks1, xbt_dynar_t *stacks2, xbt_dynar_t *equals);
+int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t *stacks1, xbt_dynar_t *stacks2, xbt_dynar_t equals);
int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2);
void init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2);
-void match_equals(xbt_dynar_t list, xbt_dynar_t *equals);
-int compare_area(void *area1, void* area2, xbt_dynar_t previous);
+void match_equals(xbt_dynar_t list, xbt_dynar_t equals);
+int compare_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dynar_t equals);
void mmalloc_backtrace_block_display(void* heapinfo, int block);
void mmalloc_backtrace_fragment_display(void* heapinfo, int block, int frag);
/****************************** MC ignore **********************************/
XBT_PUBLIC(void) MC_ignore_heap(void *address, size_t size);
+XBT_PUBLIC(void) MC_remove_ignore_heap(void *address, size_t size);
XBT_PUBLIC(void) MC_ignore_stack(const char *var_name, const char *frame);
XBT_PUBLIC(void) MC_ignore_data_bss(void *address, size_t size);
void MC_new_stack_area(void *stack, char *name, void *context, size_t size);
return 0;
}
-static int compare_global_variables(int region_type, void *d1, void *d2){
+static int compare_global_variables(int region_type, void *d1, void *d2, xbt_dynar_t equals){
unsigned int cursor = 0;
size_t offset;
global_variable_t current_var;
int pointer_align;
void *addr_pointed1 = NULL, *addr_pointed2 = NULL;
+ int res_compare = 0;
if(region_type == 1){ /* libsimgrid */
xbt_dynar_foreach(mc_global_variables, cursor, current_var){
i = current_var->size;
continue;
}else{
- if(XBT_LOG_ISENABLED(mc_compare, xbt_log_priority_verbose)){
- XBT_VERB("Different global variable in libsimgrid : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+ if((addr_pointed1 > std_heap) && ((char *)addr_pointed1 < (char *)std_heap + STD_HEAP_SIZE) && (addr_pointed2 > std_heap) && ((char *)addr_pointed2 < (char *)std_heap + STD_HEAP_SIZE)){
+ res_compare = compare_area(addr_pointed1, addr_pointed2, NULL, equals);
+ if(res_compare == 1){
+ #ifdef MC_VERBOSE
+ XBT_VERB("Different global variable in libsimgrid : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+ #endif
+ return 1;
+ }
+ }else{
+ #ifdef MC_VERBOSE
+ XBT_VERB("Different global variable in libsimgrid : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+ #endif
+ return 1;
}
- return 1;
+
}
}
i++;
i = current_var->size;
continue;
}else{
- if(XBT_LOG_ISENABLED(mc_compare, xbt_log_priority_verbose)){
- XBT_VERB("Different global variable in binary : %s", current_var->name);
+ if((addr_pointed1 > std_heap) && ((char *)addr_pointed1 < (char *)std_heap + STD_HEAP_SIZE) && (addr_pointed2 > std_heap) && ((char *)addr_pointed2 < (char *)std_heap + STD_HEAP_SIZE)){
+ res_compare = compare_area(addr_pointed1, addr_pointed2, NULL, equals);
+ if(res_compare == 1){
+ #ifdef MC_VERBOSE
+ XBT_VERB("Different global variable in binary : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+ #endif
+ return 1;
+ }else{
+ XBT_VERB("False pointer differences for variable : %s", current_var->name);
+ }
+ }else{
+ #ifdef MC_VERBOSE
+ XBT_VERB("Different global variable in binary : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+ #endif
+ return 1;
}
- return 1;
}
}
i++;
/* Init heap information used in heap comparison algorithm */
init_heap_information((xbt_mheap_t)s1->regions[heap_index]->data, (xbt_mheap_t)s2->regions[heap_index]->data);
+ xbt_dynar_t equals = xbt_dynar_new(sizeof(heap_equality_t), heap_equality_free_voidp);
+
/* Compare binary global variables */
- is_diff = compare_global_variables(s1->region_type[data_program_index], s1->regions[data_program_index]->data, s2->regions[data_program_index]->data);
+ is_diff = compare_global_variables(s1->region_type[data_program_index], s1->regions[data_program_index]->data, s2->regions[data_program_index]->data, equals);
if(is_diff != 0){
#ifdef MC_DEBUG
xbt_os_timer_stop(timer);
#endif
/* Compare libsimgrid global variables */
- is_diff = compare_global_variables(s1->region_type[data_libsimgrid_index], s1->regions[data_libsimgrid_index]->data, s2->regions[data_libsimgrid_index]->data);
+ is_diff = compare_global_variables(s1->region_type[data_libsimgrid_index], s1->regions[data_libsimgrid_index]->data, s2->regions[data_libsimgrid_index]->data, equals);
if(is_diff != 0){
#ifdef MC_DEBUG
xbt_os_timer_stop(timer);
/* Compare heap */
xbt_dynar_t stacks1 = xbt_dynar_new(sizeof(stack_region_t), stack_region_free_voidp);
xbt_dynar_t stacks2 = xbt_dynar_new(sizeof(stack_region_t), stack_region_free_voidp);
- xbt_dynar_t equals = xbt_dynar_new(sizeof(heap_equality_t), heap_equality_free_voidp);
void *heap1 = s1->regions[heap_index]->data, *heap2 = s2->regions[heap_index]->data;
- if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[heap_index]->data, (xbt_mheap_t)s2->regions[heap_index]->data, &stacks1, &stacks2, &equals)){
+ if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[heap_index]->data, (xbt_mheap_t)s2->regions[heap_index]->data, &stacks1, &stacks2, equals)){
#ifdef MC_DEBUG
xbt_os_timer_stop(timer);
static dw_frame_t get_frame_by_offset(xbt_dict_t all_variables, unsigned long int offset);
static size_t data_bss_ignore_size(void *address);
static void MC_get_global_variables(char *elf_file);
+static void heap_ignore_region_free(mc_heap_ignore_region_t r);
+static void heap_ignore_region_free_voidp(void *r);
void MC_do_the_modelcheck_for_real() {
/************ MC_ignore ***********/
+static void heap_ignore_region_free(mc_heap_ignore_region_t r){
+ if(r)
+ xbt_free(r);
+}
+
+static void heap_ignore_region_free_voidp(void *r){
+ heap_ignore_region_free((mc_heap_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;
if(mc_heap_comparison_ignore == NULL)
- mc_heap_comparison_ignore = xbt_dynar_new(sizeof(mc_heap_ignore_region_t), NULL);
+ mc_heap_comparison_ignore = xbt_dynar_new(sizeof(mc_heap_ignore_region_t), heap_ignore_region_free_voidp);
mc_heap_ignore_region_t region = NULL;
region = xbt_new0(s_mc_heap_ignore_region_t, 1);
region->address = address;
region->size = size;
- if((address >= std_heap) && (address <= (void*)((char *)std_heap + STD_HEAP_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 = 1;
- }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] = 1;
- }
-
+ 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 = 1;
+ }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] = 1;
}
unsigned int cursor = 0;
MC_SET_RAW_MEM;
}
+
+
+void MC_remove_ignore_heap(void *address, size_t size){
+
+ int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
+
+ MC_SET_RAW_MEM;
+
+ unsigned int cursor = 0;
+ int start = 0;
+ int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
+ mc_heap_ignore_region_t region;
+ int ignore_found = 0;
+
+ while(start <= end){
+ cursor = (start + end) / 2;
+ region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
+ if(region->address == address){
+ ignore_found = 1;
+ break;
+ }
+ if(region->address < address)
+ start = cursor + 1;
+ if(region->address > address){
+ if((char * )region->address <= ((char *)address + size)){
+ ignore_found = 1;
+ break;
+ }else
+ end = cursor - 1;
+ }
+ }
+
+ if(ignore_found == 1){
+ xbt_dynar_remove_at(mc_heap_comparison_ignore, cursor, NULL);
+ MC_remove_ignore_heap(address, size);
+ }
+
+ MC_UNSET_RAW_MEM;
+
+ if(raw_mem_set)
+ MC_SET_RAW_MEM;
+}
+
void MC_ignore_data_bss(void *address, size_t size){
int raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
#include "mmprivate.h"
#include "xbt/ex.h"
+#include "mc/mc.h"
/* Return memory to the heap.
Like `mfree' but don't call a mfree_hook if there is one. */
mdp -> heapstats.bytes_free +=
mdp -> heapinfo[block].busy_block.size * BLOCKSIZE;
+ if(mdp->heapinfo[block].busy_block.ignore == 1)
+ MC_remove_ignore_heap(ptr, mdp -> heapinfo[block].busy_block.busy_size);
+
/* Find the free cluster previous to this one in the free list.
Start searching at the last block referenced; this may benefit
programs with locality of allocation. */
abort();
}
mdp->heapinfo[block+it].type = -1;
+ mdp->heapinfo[block+it].busy_block.ignore = 0;
+
}
block = i;
abort();
}
mdp->heapinfo[block+it].type = -1;
+ mdp->heapinfo[block+it].busy_block.ignore = 0;
}
}
THROWF(system_error, 0, "Asked to free a fragment that is already free. I'm puzzled\n");
}
+ if(mdp->heapinfo[block].busy_frag.ignore[frag_nb] == 1)
+ MC_remove_ignore_heap(ptr, mdp->heapinfo[block].busy_frag.frag_size[frag_nb]);
+
/* Set size used in the fragment to -1 */
mdp->heapinfo[block].busy_frag.frag_size[frag_nb] = -1;
mdp->heapinfo[block].busy_frag.ignore[frag_nb] = 0;
static int is_new_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2);
static heap_area_t new_heap_area(int block, int fragment);
-static int in_mc_comparison_ignore(int block, int fragment);
static size_t heap_comparison_ignore_size(void *address);
-static void add_heap_equality(xbt_dynar_t *equals, void *a1, void *a2);
-static void remove_heap_equality(xbt_dynar_t *equals, int address, void *a);
+static void add_heap_equality(xbt_dynar_t equals, void *a1, void *a2);
+static void remove_heap_equality(xbt_dynar_t equals, int address, void *a);
static char* is_stack(void *address);
}
-int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t *stack1, xbt_dynar_t *stack2, xbt_dynar_t *equals){
+int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t *stack1, xbt_dynar_t *stack2, xbt_dynar_t equals){
if(heap1 == NULL && heap1 == NULL){
XBT_DEBUG("Malloc descriptors null");
res_compare = -1;
}
- res_compare = compare_area(addr_block1, addr_block2, previous);
+ res_compare = compare_area(addr_block1, addr_block2, previous, equals);
if(res_compare == 0 || res_compare == -1){
for(k=1; k < heapinfo2[current_block].busy_block.size; k++)
continue;
}
- res_compare = compare_area(addr_block1, addr_block2, previous);
+ res_compare = compare_area(addr_block1, addr_block2, previous, equals);
if(res_compare == 0 || res_compare == -1){
for(k=1; k < heapinfo2[i2].busy_block.size; k++)
addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
addr_frag2 = (void*) ((char *)addr_block2 + (current_fragment << ((xbt_mheap_t)s_heap)->heapinfo[current_block].type));
- res_compare = compare_area(addr_frag1, addr_frag2, previous);
+ res_compare = compare_area(addr_frag1, addr_frag2, previous, equals);
if(res_compare == 0){
equal = 1;
addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
addr_frag2 = (void*) ((char *)addr_block2 + (j2 << ((xbt_mheap_t)s_heap)->heapinfo[i2].type));
- res_compare = compare_area(addr_frag1, addr_frag2, previous);
+ res_compare = compare_area(addr_frag1, addr_frag2, previous, equals);
if(res_compare == 0){
equal = 1;
return area;
}
-static int in_mc_comparison_ignore(int block, int fragment){
-
- unsigned int cursor = 0;
- int start = 0;
- int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
- mc_heap_ignore_region_t region;
-
- while(start <= end){
- cursor = (start + end) / 2;
- region = (mc_heap_ignore_region_t)xbt_dynar_get_as(mc_heap_comparison_ignore, cursor, mc_heap_ignore_region_t);
- if(region->block == block){
- if(region->fragment == fragment)
- return 1;
- if(region->fragment < fragment)
- start = cursor + 1;
- if(region->fragment > fragment)
- end = cursor - 1;
- }
- if(region->block < block)
- start = cursor + 1;
- if(region->block > block)
- end = cursor - 1;
- }
-
- return 0;
-}
static size_t heap_comparison_ignore_size(void *address){
+
unsigned int cursor = 0;
int start = 0;
int end = xbt_dynar_length(mc_heap_comparison_ignore) - 1;
}
-int compare_area(void *area1, void* area2, xbt_dynar_t previous){
+int compare_area(void *area1, void* area2, xbt_dynar_t previous, xbt_dynar_t equals){
size_t i = 0, pointer_align = 0, ignore1 = 0, ignore2 = 0;
void *address_pointed1, *address_pointed2;
void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
void *area1_to_compare, *area2_to_compare;
+ int match_pairs = 0;
+
+ if(previous == NULL){
+ previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
+ match_pairs = 1;
+ }
+
block1 = ((char*)area1 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
block2 = ((char*)area2 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
size = heapinfo1[block1].busy_frag.frag_size[frag1];
+ if(size == 0)
+ return 0;
+
if((ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)) && heapinfo1[block1].busy_frag.ignore[frag1] == 1)
check_ignore = 1;
}
size = heapinfo1[block1].busy_frag.frag_size[frag1];
+ if(size == 0)
+ return 0;
+
if((ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)) && heapinfo1[block1].busy_frag.ignore[frag1] == 1)
check_ignore = 1;
}else{
while(i<size){
- if(check_ignore){
+ if((ignore_done < xbt_dynar_length(mc_heap_comparison_ignore)) && check_ignore){
if((ignore1 = heap_comparison_ignore_size((char *)area1 + i)) > 0){
if((ignore2 = heap_comparison_ignore_size((char *)area2 + i)) == ignore1){
address_pointed1 = *((void **)((char *)area1_to_compare + pointer_align));
address_pointed2 = *((void **)((char *)area2_to_compare + pointer_align));
- res_compare = compare_area(address_pointed1, address_pointed2, previous);
+ res_compare = compare_area(address_pointed1, address_pointed2, previous, equals);
if(res_compare == 1)
- return 1;
+ return 1;
i = pointer_align + sizeof(void *);
}
}
+ if(match_pairs)
+ match_equals(previous, equals);
+
return 0;
return 1;
}
-void match_equals(xbt_dynar_t list, xbt_dynar_t *equals){
+void match_equals(xbt_dynar_t list, xbt_dynar_t equals){
unsigned int cursor = 0;
heap_area_pair_t current_pair;
return NULL;
}
-static void add_heap_equality(xbt_dynar_t *equals, void *a1, void *a2){
+static void add_heap_equality(xbt_dynar_t equals, void *a1, void *a2){
- if(xbt_dynar_is_empty(*equals)){
+ if(xbt_dynar_is_empty(equals)){
heap_equality_t he = xbt_new0(s_heap_equality_t, 1);
he->address1 = a1;
he->address2 = a2;
- xbt_dynar_insert_at(*equals, 0, &he);
+ xbt_dynar_insert_at(equals, 0, &he);
}else{
unsigned int cursor = 0;
int start = 0;
- int end = xbt_dynar_length(*equals) - 1;
+ int end = xbt_dynar_length(equals) - 1;
heap_equality_t current_equality = NULL;
while(start <= end){
cursor = (start + end) / 2;
- current_equality = (heap_equality_t)xbt_dynar_get_as(*equals, cursor, heap_equality_t);
+ current_equality = (heap_equality_t)xbt_dynar_get_as(equals, cursor, heap_equality_t);
if(current_equality->address1 == a1){
if(current_equality->address2 == a2)
return;
he->address2 = a2;
if(current_equality->address1 < a1)
- xbt_dynar_insert_at(*equals, cursor + 1 , &he);
+ xbt_dynar_insert_at(equals, cursor + 1 , &he);
else
- xbt_dynar_insert_at(*equals, cursor, &he);
+ xbt_dynar_insert_at(equals, cursor, &he);
}
}
-static void remove_heap_equality(xbt_dynar_t *equals, int address, void *a){
+static void remove_heap_equality(xbt_dynar_t equals, int address, void *a){
unsigned int cursor = 0;
heap_equality_t current_equality;
if(address == 1){
int start = 0;
- int end = xbt_dynar_length(*equals) - 1;
+ int end = xbt_dynar_length(equals) - 1;
while(start <= end && found == 0){
cursor = (start + end) / 2;
- current_equality = (heap_equality_t)xbt_dynar_get_as(*equals, cursor, heap_equality_t);
+ current_equality = (heap_equality_t)xbt_dynar_get_as(equals, cursor, heap_equality_t);
if(current_equality->address1 == a)
found = 1;
if(current_equality->address1 < a)
}
if(found == 1)
- xbt_dynar_remove_at(*equals, cursor, NULL);
+ xbt_dynar_remove_at(equals, cursor, NULL);
}else{
- xbt_dynar_foreach(*equals, cursor, current_equality){
+ xbt_dynar_foreach(equals, cursor, current_equality){
if(current_equality->address2 == a){
found = 1;
break;
}
if(found == 1)
- xbt_dynar_remove_at(*equals, cursor, NULL);
+ xbt_dynar_remove_at(equals, cursor, NULL);
}