*
* `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<simgrid::mc::VmMap> 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;
}
/** \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<simgrid::mc::VmMap> const& maps, const char *name, int executable)
{
mc_object_info_t result = MC_new_object_info();
if (executable)
#ifndef MC_MEMORY_MAP_H
#define MC_MEMORY_MAP_H
+#include <cstdint>
+
+#include <string>
+#include <vector>
+
#include <sys/types.h>
#include <simgrid_config.h>
#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<VmMap> 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<simgrid::mc::VmMap> const& maps, mc_object_info_t result);
-SG_END_DECL()
+}
#endif
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<simgrid::mc::VmMap> 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);
//#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{
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;
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;
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<simgrid::mc::VmMap> 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;
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;
}
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;
private:
int status_;
bool running_;
- memory_map_t memory_map;
+ std::vector<VmMap> memory_map_;
remote_ptr<void> maestro_stack_start_, maestro_stack_end_;
int memory_file;
std::vector<IgnoredRegion> ignored_regions_;
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<VmMap> get_memory_map(pid_t pid)
{
/* Open the actual process's proc maps file and create the memory_map_t */
/* to be returned. */
"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<VmMap> 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 */
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();
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();
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();
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);
}
-
}