From 2e3c0670f37a0c37487fc75c73956290dc086c50 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Tue, 16 Dec 2014 13:06:37 +0100 Subject: [PATCH] [mc] Abstract the process and a snapshot types with a address_space superclass Add a `address_space`, superclass of `process` and `snapshot`. In order to do this, the contract of MC_process_read and MC_snapshot_read has been uniformized: * the order of arguments has been harmonized; * a new flag MC_ADDRESS_SPACE_READ_FLAGS_LAZY is used to avoid copy when the data is in the current memory; * MC_NO_PROCESS_INDEX has been renamed into MC_PROCESS_INDEX_MISSING; * MC_ANY_PROCESS_INDEX has been renamed into MC_PROCESS_INDEX_ANY; * MC_PROCESS_INDEX_DISABLED is used to access the raw address space (without privatisation support); * `const void*` is used instead of `void*` when it possible. Soem cleanup things are still to be done: * remove special NULL handling; * add support for SMPI privatization in the process object. --- buildtools/Cmake/DefinePackages.cmake | 2 + include/xbt/mmalloc.h | 2 +- src/mc/mc_address_space.c | 7 +++ src/mc/mc_address_space.h | 73 +++++++++++++++++++++++++ src/mc/mc_checkpoint.c | 12 ++++- src/mc/mc_compare.cpp | 24 +++++---- src/mc/mc_diff.c | 76 +++++++++++++-------------- src/mc/mc_dwarf_expression.c | 25 ++++++--- src/mc/mc_location.h | 7 +-- src/mc/mc_member.c | 4 +- src/mc/mc_mmu.h | 8 +-- src/mc/mc_object_info.h | 4 +- src/mc/mc_page_snapshot.cpp | 3 +- src/mc/mc_process.c | 38 +++++++++++--- src/mc/mc_process.h | 7 ++- src/mc/mc_snapshot.c | 69 +++++++++++++----------- src/mc/mc_snapshot.h | 65 ++++++++++------------- 17 files changed, 278 insertions(+), 148 deletions(-) create mode 100644 src/mc/mc_address_space.c create mode 100644 src/mc/mc_address_space.h diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index 871bd05418..fcb29a854d 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -594,6 +594,8 @@ set(MC_SRC_BASE ) set(MC_SRC + src/mc/mc_address_space.h + src/mc/mc_address_space.c src/mc/mc_forward.h src/mc/mc_process.h src/mc/mc_process.c diff --git a/include/xbt/mmalloc.h b/include/xbt/mmalloc.h index 191d3cc3e2..3b11dbe8fa 100644 --- a/include/xbt/mmalloc.h +++ b/include/xbt/mmalloc.h @@ -71,7 +71,7 @@ struct s_dw_type; int mmalloc_compare_heap(struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2); int mmalloc_linear_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2); int init_heap_information(xbt_mheap_t heap1, xbt_mheap_t heap2, xbt_dynar_t to_ignore1, xbt_dynar_t to_ignore2); -int compare_heap_area(int process_index, void *area1, void* area2, struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2, xbt_dynar_t previous, struct s_dw_type *type, int pointer_level); +int compare_heap_area(int process_index, const void *area1, const void* area2, struct s_mc_snapshot* snapshot1, struct s_mc_snapshot* snapshot2, xbt_dynar_t previous, struct s_dw_type *type, int pointer_level); void reset_heap_information(void); size_t mmalloc_get_bytes_used(xbt_mheap_t); diff --git a/src/mc/mc_address_space.c b/src/mc/mc_address_space.c new file mode 100644 index 0000000000..df738ecf2d --- /dev/null +++ b/src/mc/mc_address_space.c @@ -0,0 +1,7 @@ +/* Copyright (c) 2008-2014. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "mc_address_space.h" diff --git a/src/mc/mc_address_space.h b/src/mc/mc_address_space.h new file mode 100644 index 0000000000..a154676dc2 --- /dev/null +++ b/src/mc/mc_address_space.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2008-2014. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef MC_ADDRESS_SPACE_H +#define MC_ADDRESS_SPACE_H + +#include + +#include "mc_forward.h" + +// ***** Data types + +typedef enum e_adress_space_read_flags { + MC_ADDRESS_SPACE_READ_FLAGS_NONE = 0, + + /** Avoid a copy for when the data is available in the current process. + * + * In this case, the return value of a MC_address_space_read might + * be different from the provided buffer. + */ + MC_ADDRESS_SPACE_READ_FLAGS_LAZY = 1 +} e_adress_space_read_flags_t; + +/** Process index used when no process is available + * + * The expected behaviour is that if a process index is needed it will fail. + * */ +#define MC_PROCESS_INDEX_MISSING -1 + +#define MC_PROCESS_INDEX_DISABLED -2 + +/** Process index when any process is suitable + * + * We could use a special negative value in the future. + */ +#define MC_PROCESS_INDEX_ANY 0 + +// ***** Class definition + +typedef struct s_mc_address_space s_mc_address_space_t, *mc_address_space_t; +typedef struct s_mc_address_space_class s_mc_address_space_class_t, *mc_address_space_class_t; + +struct s_mc_address_space_class { + const void* (*read)( + mc_address_space_t address_space, e_adress_space_read_flags_t flags, + void* target, const void* addr, size_t size, + int process_index); +}; + +/** Base class for an address space (process and snapshot) + */ +struct s_mc_address_space { + mc_address_space_class_t address_space_class; +}; + +// ***** Virtual/non-final methods + +/** Read data from the given address space */ +static inline __attribute__((always_inline)) +const void* MC_address_space_read( + mc_address_space_t address_space, e_adress_space_read_flags_t flags, + void* target, const void* addr, size_t size, + int process_index) +{ + return address_space->address_space_class->read( + address_space, flags, target, addr, size, + process_index); +} + +#endif diff --git a/src/mc/mc_checkpoint.c b/src/mc/mc_checkpoint.c index ccfb513939..774562e2ca 100644 --- a/src/mc/mc_checkpoint.c +++ b/src/mc/mc_checkpoint.c @@ -121,7 +121,9 @@ static mc_mem_region_t mc_region_new_dense( region->permanent_addr = permanent_addr; region->size = size; region->flat.data = xbt_malloc(size); - MC_process_read(&mc_model_checker->process, region->flat.data, permanent_addr, size); + MC_process_read(&mc_model_checker->process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, + region->flat.data, permanent_addr, size, + MC_PROCESS_INDEX_DISABLED); XBT_DEBUG("New region : type : %d, data : %p (real addr %p), size : %zu", region_type, region->flat.data, permanent_addr, size); return region; @@ -274,7 +276,7 @@ static void MC_get_memory_regions(mc_process_t process, mc_snapshot_t snapshot) } else #endif { - snapshot->privatization_index = MC_NO_PROCESS_INDEX; + snapshot->privatization_index = MC_PROCESS_INDEX_MISSING; } } @@ -680,10 +682,16 @@ static void MC_get_current_fd(mc_snapshot_t snapshot){ closedir (fd_dir); } +static s_mc_address_space_class_t mc_snapshot_class = { + .read = (void*) &MC_snapshot_read +}; + mc_snapshot_t MC_take_snapshot(int num_state) { mc_process_t mc_process = &mc_model_checker->process; mc_snapshot_t snapshot = xbt_new0(s_mc_snapshot_t, 1); + snapshot->process = mc_process; + snapshot->address_space.address_space_class = &mc_snapshot_class; snapshot->enabled_processes = xbt_dynar_new(sizeof(int), NULL); smx_process_t process; diff --git a/src/mc/mc_compare.cpp b/src/mc/mc_compare.cpp index 2f7ce7ead0..f77df3f0b3 100644 --- a/src/mc/mc_compare.cpp +++ b/src/mc/mc_compare.cpp @@ -117,7 +117,7 @@ static int compare_areas_with_type(struct mc_compare_state& state, case DW_TAG_enumeration_type: case DW_TAG_union_type: { - return mc_snapshot_region_memcmp( + return MC_snapshot_region_memcmp( real_area1, region1, real_area2, region2, type->byte_size) != 0; } @@ -171,8 +171,8 @@ static int compare_areas_with_type(struct mc_compare_state& state, case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: { - void* addr_pointed1 = mc_snapshot_read_pointer_region(real_area1, region1); - void* addr_pointed2 = mc_snapshot_read_pointer_region(real_area2, region2); + 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); @@ -230,9 +230,9 @@ static int compare_areas_with_type(struct mc_compare_state& state, case DW_TAG_class_type: xbt_dynar_foreach(type->members, cursor, member) { void *member1 = - mc_member_resolve(real_area1, type, member, snapshot1, process_index); + mc_member_resolve(real_area1, type, member, (mc_address_space_t) snapshot1, process_index); void *member2 = - mc_member_resolve(real_area2, type, member, snapshot2, process_index); + mc_member_resolve(real_area2, type, member, (mc_address_space_t) snapshot2, process_index); mc_mem_region_t subregion1 = mc_get_region_hinted(member1, snapshot1, process_index, region1); mc_mem_region_t subregion2 = mc_get_region_hinted(member2, snapshot2, process_index, region2); res = @@ -485,10 +485,14 @@ int snapshot_compare(void *state1, void *state2) #endif /* Init heap information used in heap comparison algorithm */ - xbt_mheap_t heap1 = (xbt_mheap_t) mc_snapshot_read(process->heap_address, s1, MC_NO_PROCESS_INDEX, - alloca(sizeof(struct mdesc)), sizeof(struct mdesc)); - xbt_mheap_t heap2 = (xbt_mheap_t) mc_snapshot_read(process->heap_address, s2, MC_NO_PROCESS_INDEX, - alloca(sizeof(struct mdesc)), sizeof(struct mdesc)); + xbt_mheap_t heap1 = (xbt_mheap_t) MC_snapshot_read( + s1, MC_ADDRESS_SPACE_READ_FLAGS_LAZY, + alloca(sizeof(struct mdesc)), process->heap_address, sizeof(struct mdesc), + MC_PROCESS_INDEX_MISSING); + xbt_mheap_t heap2 = (xbt_mheap_t) MC_snapshot_read( + s2, MC_ADDRESS_SPACE_READ_FLAGS_LAZY, + alloca(sizeof(struct mdesc)), process->heap_address, sizeof(struct mdesc), + MC_PROCESS_INDEX_MISSING); res_init = init_heap_information(heap1, heap2, s1->to_ignore, s2->to_ignore); if (res_init == -1) { #ifdef MC_DEBUG @@ -599,7 +603,7 @@ int snapshot_compare(void *state1, void *state2) /* Compare global variables */ is_diff = - compare_global_variables(region1->object_info, MC_NO_PROCESS_INDEX, + compare_global_variables(region1->object_info, MC_ADDRESS_SPACE_READ_FLAGS_NONE, region1, region2, s1, s2); diff --git a/src/mc/mc_diff.c b/src/mc/mc_diff.c index 4adf44bb1d..257481c2a2 100644 --- a/src/mc/mc_diff.c +++ b/src/mc/mc_diff.c @@ -229,7 +229,7 @@ static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, } static ssize_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, - void *address) + const void *address) { unsigned int cursor = 0; @@ -253,7 +253,7 @@ static ssize_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, return -1; } -static int is_stack(void *address) +static int is_stack(const void *address) { unsigned int cursor = 0; stack_region_t stack; @@ -454,13 +454,13 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) void* heapinfo_address = &((xbt_mheap_t) process->heap_address)->heapinfo; // This is in snapshot do not use them directly: - malloc_info* heapinfos1 = mc_snapshot_read_pointer(heapinfo_address, snapshot1, MC_NO_PROCESS_INDEX); - malloc_info* heapinfos2 = mc_snapshot_read_pointer(heapinfo_address, snapshot2, MC_NO_PROCESS_INDEX); + const malloc_info* heapinfos1 = MC_snapshot_read_pointer(snapshot1, heapinfo_address, MC_PROCESS_INDEX_MISSING); + const malloc_info* heapinfos2 = MC_snapshot_read_pointer(snapshot2, heapinfo_address, MC_PROCESS_INDEX_MISSING); while (i1 <= state->heaplimit) { - malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i1], heap_region1, &heapinfo_temp1, sizeof(malloc_info)); - malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i1], heap_region2, &heapinfo_temp2, sizeof(malloc_info)); + const malloc_info* heapinfo1 = MC_region_read(heap_region1, &heapinfo_temp1, &heapinfos1[i1], sizeof(malloc_info)); + const malloc_info* heapinfo2 = MC_region_read(heap_region2, &heapinfo_temp2, &heapinfos2[i1], sizeof(malloc_info)); if (heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type == MMALLOC_TYPE_HEAPINFO) { /* Free block */ i1 ++; @@ -506,7 +506,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) (char *) ((xbt_mheap_t) state->s_heap)->heapbase)); res_compare = - compare_heap_area(MC_NO_PROCESS_INDEX, addr_block1, addr_block2, snapshot1, snapshot2, + compare_heap_area(MC_PROCESS_INDEX_MISSING, addr_block1, addr_block2, snapshot1, snapshot2, NULL, NULL, 0); if (res_compare != 1) { @@ -533,7 +533,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) continue; } - malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info)); + const malloc_info* heapinfo2b = MC_region_read(heap_region2, &heapinfo_temp2b, &heapinfos2[i2], sizeof(malloc_info)); if (heapinfo2b->type != MMALLOC_TYPE_UNFRAGMENTED) { i2++; @@ -546,7 +546,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) } res_compare = - compare_heap_area(MC_NO_PROCESS_INDEX, addr_block1, addr_block2, snapshot1, snapshot2, + compare_heap_area(MC_PROCESS_INDEX_MISSING, addr_block1, addr_block2, snapshot1, snapshot2, NULL, NULL, 0); if (res_compare != 1) { @@ -599,7 +599,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) (j1 << heapinfo2->type)); res_compare = - compare_heap_area(MC_NO_PROCESS_INDEX, addr_frag1, addr_frag2, snapshot1, snapshot2, + compare_heap_area(MC_PROCESS_INDEX_MISSING, addr_frag1, addr_frag2, snapshot1, snapshot2, NULL, NULL, 0); if (res_compare != 1) @@ -611,7 +611,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) while (i2 <= state->heaplimit && !equal) { - malloc_info* heapinfo2b = mc_snapshot_read_region(&heapinfos2[i2], heap_region2, &heapinfo_temp2b, sizeof(malloc_info)); + const malloc_info* heapinfo2b = MC_region_read(heap_region2, &heapinfo_temp2b, &heapinfos2[i2], sizeof(malloc_info)); if (heapinfo2b->type == MMALLOC_TYPE_FREE || heapinfo2b->type == MMALLOC_TYPE_HEAPINFO) { i2 ++; @@ -646,7 +646,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) (j2 << heapinfo2b->type)); res_compare = - compare_heap_area(MC_NO_PROCESS_INDEX, addr_frag1, addr_frag2, snapshot2, snapshot2, + compare_heap_area(MC_PROCESS_INDEX_MISSING, addr_frag1, addr_frag2, snapshot2, snapshot2, NULL, NULL, 0); if (res_compare != 1) { @@ -683,7 +683,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) size_t i = 1, j = 0; for(i = 1; i <= state->heaplimit; i++) { - malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[i], heap_region1, &heapinfo_temp1, sizeof(malloc_info)); + const malloc_info* heapinfo1 = MC_region_read(heap_region1, &heapinfo_temp1, &heapinfos1[i], sizeof(malloc_info)); if (heapinfo1->type == MMALLOC_TYPE_UNFRAGMENTED) { if (i1 == state->heaplimit) { if (heapinfo1->busy_block.busy_size > 0) { @@ -724,7 +724,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) XBT_DEBUG("Number of blocks/fragments not found in heap1 : %d", nb_diff1); for (i=1; i <= state->heaplimit; i++) { - malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[i], heap_region2, &heapinfo_temp2, sizeof(malloc_info)); + const malloc_info* heapinfo2 = MC_region_read(heap_region2, &heapinfo_temp2, &heapinfos2[i], sizeof(malloc_info)); if (heapinfo2->type == MMALLOC_TYPE_UNFRAGMENTED) { if (i1 == state->heaplimit) { if (heapinfo2->busy_block.busy_size > 0) { @@ -779,7 +779,7 @@ int mmalloc_compare_heap(mc_snapshot_t snapshot1, mc_snapshot_t snapshot2) * @param check_ignore */ static int compare_heap_area_without_type(struct s_mc_diff *state, int process_index, - void *real_area1, void *real_area2, + const void *real_area1, const void *real_area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, int size, @@ -788,7 +788,7 @@ static int compare_heap_area_without_type(struct s_mc_diff *state, int process_i mc_process_t process = &mc_model_checker->process; int i = 0; - void *addr_pointed1, *addr_pointed2; + const void *addr_pointed1, *addr_pointed2; int pointer_align, res_compare; ssize_t ignore1, ignore2; @@ -816,11 +816,11 @@ static int compare_heap_area_without_type(struct s_mc_diff *state, int process_i } } - if (mc_snapshot_region_memcmp(((char *) real_area1) + i, heap_region1, ((char *) real_area2) + i, heap_region2, 1) != 0) { + if (MC_snapshot_region_memcmp(((char *) real_area1) + i, heap_region1, ((char *) real_area2) + i, heap_region2, 1) != 0) { pointer_align = (i / sizeof(void *)) * sizeof(void *); - addr_pointed1 = mc_snapshot_read_pointer((char *) real_area1 + pointer_align, snapshot1, process_index); - addr_pointed2 = mc_snapshot_read_pointer((char *) real_area2 + pointer_align, snapshot2, process_index); + addr_pointed1 = MC_snapshot_read_pointer(snapshot1, (char *) real_area1 + pointer_align, process_index); + addr_pointed2 = MC_snapshot_read_pointer(snapshot2, (char *) real_area2 + pointer_align, process_index); if (addr_pointed1 > process->maestro_stack_start && addr_pointed1 < process->maestro_stack_end @@ -870,7 +870,7 @@ static int compare_heap_area_without_type(struct s_mc_diff *state, int process_i * @return 0 (same), 1 (different), -1 (unknown) */ static int compare_heap_area_with_type(struct s_mc_diff *state, int process_index, - void *real_area1, void *real_area2, + const void *real_area1, const void *real_area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, dw_type_t type, @@ -895,7 +895,7 @@ top: int res, elm_size, i; unsigned int cursor = 0; dw_type_t member; - void *addr_pointed1, *addr_pointed2;; + const void *addr_pointed1, *addr_pointed2;; mc_mem_region_t heap_region1 = MC_get_heap_region(snapshot1); mc_mem_region_t heap_region2 = MC_get_heap_region(snapshot2); @@ -909,12 +909,12 @@ top: if (real_area1 == real_area2) return -1; else - return (mc_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, area_size) != 0); + 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); + return (MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0); } } break; @@ -922,7 +922,7 @@ top: 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); + return (MC_snapshot_region_memcmp(real_area1, heap_region1, real_area2, heap_region2, type->byte_size) != 0); break; case DW_TAG_typedef: case DW_TAG_const_type: @@ -979,15 +979,15 @@ top: case DW_TAG_rvalue_reference_type: case DW_TAG_pointer_type: if (type->subtype && type->subtype->type == DW_TAG_subroutine_type) { - addr_pointed1 = mc_snapshot_read_pointer(real_area1, snapshot1, process_index); - addr_pointed2 = mc_snapshot_read_pointer(real_area2, snapshot2, process_index); + addr_pointed1 = MC_snapshot_read_pointer(snapshot1, real_area1, process_index); + addr_pointed2 = MC_snapshot_read_pointer(snapshot2, real_area2, process_index); return (addr_pointed1 != addr_pointed2);; } else { pointer_level++; if (pointer_level > 1) { /* Array of pointers */ for (i = 0; i < (area_size / sizeof(void *)); i++) { - addr_pointed1 = mc_snapshot_read_pointer((char*) real_area1 + i * sizeof(void *), snapshot1, process_index); - addr_pointed2 = mc_snapshot_read_pointer((char*) real_area2 + i * sizeof(void *), snapshot2, process_index); + addr_pointed1 = MC_snapshot_read_pointer(snapshot1, (char*) real_area1 + i * sizeof(void *), process_index); + addr_pointed2 = MC_snapshot_read_pointer(snapshot2, (char*) real_area2 + i * sizeof(void *), process_index); if (addr_pointed1 > state->s_heap && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1) && addr_pointed2 > state->s_heap @@ -1002,8 +1002,8 @@ top: return res; } } else { - addr_pointed1 = mc_snapshot_read_pointer(real_area1, snapshot1, process_index); - addr_pointed2 = mc_snapshot_read_pointer(real_area2, snapshot2, process_index); + addr_pointed1 = MC_snapshot_read_pointer(snapshot1, real_area1, process_index); + addr_pointed2 = MC_snapshot_read_pointer(snapshot2, real_area2, process_index); if (addr_pointed1 > state->s_heap && addr_pointed1 < mc_snapshot_get_heap_end(snapshot1) && addr_pointed2 > state->s_heap @@ -1040,9 +1040,9 @@ top: xbt_dynar_foreach(type->members, cursor, member) { // TODO, optimize this? (for the offset case) char *real_member1 = - mc_member_resolve(real_area1, type, member, snapshot1, process_index); + mc_member_resolve(real_area1, type, member, (mc_address_space_t) snapshot1, process_index); char *real_member2 = - mc_member_resolve(real_area2, type, member, snapshot2, process_index); + mc_member_resolve(real_area2, type, member, (mc_address_space_t) snapshot2, process_index); res = compare_heap_area_with_type(state, process_index, real_member1, real_member2, snapshot1, snapshot2, @@ -1108,7 +1108,7 @@ static dw_type_t get_offset_type(void *real_base_address, dw_type_t type, return member->subtype; } else { char *real_member = - mc_member_resolve(real_base_address, type, member, snapshot, process_index); + mc_member_resolve(real_base_address, type, member, (mc_address_space_t) snapshot, process_index); if (real_member - (char *) real_base_address == offset) return member->subtype; } @@ -1135,7 +1135,7 @@ static dw_type_t get_offset_type(void *real_base_address, dw_type_t type, * @param pointer_level * @return 0 (same), 1 (different), -1 */ -int compare_heap_area(int process_index, void *area1, void *area2, mc_snapshot_t snapshot1, +int compare_heap_area(int process_index, const void *area1, const void *area2, mc_snapshot_t snapshot1, mc_snapshot_t snapshot2, xbt_dynar_t previous, dw_type_t type, int pointer_level) { @@ -1159,8 +1159,8 @@ int compare_heap_area(int process_index, void *area1, void *area2, mc_snapshot_t // This is the address of std_heap->heapinfo in the application process: void* heapinfo_address = &((xbt_mheap_t) process->heap_address)->heapinfo; - malloc_info* heapinfos1 = mc_snapshot_read_pointer(heapinfo_address, snapshot1, process_index); - malloc_info* heapinfos2 = mc_snapshot_read_pointer(heapinfo_address, snapshot2, process_index); + const malloc_info* heapinfos1 = MC_snapshot_read_pointer(snapshot1, heapinfo_address, process_index); + const malloc_info* heapinfos2 = MC_snapshot_read_pointer(snapshot2, heapinfo_address, process_index); malloc_info heapinfo_temp1, heapinfo_temp2; @@ -1227,8 +1227,8 @@ int compare_heap_area(int process_index, void *area1, void *area2, mc_snapshot_t mc_mem_region_t heap_region1 = MC_get_heap_region(snapshot1); mc_mem_region_t heap_region2 = MC_get_heap_region(snapshot2); - malloc_info* heapinfo1 = mc_snapshot_read_region(&heapinfos1[block1], heap_region1, &heapinfo_temp1, sizeof(malloc_info)); - malloc_info* heapinfo2 = mc_snapshot_read_region(&heapinfos2[block2], heap_region2, &heapinfo_temp2, sizeof(malloc_info)); + const malloc_info* heapinfo1 = MC_region_read(heap_region1, &heapinfo_temp1, &heapinfos1[block1], sizeof(malloc_info)); + const malloc_info* heapinfo2 = MC_region_read(heap_region2, &heapinfo_temp2, &heapinfos2[block2], sizeof(malloc_info)); if ((heapinfo1->type == MMALLOC_TYPE_FREE || heapinfo1->type==MMALLOC_TYPE_HEAPINFO) && (heapinfo2->type == MMALLOC_TYPE_FREE || heapinfo2->type ==MMALLOC_TYPE_HEAPINFO)) { diff --git a/src/mc/mc_dwarf_expression.c b/src/mc/mc_dwarf_expression.c index 9fc2507cc2..92e4e47bfc 100644 --- a/src/mc/mc_dwarf_expression.c +++ b/src/mc/mc_dwarf_expression.c @@ -11,7 +11,6 @@ #include #include "mc_object_info.h" -#include "mc_snapshot.h" #include "mc_private.h" static int mc_dwarf_push_value(mc_expression_state_t state, Dwarf_Off value) @@ -400,9 +399,19 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, { // Computed address: uintptr_t address = (uintptr_t) state->stack[state->stack_size - 1]; - uintptr_t temp; - uintptr_t* res = (uintptr_t*) mc_snapshot_read((void*) address, state->snapshot, state->process_index, &temp, sizeof(uintptr_t)); - state->stack[state->stack_size - 1] = *res; + uintptr_t value; + if (state->address_space) { + uintptr_t temp; + const uintptr_t* res = (uintptr_t*) MC_address_space_read( + state->address_space, MC_ADDRESS_SPACE_READ_FLAGS_LAZY, + &temp, (const void*) address, sizeof(uintptr_t), state->process_index); + value = *res; + } + else { + // TODO, use a mc_process representing the current process instead of this + value = *(const uintptr_t*) address; + } + state->stack[state->stack_size - 1] = value; } break; @@ -427,13 +436,13 @@ void mc_dwarf_resolve_location(mc_location_t location, mc_object_info_t object_info, unw_cursor_t * c, void *frame_pointer_address, - mc_snapshot_t snapshot, int process_index) + mc_address_space_t address_space, int process_index) { s_mc_expression_state_t state; memset(&state, 0, sizeof(s_mc_expression_state_t)); state.frame_base = frame_pointer_address; state.cursor = c; - state.snapshot = snapshot; + state.address_space = address_space; state.object_info = object_info; state.process_index = process_index; @@ -476,7 +485,7 @@ void mc_dwarf_resolve_locations(mc_location_t location, mc_object_info_t object_info, unw_cursor_t * c, void *frame_pointer_address, - mc_snapshot_t snapshot, int process_index) + mc_address_space_t address_space, int process_index) { unw_word_t ip = 0; @@ -489,7 +498,7 @@ void mc_dwarf_resolve_locations(mc_location_t location, if (expression) { mc_dwarf_resolve_location(location, expression, object_info, c, - frame_pointer_address, snapshot, process_index); + frame_pointer_address, address_space, process_index); } else { xbt_die("Could not resolve location"); } diff --git a/src/mc/mc_location.h b/src/mc/mc_location.h index 45657f4551..c624cf2cf2 100644 --- a/src/mc/mc_location.h +++ b/src/mc/mc_location.h @@ -18,6 +18,7 @@ #include "mc_interface.h" #include "mc_object_info.h" #include "mc_forward.h" +#include "mc_address_space.h" SG_BEGIN_DECL() @@ -76,8 +77,8 @@ enum mc_location_type mc_get_location_type(mc_location_t location) { } } -void mc_dwarf_resolve_location(mc_location_t location, mc_expression_t expression, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot, int process_index); -void mc_dwarf_resolve_locations(mc_location_t location, mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot, int process_index); +void mc_dwarf_resolve_location(mc_location_t location, mc_expression_t expression, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_address_space_t address_space, int process_index); +void mc_dwarf_resolve_locations(mc_location_t location, mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_address_space_t address_space, int process_index); void mc_dwarf_expression_clear(mc_expression_t expression); void mc_dwarf_expression_init(mc_expression_t expression, size_t len, Dwarf_Op* ops); @@ -103,7 +104,7 @@ typedef struct s_mc_expression_state { unw_cursor_t* cursor; void* frame_base; - mc_snapshot_t snapshot; + mc_address_space_t address_space; mc_object_info_t object_info; int process_index; } s_mc_expression_state_t, *mc_expression_state_t; diff --git a/src/mc/mc_member.c b/src/mc/mc_member.c index b5ee0690f0..666a2463a7 100644 --- a/src/mc/mc_member.c +++ b/src/mc/mc_member.c @@ -16,7 +16,7 @@ * @return Process address of the given member of the 'object' struct/class */ void *mc_member_resolve(const void *base, dw_type_t type, dw_type_t member, - mc_snapshot_t snapshot, int process_index) + mc_address_space_t address_space, int process_index) { if (!member->location.size) { return ((char *) base) + member->offset; @@ -26,7 +26,7 @@ void *mc_member_resolve(const void *base, dw_type_t type, dw_type_t member, memset(&state, 0, sizeof(s_mc_expression_state_t)); state.frame_base = NULL; state.cursor = NULL; - state.snapshot = snapshot; + state.address_space = address_space; state.stack_size = 1; state.stack[0] = (uintptr_t) base; state.process_index = process_index; diff --git a/src/mc/mc_mmu.h b/src/mc/mc_mmu.h index 6740829b8c..1fa7423f35 100644 --- a/src/mc/mc_mmu.h +++ b/src/mc/mc_mmu.h @@ -38,7 +38,7 @@ size_t mc_page_count(size_t size) * @return Virtual memory page number of the given address */ static inline __attribute__ ((always_inline)) -size_t mc_page_number(void* base, void* address) +size_t mc_page_number(const void* base, const void* address) { xbt_assert(address>=base, "The address is not in the range"); return ((uintptr_t) address - (uintptr_t) base) >> xbt_pagebits; @@ -50,7 +50,7 @@ size_t mc_page_number(void* base, void* address) * @return Offset within the memory page */ static inline __attribute__ ((always_inline)) -size_t mc_page_offset(void* address) +size_t mc_page_offset(const void* address) { return ((uintptr_t) address) & (xbt_pagesize-1); } @@ -61,13 +61,13 @@ size_t mc_page_offset(void* address) * @param page Index of the page */ static inline __attribute__ ((always_inline)) -void* mc_page_from_number(void* base, size_t page) +void* mc_page_from_number(const void* base, size_t page) { return (void*) ((char*)base + (page << xbt_pagebits)); } static inline __attribute__ ((always_inline)) -bool mc_same_page(void* a, void* b) +bool mc_same_page(const void* a, const void* b) { return ((uintptr_t) a >> xbt_pagebits) == ((uintptr_t) b >> xbt_pagebits); } diff --git a/src/mc/mc_object_info.h b/src/mc/mc_object_info.h index cd46859375..f3b9cd4647 100644 --- a/src/mc/mc_object_info.h +++ b/src/mc/mc_object_info.h @@ -1,4 +1,4 @@ - /* Copyright (c) 2007-2014. The SimGrid Team. +/* Copyright (c) 2007-2014. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -112,7 +112,7 @@ const char* MC_dwarf_tagname(int tag); // Not used: char* get_type_description(mc_object_info_t info, char *type_name); -void* mc_member_resolve(const void* base, dw_type_t type, dw_type_t member, mc_snapshot_t snapshot, int process_index); +void* mc_member_resolve(const void* base, dw_type_t type, dw_type_t member, mc_address_space_t snapshot, int process_index); struct s_dw_variable{ Dwarf_Off dwarf_offset; /* Global offset of the field. */ diff --git a/src/mc/mc_page_snapshot.cpp b/src/mc/mc_page_snapshot.cpp index aec83aa0f2..16c85084ac 100644 --- a/src/mc/mc_page_snapshot.cpp +++ b/src/mc/mc_page_snapshot.cpp @@ -56,7 +56,8 @@ size_t* mc_take_page_snapshot_region(mc_process_t process, - move the segments in shared memory (this will break `fork` however). */ page_data = temp; - MC_process_read(process, temp, page, xbt_pagesize); + MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, + temp, page, xbt_pagesize, MC_PROCESS_INDEX_DISABLED); } pagenos[i] = mc_model_checker->pages->store_page(page_data); } diff --git a/src/mc/mc_process.c b/src/mc/mc_process.c index ada619562e..23774b570f 100644 --- a/src/mc/mc_process.c +++ b/src/mc/mc_process.c @@ -14,6 +14,7 @@ #include "mc_process.h" #include "mc_object_info.h" +#include "mc_address_space.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information"); @@ -21,9 +22,13 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, static void MC_process_init_memory_map_info(mc_process_t process); static void MC_process_open_memory_file(mc_process_t process); +static s_mc_address_space_class_t mc_process_class = { + .read = (void*) &MC_process_read +}; void MC_process_init(mc_process_t process, pid_t pid) { + process->address_space.address_space_class = &mc_process_class; process->process_flags = MC_PROCESS_NO_FLAG; process->pid = pid; if (pid==getpid()) @@ -42,12 +47,14 @@ void MC_process_init(mc_process_t process, pid_t pid) xbt_die("No heap information in the target process"); if(!std_heap_var->address) xbt_die("No constant address for this variable"); - MC_process_read(process, &process->heap_address, - std_heap_var->address, sizeof(struct mdesc*)); + MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, + &process->heap_address, std_heap_var->address, sizeof(struct mdesc*), + MC_PROCESS_INDEX_DISABLED); } void MC_process_clear(mc_process_t process) { + process->address_space.address_space_class = NULL; process->process_flags = MC_PROCESS_NO_FLAG; process->pid = 0; @@ -87,8 +94,10 @@ void MC_process_refresh_heap(mc_process_t process) process->heap = malloc(sizeof(struct mdesc)); mmalloc_set_current_heap(oldheap); } - MC_process_read(process, process->heap, - process->heap_address, sizeof(struct mdesc)); + MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, + process->heap, process->heap_address, sizeof(struct mdesc), + MC_PROCESS_INDEX_DISABLED + ); } void MC_process_refresh_malloc_info(mc_process_t process) @@ -105,8 +114,10 @@ void MC_process_refresh_malloc_info(mc_process_t process) malloc_info_bytesize); mmalloc_set_current_heap(oldheap); - MC_process_read(process, process->heap_info, - process->heap->heapinfo, malloc_info_bytesize); + MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, + process->heap_info, + process->heap->heapinfo, malloc_info_bytesize, + MC_PROCESS_INDEX_DISABLED); } #define SO_RE "\\.so[\\.0-9]*$" @@ -354,13 +365,24 @@ static ssize_t pwrite_whole(int fd, const void *buf, size_t count, off_t offset) return real_count; } -void MC_process_read(mc_process_t process, void* local, const void* remote, size_t len) +const void* MC_process_read(mc_process_t process, e_adress_space_read_flags_t flags, + void* local, const void* remote, size_t len, + int process_index) { + if (process_index != MC_PROCESS_INDEX_DISABLED) + xbt_die("Not implemented yet"); + if (MC_process_is_self(process)) { - memcpy(local, remote, len); + if (flags & MC_ADDRESS_SPACE_READ_FLAGS_LAZY) + return remote; + else { + memcpy(local, remote, len); + return local; + } } else { if (pread_whole(process->memory_file, local, len, (off_t) remote) < 0) xbt_die("Read from process %lli failed", (long long) process->pid); + return local; } } diff --git a/src/mc/mc_process.h b/src/mc/mc_process.h index 4513fe280d..05ba9b0a11 100644 --- a/src/mc/mc_process.h +++ b/src/mc/mc_process.h @@ -21,6 +21,7 @@ #include "mc_forward.h" #include "mc_mmalloc.h" // std_heap #include "mc_memory_map.h" +#include "mc_address_space.h" SG_BEGIN_DECL() @@ -39,6 +40,7 @@ typedef enum { /** Representation of a process */ struct s_mc_process { + s_mc_address_space_t address_space; e_mc_process_flags_t process_flags; pid_t pid; memory_map_t memory_map; @@ -107,7 +109,10 @@ bool MC_process_is_self(mc_process_t process) * @param remote target process memory address (source) * @param len data size */ -void MC_process_read(mc_process_t process, void* local, const void* remote, size_t len); +const void* MC_process_read(mc_process_t process, + e_adress_space_read_flags_t flags, + void* local, const void* remote, size_t len, + int process_index); /** Write data to a process memory * diff --git a/src/mc/mc_snapshot.c b/src/mc/mc_snapshot.c index 5746848cd4..0a4f4f564d 100644 --- a/src/mc/mc_snapshot.c +++ b/src/mc/mc_snapshot.c @@ -21,7 +21,7 @@ * @param Snapshot region in the snapshot this pointer belongs to * (or NULL if it does not belong to any snapshot region) * */ -mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot, int process_index) +mc_mem_region_t mc_get_snapshot_region(const void* addr, mc_snapshot_t snapshot, int process_index) { size_t n = snapshot->snapshot_regions_count; for (size_t i = 0; i != n; ++i) { @@ -31,6 +31,10 @@ mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot, int p if (region->storage_type == MC_REGION_STORAGE_TYPE_PRIVATIZED) { #ifdef HAVE_SMPI + // Use the current process index of the snapshot: + if (process_index == MC_PROCESS_INDEX_DISABLED) { + process_index = snapshot->privatization_index; + } if (process_index < 0) { xbt_die("Missing process index"); } @@ -59,7 +63,7 @@ mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot, int p * @param size Size of the data to read in bytes * @return Pointer where the data is located (target buffer of original location) */ -void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* target, size_t size) +const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, const void* addr, size_t size) { // Last byte of the memory area: void* end = (char*) addr + size - 1; @@ -99,14 +103,15 @@ void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* targ * @param size Size of the data to read in bytes * @return Pointer where the data is located (target buffer or original location) */ -void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, int process_index, void* target, size_t size) +const void* MC_snapshot_read( + mc_snapshot_t snapshot, e_adress_space_read_flags_t flags, + void* target, const void* addr, size_t size, int process_index) { - if (snapshot) { - mc_mem_region_t region = mc_get_snapshot_region(addr, snapshot, process_index); - return mc_snapshot_read_region(addr, region, target, size); - } else { - return addr; - } + mc_mem_region_t region = mc_get_snapshot_region(addr, snapshot, process_index); + if (region) + return MC_region_read(region, target, addr, size); + else + return MC_process_read(snapshot->process, flags, target, addr, size, process_index); } /** Compare memory between snapshots (with known regions) @@ -117,9 +122,9 @@ void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, int process_index, vo * @param snapshot2 Region of the address in the second snapshot * @return same as memcmp * */ -int mc_snapshot_region_memcmp( - void* addr1, mc_mem_region_t region1, - void* addr2, mc_mem_region_t region2, +int MC_snapshot_region_memcmp( + const void* addr1, mc_mem_region_t region1, + const void* addr2, mc_mem_region_t region2, size_t size) { // Using alloca() for large allocations may trigger stack overflow: @@ -129,8 +134,8 @@ int mc_snapshot_region_memcmp( const bool region2_need_buffer = region2==NULL || region2->storage_type==MC_REGION_STORAGE_TYPE_FLAT; void* buffer1a = region1_need_buffer ? NULL : stack_alloc ? alloca(size) : malloc(size); void* buffer2a = region2_need_buffer ? NULL : stack_alloc ? alloca(size) : malloc(size); - void* buffer1 = mc_snapshot_read_region(addr1, region1, buffer1a, size); - void* buffer2 = mc_snapshot_read_region(addr2, region2, buffer2a, size); + const void* buffer1 = MC_region_read(region1, buffer1a, addr1, size); + const void* buffer2 = MC_region_read(region2, buffer2a, addr2, size); int res; if (buffer1 == buffer2) { res = 0; @@ -152,13 +157,13 @@ int mc_snapshot_region_memcmp( * @param snapshot2 Second snapshot * @return same as memcmp * */ -int mc_snapshot_memcmp( - void* addr1, mc_snapshot_t snapshot1, - void* addr2, mc_snapshot_t snapshot2, int process_index, size_t size) +int MC_snapshot_memcmp( + const void* addr1, mc_snapshot_t snapshot1, + const void* addr2, mc_snapshot_t snapshot2, int process_index, size_t size) { mc_mem_region_t region1 = mc_get_snapshot_region(addr1, snapshot1, process_index); mc_mem_region_t region2 = mc_get_snapshot_region(addr2, snapshot2, process_index); - return mc_snapshot_region_memcmp(addr1, region1, addr2, region2, size); + return MC_snapshot_region_memcmp(addr1, region1, addr2, region2, size); } #ifdef SIMGRID_TEST @@ -225,46 +230,46 @@ static void test_snapshot(bool sparse_checkpoint) { xbt_assert(source!=MAP_FAILED, "Could not allocate destination memory"); xbt_test_add("Reading whole region data for %i page(s)", n); - void* read = mc_snapshot_read_region(source, region, destination, byte_size); - xbt_test_assert(!memcmp(source, read, byte_size), "Mismatch in mc_snapshot_read_region()"); + const void* read = MC_region_read(region, source, destination, byte_size); + xbt_test_assert(!memcmp(source, read, byte_size), "Mismatch in MC_region_read()"); xbt_test_add("Reading parts of region data for %i page(s)", n); for(int j=0; j!=100; ++j) { size_t offset = rand() % byte_size; size_t size = rand() % (byte_size - offset); - void* read = mc_snapshot_read_region((char*) source+offset, region, destination, size); + const void* read = MC_region_read(region, destination, (const char*) source+offset, size); xbt_test_assert(!memcmp((char*) source+offset, read, size), - "Mismatch in mc_snapshot_read_region()"); + "Mismatch in MC_region_read()"); } xbt_test_add("Compare whole region data for %i page(s)", n); - xbt_test_assert(!mc_snapshot_region_memcmp(source, NULL, source, region, byte_size), - "Mismatch in mc_snapshot_region_memcmp() for the whole region"); - xbt_test_assert(mc_snapshot_region_memcmp(source, region0, source, region, byte_size), - "Unexpected match in mc_snapshot_region_memcmp() with previous snapshot"); + xbt_test_assert(!MC_snapshot_region_memcmp(source, NULL, source, region, byte_size), + "Mismatch in MC_snapshot_region_memcmp() for the whole region"); + xbt_test_assert(MC_snapshot_region_memcmp(source, region0, source, region, byte_size), + "Unexpected match in MC_snapshot_region_memcmp() with previous snapshot"); xbt_test_add("Compare parts of region data for %i page(s) with current value", n); for(int j=0; j!=100; ++j) { size_t offset = rand() % byte_size; size_t size = rand() % (byte_size - offset); - xbt_test_assert(!mc_snapshot_region_memcmp((char*) source+offset, NULL, (char*) source+offset, region, size), - "Mismatch in mc_snapshot_region_memcmp()"); + xbt_test_assert(!MC_snapshot_region_memcmp((char*) source+offset, NULL, (char*) source+offset, region, size), + "Mismatch in MC_snapshot_region_memcmp()"); } xbt_test_add("Compare parts of region data for %i page(s) with itself", n); for(int j=0; j!=100; ++j) { size_t offset = rand() % byte_size; size_t size = rand() % (byte_size - offset); - xbt_test_assert(!mc_snapshot_region_memcmp((char*) source+offset, region, (char*) source+offset, region, size), - "Mismatch in mc_snapshot_region_memcmp()"); + xbt_test_assert(!MC_snapshot_region_memcmp((char*) source+offset, region, (char*) source+offset, region, size), + "Mismatch in MC_snapshot_region_memcmp()"); } if (n==1) { xbt_test_add("Read pointer for %i page(s)", n); memcpy(source, &mc_model_checker, sizeof(void*)); mc_mem_region_t region2 = mc_region_new_sparse(MC_REGION_TYPE_UNKNOWN, source, source, byte_size, NULL); - xbt_test_assert(mc_snapshot_read_pointer_region(source, region2) == mc_model_checker, - "Mismtach in mc_snapshot_read_pointer_region()"); + xbt_test_assert(MC_region_read_pointer(region2, source) == mc_model_checker, + "Mismtach in MC_region_read_pointer()"); MC_region_destroy(region2); } diff --git a/src/mc/mc_snapshot.h b/src/mc/mc_snapshot.h index e6e0255b4b..e46045f573 100644 --- a/src/mc/mc_snapshot.h +++ b/src/mc/mc_snapshot.h @@ -19,6 +19,7 @@ #include "mc_model_checker.h" #include "mc_page_store.h" #include "mc_mmalloc.h" +#include "mc_address_space.h" SG_BEGIN_DECL() @@ -102,7 +103,7 @@ void MC_region_destroy(mc_mem_region_t reg); void mc_region_restore_sparse(mc_process_t process, mc_mem_region_t reg, mc_mem_region_t ref_reg); static inline __attribute__ ((always_inline)) -bool mc_region_contain(mc_mem_region_t region, void* p) +bool mc_region_contain(mc_mem_region_t region, const void* p) { return p >= region->start_addr && p < (void*)((char*) region->start_addr + region->size); @@ -117,7 +118,7 @@ void* mc_translate_address_region(uintptr_t addr, mc_mem_region_t region) return (char*) snapshot_page + mc_page_offset((void*) addr); } -mc_mem_region_t mc_get_snapshot_region(void* addr, mc_snapshot_t snapshot, int process_index); +mc_mem_region_t mc_get_snapshot_region(const void* addr, mc_snapshot_t snapshot, int process_index); /** \brief Translate a pointer from process address space to snapshot address space * @@ -196,7 +197,9 @@ typedef struct s_fd_infos{ int flags; }s_fd_infos_t, *fd_infos_t; -struct s_mc_snapshot{ +struct s_mc_snapshot { + mc_process_t process; + s_mc_address_space_t address_space; size_t heap_bytes_used; mc_mem_region_t* snapshot_regions; size_t snapshot_regions_count; @@ -211,18 +214,6 @@ struct s_mc_snapshot{ fd_infos_t *current_fd; }; -/** @brief Process index used when no process is available - * - * The expected behaviour is that if a process index is needed it will fail. - * */ -#define MC_NO_PROCESS_INDEX -1 - -/** @brief Process index when any process is suitable - * - * We could use a special negative value in the future. - */ -#define MC_ANY_PROCESS_INDEX 0 - static inline __attribute__ ((always_inline)) mc_mem_region_t mc_get_region_hinted(void* addr, mc_snapshot_t snapshot, int process_index, mc_mem_region_t region) { @@ -252,7 +243,7 @@ typedef struct s_mc_snapshot_stack{ int process_index; }s_mc_snapshot_stack_t, *mc_snapshot_stack_t; -typedef struct s_mc_global_t{ +typedef struct s_mc_global_t { mc_snapshot_t snapshot; int raw_mem_set; int prev_pair; @@ -267,7 +258,7 @@ typedef struct s_mc_checkpoint_ignore_region{ size_t size; }s_mc_checkpoint_ignore_region_t, *mc_checkpoint_ignore_region_t; -static void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot); +static const void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot); mc_snapshot_t MC_take_snapshot(int num_state); void MC_restore_snapshot(mc_snapshot_t); @@ -283,33 +274,34 @@ void mc_restore_page_snapshot_region( void* start_addr, size_t page_count, size_t* pagenos, uint64_t* pagemap, size_t* reference_pagenos); -void* mc_snapshot_read_fragmented(void* addr, mc_mem_region_t region, void* target, size_t size); +const void* MC_region_read_fragmented(mc_mem_region_t region, void* target, const void* addr, size_t size); -void* mc_snapshot_read(void* addr, mc_snapshot_t snapshot, int process_index, void* target, size_t size); -int mc_snapshot_region_memcmp( - void* addr1, mc_mem_region_t region1, - void* addr2, mc_mem_region_t region2, size_t size); -int mc_snapshot_memcmp( - void* addr1, mc_snapshot_t snapshot1, - void* addr2, mc_snapshot_t snapshot2, int process_index, size_t size); - -static void* mc_snapshot_read_pointer(void* addr, mc_snapshot_t snapshot, int process_index); +const void* MC_snapshot_read(mc_snapshot_t snapshot, e_adress_space_read_flags_t flags, + void* target, const void* addr, size_t size, int process_index); +int MC_snapshot_region_memcmp( + const void* addr1, mc_mem_region_t region1, + const void* addr2, mc_mem_region_t region2, size_t size); +int MC_snapshot_memcmp( + const void* addr1, mc_snapshot_t snapshot1, + const void* addr2, mc_snapshot_t snapshot2, int process_index, size_t size); static inline __attribute__ ((always_inline)) -void* mc_snapshot_read_pointer(void* addr, mc_snapshot_t snapshot, int process_index) +const void* MC_snapshot_read_pointer(mc_snapshot_t snapshot, const void* addr, int process_index) { void* res; - return *(void**) mc_snapshot_read(addr, snapshot, process_index, &res, sizeof(void*)); + return *(const void**) MC_snapshot_read(snapshot, MC_ADDRESS_SPACE_READ_FLAGS_LAZY, + &res, addr, sizeof(void*), process_index); } static inline __attribute__ ((always_inline)) -void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot) { +const void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot) +{ if(snapshot==NULL) xbt_die("snapshot is NULL"); // This is &std_heap->breakval in the target process: void** addr = &MC_process_get_heap(&mc_model_checker->process)->breakval; // Read (std_heap->breakval) in the target process (*addr i.e. std_heap->breakval): - return mc_snapshot_read_pointer(addr, snapshot, MC_ANY_PROCESS_INDEX); + return MC_snapshot_read_pointer(snapshot, addr, MC_PROCESS_INDEX_ANY); } /** @brief Read memory from a snapshot region @@ -321,9 +313,10 @@ void* mc_snapshot_get_heap_end(mc_snapshot_t snapshot) { * @return Pointer where the data is located (target buffer of original location) */ static inline __attribute__((always_inline)) -void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, size_t size) +const void* MC_region_read(mc_mem_region_t region, void* target, const void* addr, size_t size) { if (region==NULL) + // Should be deprecated: return addr; uintptr_t offset = (char*) addr - (char*) region->start_addr; @@ -343,12 +336,12 @@ void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, { // Last byte of the region: void* end = (char*) addr + size - 1; - if( mc_same_page(addr, end) ) { + if (mc_same_page(addr, end) ) { // The memory is contained in a single page: return mc_translate_address_region((uintptr_t) addr, region); } else { // The memory spans several pages: - return mc_snapshot_read_fragmented(addr, region, target, size); + return MC_region_read_fragmented(region, target, addr, size); } } @@ -360,10 +353,10 @@ void* mc_snapshot_read_region(void* addr, mc_mem_region_t region, void* target, } static inline __attribute__ ((always_inline)) -void* mc_snapshot_read_pointer_region(void* addr, mc_mem_region_t region) +void* MC_region_read_pointer(mc_mem_region_t region, const void* addr) { void* res; - return *(void**) mc_snapshot_read_region(addr, region, &res, sizeof(void*)); + return *(void**) MC_region_read(region, &res, addr, sizeof(void*)); } SG_END_DECL() -- 2.20.1