From 214f188618ac52530034513e24a0a9b6353e0f95 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Thu, 28 May 2015 12:31:04 +0200 Subject: [PATCH] [mc] Make Process::memory_map_ a std::vector --- src/mc/mc_checkpoint.cpp | 27 ++++++++++++--------------- src/mc/mc_dwarf.cpp | 4 ++-- src/mc/mc_memory_map.h | 40 +++++++++++++++++++--------------------- src/mc/mc_object_info.h | 3 ++- src/mc/mc_private.h | 4 ---- src/mc/mc_process.cpp | 25 +++++++++++-------------- src/mc/mc_process.h | 2 +- src/mc/memory_map.cpp | 38 ++++++++++++++++---------------------- 8 files changed, 63 insertions(+), 80 deletions(-) diff --git a/src/mc/mc_checkpoint.cpp b/src/mc/mc_checkpoint.cpp index 081aeadf9e..32e0a9aa0a 100644 --- a/src/mc/mc_checkpoint.cpp +++ b/src/mc/mc_checkpoint.cpp @@ -266,42 +266,39 @@ static void MC_get_memory_regions(mc_process_t process, mc_snapshot_t snapshot) * * `dl_iterate_phdr` would be more robust but would not work in cross-process. * */ -void MC_find_object_address(memory_map_t maps, mc_object_info_t result) +void MC_find_object_address(std::vector const& maps, mc_object_info_t result) { - ssize_t i = 0; - s_map_region_t reg; const char *name = basename(result->file_name); - while (i < maps->mapsize) { - reg = maps->regions[i]; - if (maps->regions[i].pathname == NULL - || strcmp(basename(maps->regions[i].pathname), name)) { + for (size_t i = 0; i < maps.size(); ++i) { + simgrid::mc::VmMap const& reg = maps[i]; + if (maps[i].pathname.empty() + || strcmp(basename(maps[i].pathname.c_str()), name)) { // Nothing to do } else if ((reg.prot & PROT_WRITE)) { xbt_assert(!result->start_rw, "Multiple read-write segments for %s, not supported", - maps->regions[i].pathname); + maps[i].pathname.c_str()); result->start_rw = (char*) reg.start_addr; result->end_rw = (char*) reg.end_addr; // .bss is usually after the .data: - s_map_region_t *next = &(maps->regions[i + 1]); - if (next->pathname == NULL && (next->prot & PROT_WRITE) - && next->start_addr == reg.end_addr) { - result->end_rw = (char*) maps->regions[i + 1].end_addr; + simgrid::mc::VmMap const& next = maps[i + 1]; + if (next.pathname.empty() && (next.prot & PROT_WRITE) + && next.start_addr == reg.end_addr) { + result->end_rw = (char*) maps[i + 1].end_addr; } } else if ((reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)) { xbt_assert(!result->start_exec, "Multiple executable segments for %s, not supported", - maps->regions[i].pathname); + maps[i].pathname.c_str()); result->start_exec = (char*) reg.start_addr; result->end_exec = (char*) reg.end_addr; } else if ((reg.prot & PROT_READ) && !(reg.prot & PROT_EXEC)) { xbt_assert(!result->start_ro, "Multiple read only segments for %s, not supported", - maps->regions[i].pathname); + maps[i].pathname.c_str()); result->start_ro = (char*) reg.start_addr; result->end_ro = (char*) reg.end_addr; } - i++; } result->start = result->start_rw; diff --git a/src/mc/mc_dwarf.cpp b/src/mc/mc_dwarf.cpp index 7c1bcd4942..5a994b0b90 100644 --- a/src/mc/mc_dwarf.cpp +++ b/src/mc/mc_dwarf.cpp @@ -1278,8 +1278,8 @@ static void MC_post_process_types(mc_object_info_t info) } /** \brief Finds informations about a given shared object/executable */ -mc_object_info_t MC_find_object_info(memory_map_t maps, const char *name, - int executable) +mc_object_info_t MC_find_object_info( + std::vector const& maps, const char *name, int executable) { mc_object_info_t result = MC_new_object_info(); if (executable) diff --git a/src/mc/mc_memory_map.h b/src/mc/mc_memory_map.h index 425d6d6cf9..afcbb70338 100644 --- a/src/mc/mc_memory_map.h +++ b/src/mc/mc_memory_map.h @@ -7,43 +7,41 @@ #ifndef MC_MEMORY_MAP_H #define MC_MEMORY_MAP_H +#include + +#include +#include + #include #include #include "mc_forward.h" -SG_BEGIN_DECL() - -/** \file - * These functions and data structures implements a binary interface for - * the proc maps ascii interface */ +namespace simgrid { +namespace mc { -/* Each field is defined as documented in proc's manual page */ -struct s_map_region { - - void *start_addr; /* Start address of the map */ - void *end_addr; /* End address of the map */ +/** An virtual memory map entry from /proc/$pid/maps */ +struct VmMap { + std::uint64_t start_addr, end_addr; int prot; /* Memory protection */ int flags; /* Additional memory flags */ - void *offset; /* Offset in the file/whatever */ + std::uint64_t offset; /* Offset in the file/whatever */ char dev_major; /* Major of the device */ char dev_minor; /* Minor of the device */ unsigned long inode; /* Inode in the device */ - char *pathname; /* Path name of the mapped file */ - + std::string pathname; /* Path name of the mapped file */ }; -typedef struct s_map_region s_map_region_t, *map_region_t; -struct s_memory_map { +std::vector get_memory_map(pid_t pid); - s_map_region_t *regions; /* Pointer to an array of regions */ - int mapsize; /* Number of regions in the memory */ +} +} -}; +extern "C" { -XBT_INTERNAL memory_map_t MC_get_memory_map(pid_t pid); -XBT_INTERNAL void MC_free_memory_map(memory_map_t map); +XBT_INTERNAL void MC_find_object_address( + std::vector const& maps, mc_object_info_t result); -SG_END_DECL() +} #endif diff --git a/src/mc/mc_object_info.h b/src/mc/mc_object_info.h index 749c3e87b1..40d6955287 100644 --- a/src/mc/mc_object_info.h +++ b/src/mc/mc_object_info.h @@ -105,7 +105,8 @@ bool MC_object_info_is_privatized(mc_object_info_t info) XBT_INTERNAL void* MC_object_base_address(mc_object_info_t info); XBT_INTERNAL mc_object_info_t MC_new_object_info(void); -XBT_INTERNAL mc_object_info_t MC_find_object_info(memory_map_t maps, const char* name, int executable); +XBT_INTERNAL mc_object_info_t MC_find_object_info( + std::vector const& maps, const char* name, int executable); XBT_INTERNAL void MC_free_object_info(mc_object_info_t* p); XBT_INTERNAL dw_frame_t MC_file_object_info_find_function(mc_object_info_t info, const void *ip); diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index b5e564b180..da88999e63 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -109,10 +109,6 @@ XBT_INTERNAL void print_comparison_times(void); //#define MC_DEBUG 1 #define MC_VERBOSE 1 -/********************************** Variables with DWARF **********************************/ - -XBT_INTERNAL void MC_find_object_address(memory_map_t maps, mc_object_info_t result); - /********************************** Miscellaneous **********************************/ typedef struct s_local_variable{ diff --git a/src/mc/mc_process.cpp b/src/mc/mc_process.cpp index 316c722f17..d59e94d99c 100644 --- a/src/mc/mc_process.cpp +++ b/src/mc/mc_process.cpp @@ -196,7 +196,7 @@ Process::Process(pid_t pid, int sockfd) process->process_flags |= MC_PROCESS_SELF_FLAG; process->running_ = true; process->status_ = 0; - process->memory_map = MC_get_memory_map(pid); + process->memory_map_ = get_memory_map(pid); process->cache_flags = MC_PROCESS_CACHE_FLAG_NONE; process->heap = NULL; process->heap_info = NULL; @@ -242,9 +242,6 @@ Process::~Process() process->process_flags = MC_PROCESS_NO_FLAG; process->pid_ = 0; - MC_free_memory_map(process->memory_map); - process->memory_map = NULL; - process->maestro_stack_start_ = nullptr; process->maestro_stack_end_ = nullptr; @@ -335,25 +332,25 @@ void Process::init_memory_map_info() if(regcomp(&res.so_re, SO_RE, 0) || regcomp(&res.version_re, VERSION_RE, 0)) xbt_die(".so regexp did not compile"); - memory_map_t maps = this->memory_map; + std::vector const& maps = this->memory_map_; const char* current_name = NULL; - for (ssize_t i=0; i < maps->mapsize; i++) { - map_region_t reg = &(maps->regions[i]); - const char* pathname = maps->regions[i].pathname; + for (size_t i=0; i < maps.size(); i++) { + simgrid::mc::VmMap const& reg = maps[i]; + const char* pathname = maps[i].pathname.c_str(); // Nothing to do - if (maps->regions[i].pathname == NULL) { + if (maps[i].pathname.empty()) { current_name = NULL; continue; } // [stack], [vvar], [vsyscall], [vdso] ... if (pathname[0] == '[') { - if ((reg->prot & PROT_WRITE) && !memcmp(pathname, "[stack]", 7)) { - this->maestro_stack_start_ = remote(reg->start_addr); - this->maestro_stack_end_ = remote(reg->end_addr); + if ((reg.prot & PROT_WRITE) && !memcmp(pathname, "[stack]", 7)) { + this->maestro_stack_start_ = remote(reg.start_addr); + this->maestro_stack_end_ = remote(reg.end_addr); } current_name = NULL; continue; @@ -363,7 +360,7 @@ void Process::init_memory_map_info() continue; current_name = pathname; - if (!(reg->prot & PROT_READ) && (reg->prot & PROT_EXEC)) + if (!(reg.prot & PROT_READ) && (reg.prot & PROT_EXEC)) continue; const bool is_executable = !i; @@ -379,7 +376,7 @@ void Process::init_memory_map_info() } mc_object_info_t info = - MC_find_object_info(this->memory_map, pathname, is_executable); + MC_find_object_info(this->memory_map_, pathname, is_executable); this->object_infos = (mc_object_info_t*) realloc(this->object_infos, (this->object_infos_size+1) * sizeof(mc_object_info_t*)); this->object_infos[this->object_infos_size] = info; diff --git a/src/mc/mc_process.h b/src/mc/mc_process.h index 5879580461..4e301220e2 100644 --- a/src/mc/mc_process.h +++ b/src/mc/mc_process.h @@ -147,7 +147,7 @@ public: // to be private private: int status_; bool running_; - memory_map_t memory_map; + std::vector memory_map_; remote_ptr maestro_stack_start_, maestro_stack_end_; int memory_file; std::vector ignored_regions_; diff --git a/src/mc/memory_map.cpp b/src/mc/memory_map.cpp index db0fcce64e..f80105cd5b 100644 --- a/src/mc/memory_map.cpp +++ b/src/mc/memory_map.cpp @@ -16,7 +16,12 @@ extern "C" { XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_memory_map, mc, "Logging specific to algorithms for memory_map"); -memory_map_t MC_get_memory_map(pid_t pid) +} + +namespace simgrid { +namespace mc { + +std::vector get_memory_map(pid_t pid) { /* Open the actual process's proc maps file and create the memory_map_t */ /* to be returned. */ @@ -29,7 +34,7 @@ memory_map_t MC_get_memory_map(pid_t pid) "Cannot open %s to investigate the memory map of the process.", path); setbuf(fp, NULL); - memory_map_t ret = xbt_new0(s_memory_map_t, 1); + std::vector ret; /* Read one line at the time, parse it and add it to the memory map to be returned */ ssize_t read; /* Number of bytes readed */ @@ -62,9 +67,9 @@ memory_map_t MC_get_memory_map(pid_t pid) if (tok == NULL) xbt_abort(); - s_map_region_t memreg; /* temporal map region used for creating the map */ + VmMap memreg; char *endptr; - memreg.start_addr = (void *) strtoul(tok, &endptr, 16); + memreg.start_addr = strtoull(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); @@ -73,7 +78,7 @@ memory_map_t MC_get_memory_map(pid_t pid) if (tok == NULL) xbt_abort(); - memreg.end_addr = (void *) strtoul(tok, &endptr, 16); + memreg.end_addr = strtoull(tok, &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); @@ -109,7 +114,7 @@ memory_map_t MC_get_memory_map(pid_t pid) memreg.flags |= MAP_SHARED; /* Get the offset value */ - memreg.offset = (void *) strtoul(lfields[2], &endptr, 16); + memreg.offset = strtoull(lfields[2], &endptr, 16); /* Make sure that the entire string was an hex number */ if (*endptr != '\0') xbt_abort(); @@ -139,32 +144,21 @@ memory_map_t MC_get_memory_map(pid_t pid) xbt_abort(); /* And finally get the pathname */ - memreg.pathname = xbt_strdup(lfields[5]); + if (lfields[5]) + memreg.pathname = lfields[5]; /* Create space for a new map region in the region's array and copy the */ /* parsed stuff from the temporal memreg variable */ XBT_DEBUG("Found region for %s", - memreg.pathname ? memreg.pathname : "(null)"); - ret->regions = (map_region_t) - xbt_realloc(ret->regions, sizeof(memreg) * (ret->mapsize + 1)); - memcpy(ret->regions + ret->mapsize, &memreg, sizeof(memreg)); - ret->mapsize++; + !memreg.pathname.empty() ? memreg.pathname.c_str() : "(null)"); + ret.push_back(std::move(memreg)); } free(line); fclose(fp); - return ret; + return std::move(ret); } -void MC_free_memory_map(memory_map_t map){ - - int i; - for(i=0; i< map->mapsize; i++){ - xbt_free(map->regions[i].pathname); - } - xbt_free(map->regions); - xbt_free(map); } - } -- 2.20.1