MC_SET_MC_HEAP;
- xbt_assert(process->libsimgrid_info, "MC subsystem not initialized");
+ xbt_assert(process->object_infos, "MC subsystem not initialized");
- unsigned int cursor = 0;
- dw_variable_t current_var;
- int start = 0;
- int end = xbt_dynar_length(process->libsimgrid_info->global_variables) - 1;
+ size_t n = process->object_infos_size;
+ for (size_t i=0; i!=n; ++i) {
+ mc_object_info_t info = process->object_infos[i];
- while (start <= end) {
- cursor = (start + end) / 2;
- current_var =
- (dw_variable_t) xbt_dynar_get_as(process->libsimgrid_info->global_variables,
- cursor, dw_variable_t);
- if (strcmp(current_var->name, name) == 0) {
- xbt_dynar_remove_at(process->libsimgrid_info->global_variables, cursor, NULL);
- start = 0;
- end = xbt_dynar_length(process->libsimgrid_info->global_variables) - 1;
- } else if (strcmp(current_var->name, name) < 0) {
- start = cursor + 1;
- } else {
- end = cursor - 1;
+ // Binary search:
+ int start = 0;
+ int end = xbt_dynar_length(info->global_variables) - 1;
+ while (start <= end) {
+ unsigned int cursor = (start + end) / 2;
+ dw_variable_t current_var =
+ (dw_variable_t) xbt_dynar_get_as(info->global_variables,
+ cursor, dw_variable_t);
+ if (strcmp(current_var->name, name) == 0) {
+ xbt_dynar_remove_at(info->global_variables, cursor, NULL);
+ start = 0;
+ end = xbt_dynar_length(info->global_variables) - 1;
+ } else if (strcmp(current_var->name, name) < 0) {
+ start = cursor + 1;
+ } else {
+ end = cursor - 1;
+ }
}
}
#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
+#include <regex.h>
#include <sys/mman.h> // PROT_*
#include <libgen.h>
"MC process information");
static void MC_init_memory_map_info(mc_process_t process);
-static void MC_init_debug_info(mc_process_t process);
void MC_process_init(mc_process_t process, pid_t pid)
{
process->process_flags |= MC_PROCESS_SELF_FLAG;
process->memory_map = MC_get_memory_map(pid);
MC_init_memory_map_info(process);
- MC_init_debug_info(process);
}
void MC_process_clear(mc_process_t 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 = NULL;
process->maestro_stack_end = NULL;
- free(process->libsimgrid_path);
- process->libsimgrid_path = NULL;
- MC_free_object_info(&process->binary_info);
- MC_free_object_info(&process->libsimgrid_info);
+
+ size_t i;
+ for (i=0; i!=process->object_infos_size; ++i) {
+ MC_free_object_info(&process->object_infos[i]);
+ }
+ free(process->object_infos);
+ process->object_infos = NULL;
+ process->object_infos_size = 0;
+}
+
+#define SO_RE "\\.so[\\.0-9]*$"
+#define VERSION_RE "-[\\.0-9]*$"
+
+const char* FILTERED_LIBS[] = {
+ "libstdc++",
+ "libc++",
+ "libm",
+ "libgcc_s",
+ "libpthread",
+ "libunwind",
+ "libunwind-x86_64",
+ "libunwind-x86",
+ "libdw",
+ "libdl",
+ "librt",
+ "liblzma",
+ "libelf",
+ "libbz2",
+ "libz",
+ "libelf",
+ "libc",
+ "ld"
+};
+
+static bool MC_is_simgrid_lib(const char* libname)
+{
+ return !strcmp(libname, "libsimgrid");
+}
+
+static bool MC_is_filtered_lib(const char* libname)
+{
+ const size_t n = sizeof(FILTERED_LIBS) / sizeof(const char*);
+ size_t i;
+ for (i=0; i!=n; ++i)
+ if (strcmp(libname, FILTERED_LIBS[i])==0)
+ return true;
+ return false;
+}
+
+struct s_mc_memory_map_re {
+ regex_t so_re;
+ regex_t version_re;
+};
+
+static char* MC_get_lib_name(const char* pathname, struct s_mc_memory_map_re* res) {
+ const char* map_basename = basename((char*) pathname);
+
+ regmatch_t match;
+ if(regexec(&res->so_re, map_basename, 1, &match, 0))
+ return NULL;
+
+ char* libname = strndup(map_basename, match.rm_so);
+
+ // Strip the version suffix:
+ if(libname && !regexec(&res->version_re, libname, 1, &match, 0)) {
+ char* temp = libname;
+ libname = strndup(temp, match.rm_so);
+ free(temp);
+ }
+
+ return libname;
}
/** @brief Finds the range of the different memory segments and binary paths */
static void MC_init_memory_map_info(mc_process_t process)
{
+ XBT_INFO("Get debug information ...");
process->maestro_stack_start = NULL;
process->maestro_stack_end = NULL;
- process->libsimgrid_path = NULL;
+ process->object_infos = NULL;
+ process->object_infos_size = 0;
+ process->binary_info = NULL;
+ process->libsimgrid_info = NULL;
+
+ struct s_mc_memory_map_re res;
+
+ 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 = process->memory_map;
- unsigned int i = 0;
- while (i < maps->mapsize) {
+ const char* current_name = NULL;
+
+ size_t i = 0;
+ for (i=0; i < maps->mapsize; i++) {
map_region_t reg = &(maps->regions[i]);
+ const char* pathname = maps->regions[i].pathname;
+
+ // Nothing to do
if (maps->regions[i].pathname == NULL) {
- // Nothing to do
- } else if ((reg->prot & PROT_WRITE)
- && !memcmp(maps->regions[i].pathname, "[stack]", 7)) {
- process->maestro_stack_start = reg->start_addr;
- process->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 (process->libsimgrid_path == NULL)
- process->libsimgrid_path = strdup(maps->regions[i].pathname);
+ current_name = NULL;
+ continue;
}
- i++;
- }
-
- xbt_assert(process->maestro_stack_start, "maestro_stack_start");
- xbt_assert(process->maestro_stack_end, "maestro_stack_end");
- xbt_assert(process->libsimgrid_path, "libsimgrid_path&");
-}
-static void MC_init_debug_info(mc_process_t process)
-{
- XBT_INFO("Get debug information ...");
-
- memory_map_t maps = process->memory_map;
+ // [stack], [vvar], [vsyscall], [vdso] ...
+ if (pathname[0] == '[') {
+ if ((reg->prot & PROT_WRITE) && !memcmp(pathname, "[stack]", 7)) {
+ process->maestro_stack_start = reg->start_addr;
+ process->maestro_stack_end = reg->end_addr;
+ }
+ current_name = NULL;
+ continue;
+ }
- // TODO, fix binary name
+ if (current_name && strcmp(current_name, pathname)==0)
+ continue;
+
+ current_name = pathname;
+ if (!(reg->prot & PROT_READ) && (reg->prot & PROT_EXEC))
+ continue;
+
+ const bool is_executable = !i;
+ char* libname = NULL;
+ if (!is_executable) {
+ libname = MC_get_lib_name(pathname, &res);
+ if(!libname)
+ continue;
+ if (MC_is_filtered_lib(libname)) {
+ free(libname);
+ continue;
+ }
+ }
- /* Get local variables for state equality detection */
- process->binary_info = MC_find_object_info(maps, xbt_binary_name, 1);
- process->object_infos[0] = process->binary_info;
+ mc_object_info_t info =
+ MC_find_object_info(process->memory_map, pathname, is_executable);
+ process->object_infos = (mc_object_info_t*) realloc(process->object_infos,
+ (process->object_infos_size+1) * sizeof(mc_object_info_t*));
+ process->object_infos[process->object_infos_size] = info;
+ process->object_infos_size++;
+ if (is_executable)
+ process->binary_info = info;
+ else if (libname && MC_is_simgrid_lib(libname))
+ process->libsimgrid_info = info;
+ free(libname);
+ }
- process->libsimgrid_info = MC_find_object_info(maps, process->libsimgrid_path, 0);
- process->object_infos[1] = process->libsimgrid_info;
+ regfree(&res.so_re);
+ regfree(&res.version_re);
- process->object_infos_size = 2;
+ // Resolve time (including accress differents objects):
+ for (i=0; i!=process->object_infos_size; ++i)
+ MC_post_process_object_info(process, process->object_infos[i]);
- // Use information of the other objects:
- MC_post_process_object_info(process, process->libsimgrid_info);
- MC_post_process_object_info(process, process->binary_info);
+ xbt_assert(process->maestro_stack_start, "maestro_stack_start");
+ xbt_assert(process->maestro_stack_end, "maestro_stack_end");
XBT_INFO("Get debug information done !");
}