X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/42d8a4dc6763b3a784a72cb6842dfd1f5115d2a0..1113792240aa3e88b1a2ba75474f338ad8db2ca2:/src/mc/mc_checkpoint.c diff --git a/src/mc/mc_checkpoint.c b/src/mc/mc_checkpoint.c index aaa99adfbb..cd4310a1df 100644 --- a/src/mc/mc_checkpoint.c +++ b/src/mc/mc_checkpoint.c @@ -7,12 +7,14 @@ #define _GNU_SOURCE #define UNW_LOCAL_ONLY +#include #include #include #include #include "internal_config.h" +#include "mc_memory_map.h" #include "mc_private.h" #include "xbt/module.h" #include @@ -23,19 +25,20 @@ #include "../simix/smx_private.h" +#define UNW_LOCAL_ONLY #include #include #include "mc_private.h" #include +#include "mc_snapshot.h" +#include "mc_object_info.h" #include "mc_mmu.h" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc, "Logging specific to mc_checkpoint"); -char *libsimgrid_path; - /************************************ Free functions **************************************/ /*****************************************************************************************/ @@ -171,6 +174,7 @@ static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, static void MC_get_memory_regions(mc_snapshot_t snapshot) { + mc_process_t process = &mc_model_checker->process; void *start_heap = std_heap->base; void *end_heap = std_heap->breakval; @@ -180,8 +184,8 @@ static void MC_get_memory_regions(mc_snapshot_t snapshot) snapshot->privatization_regions = NULL; MC_snapshot_add_region(snapshot, 1, - mc_libsimgrid_info->start_rw, mc_libsimgrid_info->start_rw, - mc_libsimgrid_info->end_rw - mc_libsimgrid_info->start_rw); + process->libsimgrid_info->start_rw, process->libsimgrid_info->start_rw, + process->libsimgrid_info->end_rw - process->libsimgrid_info->start_rw); #ifdef HAVE_SMPI size_t i; @@ -194,7 +198,7 @@ static void MC_get_memory_regions(mc_snapshot_t snapshot) mc_mem_region_t ref_reg = mc_model_checker->parent_snapshot ? mc_model_checker->parent_snapshot->privatization_regions[i] : NULL; snapshot->privatization_regions[i] = - MC_region_new(-1, mc_binary_info->start_rw, smpi_privatisation_regions[i].address, size_data_exe, ref_reg); + MC_region_new(-1, process->binary_info->start_rw, smpi_privatisation_regions[i].address, size_data_exe, ref_reg); } snapshot->privatization_index = smpi_loaded_page; snapshot->regions[2] = NULL; @@ -202,50 +206,13 @@ static void MC_get_memory_regions(mc_snapshot_t snapshot) #endif { MC_snapshot_add_region(snapshot, 2, - mc_binary_info->start_rw, mc_binary_info->start_rw, - mc_binary_info->end_rw - mc_binary_info->start_rw); + process->binary_info->start_rw, process->binary_info->start_rw, + process->binary_info->end_rw - process->binary_info->start_rw); snapshot->privatization_regions = NULL; snapshot->privatization_index = -1; } } -/** @brief Finds the range of the different memory segments and binary paths */ -void MC_init_memory_map_info() -{ - - unsigned int i = 0; - s_map_region_t reg; - memory_map_t maps = MC_get_memory_map(); - - maestro_stack_start = NULL; - maestro_stack_end = NULL; - libsimgrid_path = NULL; - - while (i < maps->mapsize) { - reg = maps->regions[i]; - if (maps->regions[i].pathname == NULL) { - // Nothing to do - } else if ((reg.prot & PROT_WRITE) - && !memcmp(maps->regions[i].pathname, "[stack]", 7)) { - maestro_stack_start = reg.start_addr; - maestro_stack_end = reg.end_addr; - } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC) - && !memcmp(basename(maps->regions[i].pathname), "libsimgrid", - 10)) { - if (libsimgrid_path == NULL) - libsimgrid_path = strdup(maps->regions[i].pathname); - } - i++; - } - - xbt_assert(maestro_stack_start, "maestro_stack_start"); - xbt_assert(maestro_stack_end, "maestro_stack_end"); - xbt_assert(libsimgrid_path, "libsimgrid_path&"); - - MC_free_memory_map(maps); - -} - /** \brief Fills the position of the segments (executable, read-only, read/write). * * TODO, use dl_iterate_phdr to be more robust @@ -319,6 +286,8 @@ static bool mc_valid_variable(dw_variable_t var, dw_frame_t scope, static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, dw_frame_t scope, int process_index, xbt_dynar_t result) { + mc_process_t process = &mc_model_checker->process; + void *ip = (void *) stack_frame->ip; if (ip < scope->low_pc || ip >= scope->high_pc) return; @@ -331,7 +300,7 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, continue; int region_type; - if ((long) stack_frame->ip > (long) mc_libsimgrid_info->start_exec) + if ((long) stack_frame->ip > (long) process->libsimgrid_info->start_exec) region_type = 1; else region_type = 2; @@ -402,6 +371,7 @@ static void MC_stack_frame_free_voipd(void *s) static xbt_dynar_t MC_unwind_stack_frames(void *stack_context) { + mc_process_t process = &mc_model_checker->process; xbt_dynar_t result = xbt_dynar_new(sizeof(mc_stack_frame_t), MC_stack_frame_free_voipd); @@ -430,7 +400,7 @@ static xbt_dynar_t MC_unwind_stack_frames(void *stack_context) // TODO, use real addresses in frame_t instead of fixing it here - dw_frame_t frame = MC_find_function_by_ip((void *) ip); + dw_frame_t frame = MC_process_find_function(process, (void *) ip); stack_frame->frame = frame; if (frame) { @@ -576,56 +546,74 @@ int mc_important_snapshot(mc_snapshot_t snapshot) } static void MC_get_current_fd(mc_snapshot_t snapshot){ - - struct dirent *fd_number; - DIR *fd_dir; - char *command; - size_t n; - char *line = NULL; - FILE *fp; - int fd_value; - - snapshot->total_fd = 0; - - fd_dir = opendir ("/proc/self/fd"); - if (fd_dir == NULL) { - printf ("Cannot open directory '/proc/self/fd'\n"); - return; - } - - while ((fd_number = readdir(fd_dir)) != NULL) { - - fd_value = atoi(fd_number->d_name); - - if(fd_value < 3) - continue; - - command = bprintf("readlink /proc/self/fd/%s", fd_number->d_name); - fp = popen(command, "r"); - if(fp == NULL){ - perror("popen failed"); - xbt_abort(); - } - xbt_getline(&line, &n, fp); - if(line && strncmp(line, "pipe:", 5) != 0 && strncmp(line, "socket:", 7) != 0){ - fd_infos_t fd = xbt_new0(s_fd_infos_t, 1); - fd->filename = strdup(line); - fd->filename[strlen(line)-1] = '\0'; - fd->number = fd_value; - fd->flags = fcntl(fd_value, F_GETFD); - fd->current_position = lseek(fd_value, 0, SEEK_CUR); - snapshot->current_fd = xbt_realloc(snapshot->current_fd, (snapshot->total_fd + 1) * sizeof(fd_infos_t)); - snapshot->current_fd[snapshot->total_fd] = fd; - snapshot->total_fd++; - } - - xbt_free(command); - pclose(fp); - } - - xbt_free(line); - closedir (fd_dir); + snapshot->total_fd = 0; + + const size_t fd_dir_path_size = 20; + char fd_dir_path[fd_dir_path_size]; + if (snprintf(fd_dir_path, fd_dir_path_size, + "/proc/%lli/fd", (long long int) getpid()) > fd_dir_path_size) + xbt_die("Unexpected buffer is too small for fd_dir_path"); + + DIR* fd_dir = opendir (fd_dir_path); + if (fd_dir == NULL) + xbt_die("Cannot open directory '/proc/self/fd'\n"); + + size_t total_fd = 0; + struct dirent* fd_number; + while ((fd_number = readdir(fd_dir))) { + + int fd_value = atoi(fd_number->d_name); + + if(fd_value < 3) + continue; + + const size_t source_size = 25; + char source[25]; + if (snprintf(source, source_size, "/proc/self/fd/%s", fd_number->d_name) > source_size) + xbt_die("Unexpected buffer is too small for fd %s", fd_number->d_name); + + const size_t link_size = 200; + char link[200]; + int res = readlink(source, link, link_size); + if (res<0) { + xbt_die("Could not read link for %s", source); + } + if (res==200) { + xbt_die("Buffer to small for link of %s", source); + } + link[res] = '\0'; + + if(smpi_is_privatisation_file(link)) + continue; + + // This is (probably) the DIR* we are reading: + // TODO, read all the file entries at once and close the DIR.* + if(strcmp(fd_dir_path, link) == 0) + continue; + + // We don't handle them. + // It does not mean we should silently ignore them however. + if (strncmp(link, "pipe:", 5) == 0 || strncmp(link, "socket:", 7) == 0) + continue; + + // This is probably a shared memory used by lttng-ust: + if(strncmp("/dev/shm/ust-shm-tmp-", link, 21)==0) + continue; + + // Add an entry for this FD in the snapshot: + fd_infos_t fd = xbt_new0(s_fd_infos_t, 1); + fd->filename = strdup(link); + fd->number = fd_value; + fd->flags = fcntl(fd_value, F_GETFL) | fcntl(fd_value, F_GETFD) ; + fd->current_position = lseek(fd_value, 0, SEEK_CUR); + snapshot->current_fd = xbt_realloc(snapshot->current_fd, (total_fd + 1) * sizeof(fd_infos_t)); + snapshot->current_fd[total_fd] = fd; + total_fd++; + } + + snapshot->total_fd = total_fd; + closedir (fd_dir); } mc_snapshot_t MC_take_snapshot(int num_state) @@ -707,11 +695,16 @@ void MC_restore_snapshot(mc_snapshot_t snapshot) for(i=0; i < snapshot->total_fd; i++){ new_fd = open(snapshot->current_fd[i]->filename, snapshot->current_fd[i]->flags); + if (new_fd <0) { + xbt_die("Could not reopen the file %s fo restoring the file descriptor", + snapshot->current_fd[i]->filename); + } if(new_fd != -1 && new_fd != snapshot->current_fd[i]->number){ dup2(new_fd, snapshot->current_fd[i]->number); - fprintf(stderr, "%p\n", fdopen(snapshot->current_fd[i]->number, "rw")); - lseek(snapshot->current_fd[i]->number, snapshot->current_fd[i]->current_position, SEEK_SET); + //fprintf(stderr, "%p\n", fdopen(snapshot->current_fd[i]->number, "rw")); + close(new_fd); }; + lseek(snapshot->current_fd[i]->number, snapshot->current_fd[i]->current_position, SEEK_SET); } if (_sg_mc_sparse_checkpoint && _sg_mc_soft_dirty) {