X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/95bcda88a7fcfa168381cba0eedadb1e4937d0b3..e7c2b72c7328c4aade5049a3cc21603a9d27842c:/src/mc/mc_process.c diff --git a/src/mc/mc_process.c b/src/mc/mc_process.c index 0beaf82fac..e49a7e23dc 100644 --- a/src/mc/mc_process.c +++ b/src/mc/mc_process.c @@ -25,8 +25,8 @@ #include "mc_unw.h" #include "mc_snapshot.h" #include "mc_ignore.h" - -#include "simix/smx_private.h" +#include "mc_smx.h" +#include "mc_server.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information"); @@ -82,8 +82,8 @@ void MC_process_init(mc_process_t process, pid_t pid, int sockfd) &process->heap_address, std_heap_var->address, sizeof(struct mdesc*), MC_PROCESS_INDEX_DISABLED); - process->smx_process_infos = mc_smx_process_info_list_new(); - process->smx_old_process_infos = mc_smx_process_info_list_new(); + process->smx_process_infos = MC_smx_process_info_list_new(); + process->smx_old_process_infos = MC_smx_process_info_list_new(); process->checkpoint_ignore = MC_checkpoint_ignore_new(); @@ -162,14 +162,14 @@ void MC_process_refresh_heap(mc_process_t process) void MC_process_refresh_malloc_info(mc_process_t process) { assert(!MC_process_is_self(process)); - if (!process->cache_flags & MC_PROCESS_CACHE_FLAG_HEAP) + if (!(process->cache_flags & MC_PROCESS_CACHE_FLAG_HEAP)) MC_process_refresh_heap(process); // Refresh process->heapinfo: - size_t malloc_info_bytesize = process->heap->heaplimit * sizeof(malloc_info); + size_t malloc_info_bytesize = + (process->heap->heaplimit + 1) * sizeof(malloc_info); xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap); - process->heap_info = (malloc_info*) realloc(process->heap_info, - malloc_info_bytesize); + process->heap_info = realloc(process->heap_info, malloc_info_bytesize); mmalloc_set_current_heap(heap); MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, @@ -178,66 +178,6 @@ void MC_process_refresh_malloc_info(mc_process_t process) MC_PROCESS_INDEX_DISABLED); } -/** Load the remote swag of processes into a dynar - * - * @param process MCed process - * @param target Local dynar (to be filled with copies of `s_smx_process_t`) - * @param remote_swag Address of the process SWAG in the remote list - */ -static void MC_process_refresh_simix_process_list( - mc_process_t process, - xbt_dynar_t target, xbt_swag_t remote_swag) -{ - // swag = REMOTE(*simix_global->process_list) - s_xbt_swag_t swag; - MC_process_read(process, MC_PROCESS_NO_FLAG, &swag, remote_swag, sizeof(swag), - MC_PROCESS_INDEX_ANY); - - smx_process_t p; - xbt_dynar_reset(target); - - int i = 0; - for (p = swag.head; p; ++i) { - - s_mc_smx_process_info_t info; - info.address = p; - MC_process_read(process, MC_PROCESS_NO_FLAG, - &info.copy, p, sizeof(info.copy), MC_PROCESS_INDEX_ANY); - xbt_dynar_push(target, &info); - - // Lookup next process address: - p = xbt_swag_getNext(&info.copy, swag.offset); - } - assert(i == swag.count); -} - -void MC_process_refresh_simix_processes(mc_process_t process) -{ - if (process->cache_flags & MC_PROCESS_CACHE_FLAG_SIMIX_PROCESSES) - return; - - xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap); - - // TODO, avoid to reload `&simix_global`, `simix_global`, `*simix_global` - - // simix_global_p = REMOTE(simix_global); - smx_global_t simix_global_p; - MC_process_read_variable(process, "simix_global", &simix_global_p, sizeof(simix_global_p)); - - // simix_global = REMOTE(*simix_global) - s_smx_global_t simix_global; - MC_process_read(process, MC_PROCESS_NO_FLAG, &simix_global, simix_global_p, sizeof(simix_global), - MC_PROCESS_INDEX_ANY); - - MC_process_refresh_simix_process_list( - process, process->smx_process_infos, simix_global.process_list); - MC_process_refresh_simix_process_list( - process, process->smx_old_process_infos, simix_global.process_to_destroy); - - process->cache_flags |= MC_PROCESS_CACHE_FLAG_SIMIX_PROCESSES; - mmalloc_set_current_heap(heap); -} - #define SO_RE "\\.so[\\.0-9]*$" #define VERSION_RE "-[\\.0-9]*$" @@ -466,10 +406,49 @@ void MC_process_read_variable(mc_process_t process, const char* name, void* targ dw_variable_t var = MC_process_find_variable_by_name(process, name); if (!var->address) xbt_die("No simple location for this variable"); + if (!var->type->full_type) + xbt_die("Partial type for %s, cannot check size", name); + if (var->type->full_type->byte_size != size) + xbt_die("Unexpected size for %s (expected %zi, was %zi)", + name, size, (size_t) var->type->full_type->byte_size); MC_process_read(process, MC_PROCESS_NO_FLAG, target, var->address, size, MC_PROCESS_INDEX_ANY); } +char* MC_process_read_string(mc_process_t process, void* address) +{ + if (!address) + return NULL; + if (MC_process_is_self(process)) + return strdup((char*) address); + + size_t len = 128; + char* res = malloc(len); + off_t off = 0; + + while (1) { + ssize_t c = pread(process->memory_file, res + off, len - off, (off_t) address + off); + if (c == -1) { + if (errno == EINTR) + continue; + else + xbt_die("Could not read from from remote process"); + } + if (c==0) + xbt_die("Could not read string from remote process"); + + void* p = memchr(res + off, '\0', c); + if (p) + return res; + + off += c; + if (off == len) { + len *= 2; + res = realloc(res, len); + } + } +} + // ***** Memory access int MC_process_vm_open(pid_t pid, int flags) @@ -563,6 +542,28 @@ const void* MC_process_read(mc_process_t process, e_adress_space_read_flags_t fl } } +const void* MC_process_read_simple(mc_process_t process, + void* local, const void* remote, size_t len) +{ + e_adress_space_read_flags_t flags = MC_PROCESS_NO_FLAG; + int index = MC_PROCESS_INDEX_ANY; + MC_process_read(process, flags, local, remote, len, index); + return local; +} + +const void* MC_process_read_dynar_element(mc_process_t process, + void* local, const void* remote_dynar, size_t i, size_t len) +{ + s_xbt_dynar_t d; + MC_process_read_simple(process, &d, remote_dynar, sizeof(d)); + if (i >= d.used) + xbt_die("Out of bound index %zi/%zi", i, d.used); + if (len != d.elmsize) + xbt_die("Bad size in MC_process_read_dynar_element"); + MC_process_read_simple(process, local, xbt_dynar_get_ptr(&d, i), len); + return local; +} + void MC_process_write(mc_process_t process, const void* local, void* remote, size_t len) { if (MC_process_is_self(process)) { @@ -573,6 +574,16 @@ void MC_process_write(mc_process_t process, const void* local, void* remote, siz } } +unsigned long MC_process_read_dynar_length(mc_process_t process, const void* remote_dynar) +{ + if (!remote_dynar) + return 0; + unsigned long res; + MC_process_read_simple(process, &res, + &((xbt_dynar_t)remote_dynar)->used, sizeof(res)); + return res; +} + static pthread_once_t zero_buffer_flag = PTHREAD_ONCE_INIT; static const void* zero_buffer; static const int zero_buffer_size = 10 * 4096; @@ -603,38 +614,6 @@ void MC_process_clear_memory(mc_process_t process, void* remote, size_t len) } } -/** Get the issuer of a simcall (`req->issuer`) - * - * In split-process mode, it does the black magic necessary to get an address - * of a (shallow) copy of the data structure the issuer SIMIX process in the local - * address space. - * - * @param process the MCed process - * @param req the simcall (copied in the local process) - */ -smx_process_t MC_process_get_issuer(mc_process_t process, smx_simcall_t req) -{ - if (MC_process_is_self(&mc_model_checker->process)) - return req->issuer; - - MC_process_refresh_simix_processes(process); - - // This is the address of the smx_process in the MCed process: - void* address = req->issuer; - - unsigned i; - mc_smx_process_info_t p; - - xbt_dynar_foreach_ptr(process->smx_process_infos, i, p) - if (p->address == address) - return &p->copy; - xbt_dynar_foreach_ptr(process->smx_old_process_infos, i, p) - if (p->address == address) - return &p->copy; - - xbt_die("Issuer not found"); -} - void MC_simcall_handle(smx_simcall_t req, int value) { if (MC_process_is_self(&mc_model_checker->process)) { @@ -642,32 +621,15 @@ void MC_simcall_handle(smx_simcall_t req, int value) return; } - MC_process_refresh_simix_processes(&mc_model_checker->process); - unsigned i; mc_smx_process_info_t pi = NULL; xbt_dynar_foreach_ptr(mc_model_checker->process.smx_process_infos, i, pi) { - smx_process_t p = (smx_process_t) pi->address; if (req == &pi->copy.simcall) { - smx_simcall_t real_req = &p->simcall; - // TODO, use a remote call - SIMIX_simcall_handle(real_req, value); + MC_server_simcall_handle(&mc_model_checker->process, pi->copy.pid, value); return; } } - // Check (remove afterwards): - xbt_dynar_foreach_ptr(mc_model_checker->process.smx_process_infos, i, pi) { - smx_process_t p = (smx_process_t) pi->address; - if (req == &p->simcall) - xbt_die("The real simcall was passed. We expected the local copy."); - } - xbt_die("Could not find the request"); } - -void mc_smx_process_info_clear(mc_smx_process_info_t p) -{ - // Nothing yet -}