X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2e3c0670f37a0c37487fc75c73956290dc086c50..02f267e2895f3985fe73344a8b96ac05363b8b62:/src/mc/mc_process.c diff --git a/src/mc/mc_process.c b/src/mc/mc_process.c index 23774b570f..10d0a45d6e 100644 --- a/src/mc/mc_process.c +++ b/src/mc/mc_process.c @@ -10,11 +10,19 @@ #include #include // PROT_* +#include + #include +#include +#include + #include "mc_process.h" #include "mc_object_info.h" #include "mc_address_space.h" +#include "mc_unw.h" +#include "mc_snapshot.h" +#include "mc_ignore.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information"); @@ -22,17 +30,36 @@ 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 +// ***** Destructor callbacks + +// ***** mc_address_space methods for mc_process + +static mc_process_t MC_process_get_process(mc_process_t p) { + return p; +} + +static const s_mc_address_space_class_t mc_process_class = { + .read = (void*) &MC_process_read, + .get_process = (void*) MC_process_get_process }; -void MC_process_init(mc_process_t process, pid_t pid) +bool MC_is_process(mc_address_space_t p) +{ + return p->address_space_class == &mc_process_class; +} + +// ***** mc_process + +void MC_process_init(mc_process_t process, pid_t pid, int sockfd) { process->address_space.address_space_class = &mc_process_class; process->process_flags = MC_PROCESS_NO_FLAG; + process->socket = sockfd; process->pid = pid; if (pid==getpid()) process->process_flags |= MC_PROCESS_SELF_FLAG; + process->running = true; + process->status = 0; process->memory_map = MC_get_memory_map(pid); process->memory_file = -1; process->cache_flags = 0; @@ -50,6 +77,17 @@ void MC_process_init(mc_process_t process, pid_t pid) MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE, &process->heap_address, std_heap_var->address, sizeof(struct mdesc*), MC_PROCESS_INDEX_DISABLED); + + process->checkpoint_ignore = MC_checkpoint_ignore_new(); + + process->unw_addr_space = unw_create_addr_space(&mc_unw_accessors , __BYTE_ORDER); + if (process->process_flags & MC_PROCESS_SELF_FLAG) { + process->unw_underlying_addr_space = unw_local_addr_space; + process->unw_underlying_context = NULL; + } else { + process->unw_underlying_addr_space = unw_create_addr_space(&mc_unw_vmread_accessors, __BYTE_ORDER); + process->unw_underlying_context = _UPT_create(pid); + } } void MC_process_clear(mc_process_t process) @@ -64,6 +102,8 @@ void MC_process_clear(mc_process_t process) process->maestro_stack_start = NULL; process->maestro_stack_end = NULL; + xbt_dynar_free(&process->checkpoint_ignore); + size_t i; for (i=0; i!=process->object_infos_size; ++i) { MC_free_object_info(&process->object_infos[i]); @@ -75,6 +115,16 @@ void MC_process_clear(mc_process_t process) close(process->memory_file); } + if (process->unw_underlying_addr_space != unw_local_addr_space) { + unw_destroy_addr_space(process->unw_underlying_addr_space); + _UPT_destroy(process->unw_underlying_context); + } + process->unw_underlying_context = NULL; + process->unw_underlying_addr_space = NULL; + + unw_destroy_addr_space(process->unw_addr_space); + process->unw_addr_space = NULL; + process->cache_flags = 0; free(process->heap); @@ -132,6 +182,7 @@ const char* FILTERED_LIBS[] = { "libunwind", "libunwind-x86_64", "libunwind-x86", + "libunwind-ptrace", "libdw", "libdl", "librt", @@ -186,7 +237,7 @@ static char* MC_get_lib_name(const char* pathname, struct s_mc_memory_map_re* re /** @brief Finds the range of the different memory segments and binary paths */ static void MC_process_init_memory_map_info(mc_process_t process) { - XBT_INFO("Get debug information ..."); + XBT_DEBUG("Get debug information ..."); process->maestro_stack_start = NULL; process->maestro_stack_end = NULL; process->object_infos = NULL; @@ -263,18 +314,42 @@ static void MC_process_init_memory_map_info(mc_process_t process) for (i=0; i!=process->object_infos_size; ++i) MC_post_process_object_info(process, process->object_infos[i]); - xbt_assert(process->maestro_stack_start, "maestro_stack_start"); - xbt_assert(process->maestro_stack_end, "maestro_stack_end"); + xbt_assert(process->maestro_stack_start, "Did not find maestro_stack_start"); + xbt_assert(process->maestro_stack_end, "Did not find maestro_stack_end"); - XBT_INFO("Get debug information done !"); + XBT_DEBUG("Get debug information done !"); } -mc_object_info_t MC_process_find_object_info(mc_process_t process, void *ip) +mc_object_info_t MC_process_find_object_info(mc_process_t process, const void *addr) { size_t i; for (i = 0; i != process->object_infos_size; ++i) { - if (ip >= (void *) process->object_infos[i]->start_exec - && ip <= (void *) process->object_infos[i]->end_exec) { + if (addr >= (void *) process->object_infos[i]->start + && addr <= (void *) process->object_infos[i]->end) { + return process->object_infos[i]; + } + } + return NULL; +} + +mc_object_info_t MC_process_find_object_info_exec(mc_process_t process, const void *addr) +{ + size_t i; + for (i = 0; i != process->object_infos_size; ++i) { + if (addr >= (void *) process->object_infos[i]->start_exec + && addr <= (void *) process->object_infos[i]->end_exec) { + return process->object_infos[i]; + } + } + return NULL; +} + +mc_object_info_t MC_process_find_object_info_rw(mc_process_t process, const void *addr) +{ + size_t i; + for (i = 0; i != process->object_infos_size; ++i) { + if (addr >= (void *) process->object_infos[i]->start_rw + && addr <= (void *) process->object_infos[i]->end_rw) { return process->object_infos[i]; } } @@ -283,9 +358,9 @@ mc_object_info_t MC_process_find_object_info(mc_process_t process, void *ip) // Functions, variables… -dw_frame_t MC_process_find_function(mc_process_t process, void *ip) +dw_frame_t MC_process_find_function(mc_process_t process, const void *ip) { - mc_object_info_t info = MC_process_find_object_info(process, ip); + mc_object_info_t info = MC_process_find_object_info_exec(process, ip); if (info == NULL) return NULL; else @@ -307,23 +382,26 @@ dw_variable_t MC_process_find_variable_by_name(mc_process_t process, const char* // ***** Memory access -static void MC_process_open_memory_file(mc_process_t process) +int MC_process_vm_open(pid_t pid, int flags) { - if (MC_process_is_self(process) || process->memory_file >= 0) - return; - const size_t buffer_size = 30; char buffer[buffer_size]; - int res = snprintf(buffer, buffer_size, "/proc/%lli/mem", (long long) process->pid); - if (res < 0 || res>= buffer_size) { - XBT_ERROR("Could not open memory file descriptor for process %lli", - (long long) process->pid); - return; + int res = snprintf(buffer, buffer_size, "/proc/%lli/mem", (long long) pid); + if (res < 0 || res >= buffer_size) { + errno = ENAMETOOLONG; + return -1; } + return open(buffer, flags); +} + +static void MC_process_open_memory_file(mc_process_t process) +{ + if (MC_process_is_self(process) || process->memory_file >= 0) + return; - int fd = open(buffer, O_RDWR); + int fd = MC_process_vm_open(process->pid, O_RDWR); if (fd<0) - xbt_die("Could not initialise memory access for remote process"); + xbt_die("Could not open file for process virtual address space"); process->memory_file = fd; } @@ -369,8 +447,17 @@ const void* MC_process_read(mc_process_t process, e_adress_space_read_flags_t fl void* local, const void* remote, size_t len, int process_index) { - if (process_index != MC_PROCESS_INDEX_DISABLED) - xbt_die("Not implemented yet"); + if (process_index != MC_PROCESS_INDEX_DISABLED) { + mc_object_info_t info = MC_process_find_object_info_rw(process, remote); + // Segment overlap is not handled. + if (MC_object_info_is_privatized(info)) { + if (process_index < 0) + xbt_die("Missing process index"); + // Address translation in the privaization segment: + size_t offset = (const char*) remote - info->start_rw; + remote = (const char*) remote - offset; + } + } if (MC_process_is_self(process)) { if (flags & MC_ADDRESS_SPACE_READ_FLAGS_LAZY) @@ -395,3 +482,33 @@ void MC_process_write(mc_process_t process, const void* local, void* remote, siz xbt_die("Write to process %lli failed", (long long) process->pid); } } + +static pthread_once_t zero_buffer_flag = PTHREAD_ONCE_INIT; +static const void* zero_buffer; +static const int zero_buffer_size = 10 * 4096; + +static void MC_zero_buffer_init(void) +{ + int fd = open("/dev/zero", O_RDONLY); + if (fd<0) + xbt_die("Could not open /dev/zero"); + zero_buffer = mmap(NULL, zero_buffer_size, PROT_READ, MAP_SHARED, fd, 0); + if (zero_buffer == MAP_FAILED) + xbt_die("Could not map the zero buffer"); + close(fd); +} + +void MC_process_clear_memory(mc_process_t process, void* remote, size_t len) +{ + if (MC_process_is_self(process)) { + memset(remote, 0, len); + } else { + pthread_once(&zero_buffer_flag, MC_zero_buffer_init); + while (len) { + size_t s = len > zero_buffer_size ? zero_buffer_size : len; + MC_process_write(process, zero_buffer, remote, s); + remote = (char*) remote + s; + len -= s; + } + } +}