xbt_die("No heap region");
}
-static
-int mmalloc_compare_heap(
- simgrid::mc::StateComparator& state, simgrid::mc::Snapshot* snapshot1, simgrid::mc::Snapshot* snapshot2)
+static bool mmalloc_heap_equal(simgrid::mc::StateComparator& state, simgrid::mc::Snapshot* snapshot1,
+ simgrid::mc::Snapshot* snapshot2)
{
simgrid::mc::RemoteClient* process = &mc_model_checker->process();
if (i1 == state.heaplimit)
XBT_DEBUG("Number of blocks/fragments not found in heap2: %d", nb_diff2);
- return nb_diff1 > 0 || nb_diff2 > 0;
+ return nb_diff1 == 0 && nb_diff2 == 0;
}
/**
simgrid::mc::Snapshot* snapshot2, HeapLocationPairs* previous,
simgrid::mc::Type* type, int area_size, int check_ignore, int pointer_level)
{
- do {
-
- // HACK: This should not happen but in pratice, there are some
- // DW_TAG_typedef without an associated DW_AT_type:
- //<1><538832>: Abbrev Number: 111 (DW_TAG_typedef)
- // <538833> DW_AT_name : (indirect string, offset: 0x2292f3): gregset_t
- // <538837> DW_AT_decl_file : 98
- // <538838> DW_AT_decl_line : 37
- if (type == nullptr)
- return 0;
-
- if (is_stack(real_area1) && is_stack(real_area2))
- return 0;
+ // HACK: This should not happen but in pratice, there are some
+ // DW_TAG_typedef without an associated DW_AT_type:
+ //<1><538832>: Abbrev Number: 111 (DW_TAG_typedef)
+ // <538833> DW_AT_name : (indirect string, offset: 0x2292f3): gregset_t
+ // <538837> DW_AT_decl_file : 98
+ // <538838> DW_AT_decl_line : 37
+ if (type == nullptr)
+ return 0;
- if (check_ignore > 0) {
- ssize_t ignore1 = heap_comparison_ignore_size(state.processStates[0].to_ignore, real_area1);
- if (ignore1 > 0 && heap_comparison_ignore_size(state.processStates[1].to_ignore, real_area2) == ignore1)
- return 0;
- }
+ if (is_stack(real_area1) && is_stack(real_area2))
+ return 0;
- simgrid::mc::Type* subtype;
- simgrid::mc::Type* subsubtype;
- int elm_size;
- const void* addr_pointed1;
- const void* addr_pointed2;
+ if (check_ignore > 0) {
+ ssize_t ignore1 = heap_comparison_ignore_size(state.processStates[0].to_ignore, real_area1);
+ if (ignore1 > 0 && heap_comparison_ignore_size(state.processStates[1].to_ignore, real_area2) == ignore1)
+ return 0;
+ }
- simgrid::mc::Region* heap_region1 = MC_get_heap_region(snapshot1);
- simgrid::mc::Region* heap_region2 = MC_get_heap_region(snapshot2);
+ simgrid::mc::Type* subtype;
+ simgrid::mc::Type* subsubtype;
+ int elm_size;
+ const void* addr_pointed1;
+ const void* addr_pointed2;
- switch (type->type) {
- case DW_TAG_unspecified_type:
- return 1;
+ simgrid::mc::Region* heap_region1 = MC_get_heap_region(snapshot1);
+ simgrid::mc::Region* heap_region2 = MC_get_heap_region(snapshot2);
- case DW_TAG_base_type:
- if (not type->name.empty() && type->name == "char") { /* String, hence random (arbitrary ?) size */
- if (real_area1 == real_area2)
- return -1;
- else
- return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, area_size) != 0;
- } else {
- if (area_size != -1 && type->byte_size != area_size)
- return -1;
- else
- return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0;
- }
+ switch (type->type) {
+ case DW_TAG_unspecified_type:
+ return 1;
- case DW_TAG_enumeration_type:
+ case DW_TAG_base_type:
+ if (not type->name.empty() && type->name == "char") { /* String, hence random (arbitrary ?) size */
+ if (real_area1 == real_area2)
+ return -1;
+ else
+ return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, area_size) != 0;
+ } else {
if (area_size != -1 && type->byte_size != area_size)
return -1;
- return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0;
-
- case DW_TAG_typedef:
- case DW_TAG_const_type:
- case DW_TAG_volatile_type:
- // Poor man's TCO:
- type = type->subtype;
- continue; // restart
-
- case DW_TAG_array_type:
- subtype = type->subtype;
- switch (subtype->type) {
- case DW_TAG_unspecified_type:
- return 1;
-
- case DW_TAG_base_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_structure_type:
- case DW_TAG_class_type:
- case DW_TAG_union_type:
- if (subtype->full_type)
- subtype = subtype->full_type;
- elm_size = subtype->byte_size;
- break;
- // TODO, just remove the type indirection?
- case DW_TAG_const_type:
- case DW_TAG_typedef:
- case DW_TAG_volatile_type:
- subsubtype = subtype->subtype;
- if (subsubtype->full_type)
- subsubtype = subsubtype->full_type;
- elm_size = subsubtype->byte_size;
- break;
- default:
- return 0;
- }
- for (int i = 0; i < type->element_count; i++) {
- // TODO, add support for variable stride (DW_AT_byte_stride)
- int res = compare_heap_area_with_type(state, (char*)real_area1 + (i * elm_size),
- (char*)real_area2 + (i * elm_size), snapshot1, snapshot2, previous,
- type->subtype, subtype->byte_size, check_ignore, pointer_level);
- if (res == 1)
- return res;
- }
- return 0;
+ else
+ return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0;
+ }
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_pointer_type:
- if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) {
- addr_pointed1 = snapshot1->read(remote((void**)real_area1));
- addr_pointed2 = snapshot2->read(remote((void**)real_area2));
+ case DW_TAG_enumeration_type:
+ if (area_size != -1 && type->byte_size != area_size)
+ return -1;
+ return MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0;
+
+ case DW_TAG_typedef:
+ case DW_TAG_const_type:
+ case DW_TAG_volatile_type:
+ return compare_heap_area_with_type(state, real_area1, real_area2, snapshot1, snapshot2, previous, type->subtype,
+ area_size, check_ignore, pointer_level);
+
+ case DW_TAG_array_type:
+ subtype = type->subtype;
+ switch (subtype->type) {
+ case DW_TAG_unspecified_type:
+ return 1;
+
+ case DW_TAG_base_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ case DW_TAG_union_type:
+ if (subtype->full_type)
+ subtype = subtype->full_type;
+ elm_size = subtype->byte_size;
+ break;
+ // TODO, just remove the type indirection?
+ case DW_TAG_const_type:
+ case DW_TAG_typedef:
+ case DW_TAG_volatile_type:
+ subsubtype = subtype->subtype;
+ if (subsubtype->full_type)
+ subsubtype = subsubtype->full_type;
+ elm_size = subsubtype->byte_size;
+ break;
+ default:
+ return 0;
+ }
+ for (int i = 0; i < type->element_count; i++) {
+ // TODO, add support for variable stride (DW_AT_byte_stride)
+ int res = compare_heap_area_with_type(state, (char*)real_area1 + (i * elm_size),
+ (char*)real_area2 + (i * elm_size), snapshot1, snapshot2, previous,
+ type->subtype, subtype->byte_size, check_ignore, pointer_level);
+ if (res == 1)
+ return res;
+ }
+ return 0;
+
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_pointer_type:
+ if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) {
+ addr_pointed1 = snapshot1->read(remote((void**)real_area1));
+ addr_pointed2 = snapshot2->read(remote((void**)real_area2));
+ return (addr_pointed1 != addr_pointed2);
+ }
+ pointer_level++;
+ if (pointer_level <= 1) {
+ addr_pointed1 = snapshot1->read(remote((void**)real_area1));
+ addr_pointed2 = snapshot2->read(remote((void**)real_area2));
+ if (addr_pointed1 > state.std_heap_copy.heapbase && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1) &&
+ addr_pointed2 > state.std_heap_copy.heapbase && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2))
+ return compare_heap_area(state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, type->subtype,
+ pointer_level);
+ else
return (addr_pointed1 != addr_pointed2);
- }
- pointer_level++;
- if (pointer_level <= 1) {
- addr_pointed1 = snapshot1->read(remote((void**)real_area1));
- addr_pointed2 = snapshot2->read(remote((void**)real_area2));
- if (addr_pointed1 > state.std_heap_copy.heapbase && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1) &&
- addr_pointed2 > state.std_heap_copy.heapbase && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2))
- return compare_heap_area(state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, type->subtype,
- pointer_level);
- else
- return (addr_pointed1 != addr_pointed2);
- }
- for (size_t i = 0; i < (area_size / sizeof(void*)); i++) {
- addr_pointed1 = snapshot1->read(remote((void**)((char*)real_area1 + i * sizeof(void*))));
- addr_pointed2 = snapshot2->read(remote((void**)((char*)real_area2 + i * sizeof(void*))));
- int res;
- if (addr_pointed1 > state.std_heap_copy.heapbase && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1) &&
- addr_pointed2 > state.std_heap_copy.heapbase && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2))
- res = compare_heap_area(state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, type->subtype,
- pointer_level);
- else
- res = (addr_pointed1 != addr_pointed2);
+ }
+ for (size_t i = 0; i < (area_size / sizeof(void*)); i++) {
+ addr_pointed1 = snapshot1->read(remote((void**)((char*)real_area1 + i * sizeof(void*))));
+ addr_pointed2 = snapshot2->read(remote((void**)((char*)real_area2 + i * sizeof(void*))));
+ int res;
+ if (addr_pointed1 > state.std_heap_copy.heapbase && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1) &&
+ addr_pointed2 > state.std_heap_copy.heapbase && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2))
+ res = compare_heap_area(state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, previous, type->subtype,
+ pointer_level);
+ else
+ res = (addr_pointed1 != addr_pointed2);
+ if (res == 1)
+ return res;
+ }
+ return 0;
+
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ if (type->full_type)
+ type = type->full_type;
+ if (area_size != -1 && type->byte_size != area_size) {
+ if (area_size <= type->byte_size || area_size % type->byte_size != 0)
+ return -1;
+ for (size_t i = 0; i < (size_t)(area_size / type->byte_size); i++) {
+ int res = compare_heap_area_with_type(state, (char*)real_area1 + i * type->byte_size,
+ (char*)real_area2 + i * type->byte_size, snapshot1, snapshot2, previous,
+ type, -1, check_ignore, 0);
if (res == 1)
return res;
}
- return 0;
-
- case DW_TAG_structure_type:
- case DW_TAG_class_type:
- if (type->full_type)
- type = type->full_type;
- if (area_size != -1 && type->byte_size != area_size) {
- if (area_size <= type->byte_size || area_size % type->byte_size != 0)
- return -1;
- for (size_t i = 0; i < (size_t)(area_size / type->byte_size); i++) {
- int res = compare_heap_area_with_type(state, (char*)real_area1 + i * type->byte_size,
- (char*)real_area2 + i * type->byte_size, snapshot1, snapshot2,
- previous, type, -1, check_ignore, 0);
- if (res == 1)
- return res;
- }
} else {
for (simgrid::mc::Member& member : type->members) {
// TODO, optimize this? (for the offset case)
}
return 0;
- case DW_TAG_union_type:
- return compare_heap_area_without_type(state, real_area1, real_area2, snapshot1, snapshot2, previous,
- type->byte_size, check_ignore);
-
- default:
- return 0;
- }
-
- xbt_die("Unreachable");
- } while (true);
+ case DW_TAG_union_type:
+ return compare_heap_area_without_type(state, real_area1, real_area2, snapshot1, snapshot2, previous,
+ type->byte_size, check_ignore);
+ }
+ return 0;
}
/** Infer the type of a part of the block from the type of the block
int i;
int res;
- do {
- xbt_assert(type != nullptr);
- switch (type->type) {
- case DW_TAG_unspecified_type:
- return 1;
+ xbt_assert(type != nullptr);
+ switch (type->type) {
+ case DW_TAG_unspecified_type:
+ return 1;
- case DW_TAG_base_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_union_type:
- return MC_snapshot_region_memcmp(real_area1, region1, real_area2, region2, type->byte_size) != 0;
- case DW_TAG_typedef:
- case DW_TAG_volatile_type:
- case DW_TAG_const_type:
- // Poor man's TCO:
- type = type->subtype;
- continue; // restart
- case DW_TAG_array_type:
- subtype = type->subtype;
- switch (subtype->type) {
- case DW_TAG_unspecified_type:
- return 1;
-
- case DW_TAG_base_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_structure_type:
- case DW_TAG_class_type:
- case DW_TAG_union_type:
- if (subtype->full_type)
- subtype = subtype->full_type;
- elm_size = subtype->byte_size;
- break;
- case DW_TAG_const_type:
- case DW_TAG_typedef:
- case DW_TAG_volatile_type:
- subsubtype = subtype->subtype;
- if (subsubtype->full_type)
- subsubtype = subsubtype->full_type;
- elm_size = subsubtype->byte_size;
- break;
- default:
- return 0;
- }
- for (i = 0; i < type->element_count; i++) {
- size_t off = i * elm_size;
- res = compare_areas_with_type(state, (char*)real_area1 + off, snapshot1, region1, (char*)real_area2 + off,
- snapshot2, region2, type->subtype, pointer_level);
- if (res == 1)
- return res;
- }
- break;
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type: {
- void* addr_pointed1 = MC_region_read_pointer(region1, real_area1);
- void* addr_pointed2 = MC_region_read_pointer(region2, real_area2);
-
- if (type->subtype && type->subtype->type == DW_TAG_subroutine_type)
- return (addr_pointed1 != addr_pointed2);
- if (addr_pointed1 == nullptr && addr_pointed2 == nullptr)
- return 0;
- if (addr_pointed1 == nullptr || addr_pointed2 == nullptr)
+ case DW_TAG_base_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_union_type:
+ return MC_snapshot_region_memcmp(real_area1, region1, real_area2, region2, type->byte_size) != 0;
+ case DW_TAG_typedef:
+ case DW_TAG_volatile_type:
+ case DW_TAG_const_type:
+ return compare_areas_with_type(state, real_area1, snapshot1, region1, real_area2, snapshot2, region2,
+ type->subtype, pointer_level);
+ case DW_TAG_array_type:
+ subtype = type->subtype;
+ switch (subtype->type) {
+ case DW_TAG_unspecified_type:
return 1;
- if (not state.compared_pointers.insert(std::make_pair(addr_pointed1, addr_pointed2)).second)
+
+ case DW_TAG_base_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ case DW_TAG_union_type:
+ if (subtype->full_type)
+ subtype = subtype->full_type;
+ elm_size = subtype->byte_size;
+ break;
+ case DW_TAG_const_type:
+ case DW_TAG_typedef:
+ case DW_TAG_volatile_type:
+ subsubtype = subtype->subtype;
+ if (subsubtype->full_type)
+ subsubtype = subsubtype->full_type;
+ elm_size = subsubtype->byte_size;
+ break;
+ default:
return 0;
+ }
+ for (i = 0; i < type->element_count; i++) {
+ size_t off = i * elm_size;
+ res = compare_areas_with_type(state, (char*)real_area1 + off, snapshot1, region1, (char*)real_area2 + off,
+ snapshot2, region2, type->subtype, pointer_level);
+ if (res == 1)
+ return res;
+ }
+ break;
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type: {
+ void* addr_pointed1 = MC_region_read_pointer(region1, real_area1);
+ void* addr_pointed2 = MC_region_read_pointer(region2, real_area2);
+
+ if (type->subtype && type->subtype->type == DW_TAG_subroutine_type)
+ return (addr_pointed1 != addr_pointed2);
+ if (addr_pointed1 == nullptr && addr_pointed2 == nullptr)
+ return 0;
+ if (addr_pointed1 == nullptr || addr_pointed2 == nullptr)
+ return 1;
+ if (not state.compared_pointers.insert(std::make_pair(addr_pointed1, addr_pointed2)).second)
+ return 0;
- pointer_level++;
-
- // Some cases are not handled here:
- // * the pointers lead to different areas (one to the heap, the other to the RW segment ...)
- // * a pointer leads to the read-only segment of the current object
- // * a pointer lead to a different ELF object
-
- if (addr_pointed1 > process->heap_address && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)) {
- if (not(addr_pointed2 > process->heap_address && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2)))
- return 1;
- // The pointers are both in the heap:
- return simgrid::mc::compare_heap_area(state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, nullptr,
- type->subtype, pointer_level);
-
- } else if (region1->contain(simgrid::mc::remote(addr_pointed1))) {
- // The pointers are both in the current object R/W segment:
- if (not region2->contain(simgrid::mc::remote(addr_pointed2)))
- return 1;
- if (not type->type_id)
- return (addr_pointed1 != addr_pointed2);
- else
- return compare_areas_with_type(state, addr_pointed1, snapshot1, region1, addr_pointed2, snapshot2, region2,
- type->subtype, pointer_level);
- } else {
+ pointer_level++;
- // TODO, We do not handle very well the case where
- // it belongs to a different (non-heap) region from the current one.
+ // Some cases are not handled here:
+ // * the pointers lead to different areas (one to the heap, the other to the RW segment ...)
+ // * a pointer leads to the read-only segment of the current object
+ // * a pointer lead to a different ELF object
+
+ if (addr_pointed1 > process->heap_address && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1)) {
+ if (not(addr_pointed2 > process->heap_address && addr_pointed2 < mc_snapshot_get_heap_end(snapshot2)))
+ return 1;
+ // The pointers are both in the heap:
+ return simgrid::mc::compare_heap_area(state, addr_pointed1, addr_pointed2, snapshot1, snapshot2, nullptr,
+ type->subtype, pointer_level);
+ } else if (region1->contain(simgrid::mc::remote(addr_pointed1))) {
+ // The pointers are both in the current object R/W segment:
+ if (not region2->contain(simgrid::mc::remote(addr_pointed2)))
+ return 1;
+ if (not type->type_id)
return (addr_pointed1 != addr_pointed2);
- }
+ else
+ return compare_areas_with_type(state, addr_pointed1, snapshot1, region1, addr_pointed2, snapshot2, region2,
+ type->subtype, pointer_level);
+ } else {
+
+ // TODO, We do not handle very well the case where
+ // it belongs to a different (non-heap) region from the current one.
+
+ return (addr_pointed1 != addr_pointed2);
}
- case DW_TAG_structure_type:
- case DW_TAG_class_type:
- for (simgrid::mc::Member& member : type->members) {
- void* member1 = simgrid::dwarf::resolve_member(real_area1, type, &member, snapshot1);
- void* member2 = simgrid::dwarf::resolve_member(real_area2, type, &member, snapshot2);
- simgrid::mc::Region* subregion1 = snapshot1->get_region(member1, region1); // region1 is hinted
- simgrid::mc::Region* subregion2 = snapshot2->get_region(member2, region2); // region2 is hinted
- res = compare_areas_with_type(state, member1, snapshot1, subregion1, member2, snapshot2, subregion2,
- member.type, pointer_level);
- if (res == 1)
- return res;
- }
- break;
- case DW_TAG_subroutine_type:
- return -1;
- default:
- XBT_VERB("Unknown case: %d", type->type);
- break;
}
+ case DW_TAG_structure_type:
+ case DW_TAG_class_type:
+ for (simgrid::mc::Member& member : type->members) {
+ void* member1 = simgrid::dwarf::resolve_member(real_area1, type, &member, snapshot1);
+ void* member2 = simgrid::dwarf::resolve_member(real_area2, type, &member, snapshot2);
+ simgrid::mc::Region* subregion1 = snapshot1->get_region(member1, region1); // region1 is hinted
+ simgrid::mc::Region* subregion2 = snapshot2->get_region(member2, region2); // region2 is hinted
+ res = compare_areas_with_type(state, member1, snapshot1, subregion1, member2, snapshot2, subregion2,
+ member.type, pointer_level);
+ if (res == 1)
+ return res;
+ }
+ break;
+ case DW_TAG_subroutine_type:
+ return -1;
+ default:
+ XBT_VERB("Unknown case: %d", type->type);
+ break;
+ }
- return 0;
- } while (true);
+ return 0;
}
-static int compare_global_variables(simgrid::mc::StateComparator& state, simgrid::mc::ObjectInformation* object_info,
- simgrid::mc::Region* r1, simgrid::mc::Region* r2, simgrid::mc::Snapshot* snapshot1,
- simgrid::mc::Snapshot* snapshot2)
+static bool global_variables_equal(simgrid::mc::StateComparator& state, simgrid::mc::ObjectInformation* object_info,
+ simgrid::mc::Region* r1, simgrid::mc::Region* r2, simgrid::mc::Snapshot* snapshot1,
+ simgrid::mc::Snapshot* snapshot2)
{
xbt_assert(r1 && r2, "Missing region.");
XBT_VERB("Global variable %s (%p) is different between snapshots",
current_var.name.c_str(),
(char *) current_var.address);
- return 1;
+ return false;
}
}
- return 0;
+ return true;
}
-static int compare_local_variables(simgrid::mc::StateComparator& state,
- simgrid::mc::Snapshot* snapshot1,
- simgrid::mc::Snapshot* snapshot2,
- mc_snapshot_stack_t stack1,
- mc_snapshot_stack_t stack2)
+static bool local_variables_equal(simgrid::mc::StateComparator& state, simgrid::mc::Snapshot* snapshot1,
+ simgrid::mc::Snapshot* snapshot2, mc_snapshot_stack_t stack1,
+ mc_snapshot_stack_t stack2)
{
if (stack1->local_variables.size() != stack2->local_variables.size()) {
XBT_VERB("Different number of local variables");
- return 1;
+ return false;
}
- unsigned int cursor = 0;
- local_variable_t current_var1;
- local_variable_t current_var2;
- while (cursor < stack1->local_variables.size()) {
- current_var1 = &stack1->local_variables[cursor];
- current_var2 = &stack1->local_variables[cursor];
- if (current_var1->name != current_var2->name
- || current_var1->subprogram != current_var2->subprogram
- || current_var1->ip != current_var2->ip) {
- // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
- XBT_VERB
- ("Different name of variable (%s - %s) "
- "or frame (%s - %s) or ip (%lu - %lu)",
- current_var1->name.c_str(),
- current_var2->name.c_str(),
- current_var1->subprogram->name.c_str(),
- current_var2->subprogram->name.c_str(),
- current_var1->ip, current_var2->ip);
- return 1;
- }
+ for (unsigned int cursor = 0; cursor < stack1->local_variables.size(); cursor++) {
+ local_variable_t current_var1 = &stack1->local_variables[cursor];
+ local_variable_t current_var2 = &stack2->local_variables[cursor];
+ if (current_var1->name != current_var2->name || current_var1->subprogram != current_var2->subprogram ||
+ current_var1->ip != current_var2->ip) {
// TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
+ XBT_VERB("Different name of variable (%s - %s) "
+ "or frame (%s - %s) or ip (%lu - %lu)",
+ current_var1->name.c_str(), current_var2->name.c_str(), current_var1->subprogram->name.c_str(),
+ current_var2->subprogram->name.c_str(), current_var1->ip, current_var2->ip);
+ return false;
+ }
+ // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
- simgrid::mc::Type* subtype = current_var1->type;
- int res = compare_areas_with_type(state, current_var1->address, snapshot1,
- snapshot1->get_region(current_var1->address), current_var2->address,
- snapshot2, snapshot2->get_region(current_var2->address), subtype, 0);
-
- if (res == 1) {
- // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
- XBT_VERB("Local variable %s (%p - %p) in frame %s "
- "is different between snapshots",
- current_var1->name.c_str(), current_var1->address, current_var2->address,
- current_var1->subprogram->name.c_str());
- return res;
- }
- cursor++;
+ if (compare_areas_with_type(state, current_var1->address, snapshot1, snapshot1->get_region(current_var1->address),
+ current_var2->address, snapshot2, snapshot2->get_region(current_var2->address),
+ current_var1->type, 0) == 1) {
+ // TODO, fix current_varX->subprogram->name to include name if DW_TAG_inlined_subprogram
+ XBT_VERB("Local variable %s (%p - %p) in frame %s "
+ "is different between snapshots",
+ current_var1->name.c_str(), current_var1->address, current_var2->address,
+ current_var1->subprogram->name.c_str());
+ return false;
}
- return 0;
+ }
+ return true;
}
namespace simgrid {
static std::unique_ptr<simgrid::mc::StateComparator> state_comparator;
-int snapshot_compare(Snapshot* s1, Snapshot* s2)
+bool snapshot_equal(Snapshot* s1, Snapshot* s2)
{
// TODO, make this a field of ModelChecker or something similar
if (state_comparator == nullptr)
RemoteClient* process = &mc_model_checker->process();
- if (_sg_mc_hash) {
- if (s1->hash_ != s2->hash_) {
- XBT_VERB("(%d - %d) Different hash: 0x%" PRIx64 "--0x%" PRIx64, s1->num_state_, s2->num_state_, s1->hash_,
- s2->hash_);
- return 1;
+ if (s1->hash_ != s2->hash_) {
+ XBT_VERB("(%d - %d) Different hash: 0x%" PRIx64 "--0x%" PRIx64, s1->num_state_, s2->num_state_, s1->hash_,
+ s2->hash_);
+ return false;
} else
XBT_VERB("(%d - %d) Same hash: 0x%" PRIx64, s1->num_state_, s2->num_state_, s1->hash_);
- }
/* Compare enabled processes */
if (s1->enabled_processes_ != s2->enabled_processes_) {
XBT_VERB("(%d - %d) Different amount of enabled processes", s1->num_state_, s2->num_state_);
- return 1;
+ return false;
}
/* Compare size of stacks */
- int is_diff = 0;
for (unsigned long i = 0; i < s1->stacks_.size(); i++) {
size_t size_used1 = s1->stack_sizes_[i];
size_t size_used2 = s2->stack_sizes_[i];
if (size_used1 != size_used2) {
XBT_VERB("(%d - %d) Different size used in stacks: %zu - %zu", s1->num_state_, s2->num_state_, size_used1,
size_used2);
- return 1;
+ return false;
}
}
- if (is_diff) // do not proceed if there is any stacks that don't match
- return 1;
/* Init heap information used in heap comparison algorithm */
xbt_mheap_t heap1 = (xbt_mheap_t)s1->read_bytes(alloca(sizeof(struct mdesc)), sizeof(struct mdesc),
if (res_init == -1) {
XBT_VERB("(%d - %d) Different heap information", s1->num_state_, s2->num_state_);
- return 1;
+ return false;
}
/* Stacks comparison */
- // int diff_local = 0;
for (unsigned int cursor = 0; cursor < s1->stacks_.size(); cursor++) {
mc_snapshot_stack_t stack1 = &s1->stacks_[cursor];
mc_snapshot_stack_t stack2 = &s2->stacks_[cursor];
- if (compare_local_variables(*state_comparator, s1, s2, stack1, stack2) > 0) {
+ if (not local_variables_equal(*state_comparator, s1, s2, stack1, stack2)) {
XBT_VERB("(%d - %d) Different local variables between stacks %u", s1->num_state_, s2->num_state_, cursor + 1);
- return 1;
+ return false;
}
}
size_t regions_count = s1->snapshot_regions_.size();
- // TODO, raise a difference instead?
- xbt_assert(regions_count == s2->snapshot_regions_.size());
+ if (regions_count != s2->snapshot_regions_.size())
+ return false;
for (size_t k = 0; k != regions_count; ++k) {
Region* region1 = s1->snapshot_regions_[k].get();
xbt_assert(region1->object_info());
/* Compare global variables */
- if (compare_global_variables(*state_comparator, region1->object_info(), region1, region2, s1, s2)) {
+ if (not global_variables_equal(*state_comparator, region1->object_info(), region1, region2, s1, s2)) {
std::string const& name = region1->object_info()->file_name;
XBT_VERB("(%d - %d) Different global variables in %s", s1->num_state_, s2->num_state_, name.c_str());
- return 1;
+ return false;
}
}
/* Compare heap */
- if (mmalloc_compare_heap(*state_comparator, s1, s2) > 0) {
+ if (not mmalloc_heap_equal(*state_comparator, s1, s2)) {
XBT_VERB("(%d - %d) Different heap (mmalloc_compare)", s1->num_state_, s2->num_state_);
- return 1;
+ return false;
}
XBT_VERB("(%d - %d) No difference found", s1->num_state_, s2->num_state_);
- return 0;
+ return true;
}
}