#define _GNU_SOURCE
#define UNW_LOCAL_ONLY
+#include <unistd.h>
#include <string.h>
#include <link.h>
#include <dirent.h>
#include "internal_config.h"
+#include "mc_memory_map.h"
#include "mc_private.h"
#include "xbt/module.h"
#include <xbt/mmalloc.h>
#include "../simix/smx_private.h"
+#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <libelf.h>
#include "mc_private.h"
#include <mc/mc.h>
+#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 **************************************/
/*****************************************************************************************/
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;
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;
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;
#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
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;
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;
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);
// 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) {
}
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)
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);
+ 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) {