Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Basic support for more other libraries than libsimgrid.so
authorGabriel Corona <gabriel.corona@loria.fr>
Thu, 4 Dec 2014 15:03:20 +0000 (16:03 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Fri, 5 Dec 2014 14:34:09 +0000 (15:34 +0100)
src/mc/mc_dwarf.c
src/mc/mc_ignore.c
src/mc/mc_object_info.h
src/mc/mc_process.c
src/mc/mc_process.h

index b9cf927..a286459 100644 (file)
@@ -1024,7 +1024,7 @@ void MC_dwarf_get_variables(mc_object_info_t info)
   }
   Dwarf *dwarf = dwarf_begin(fd, DWARF_C_READ);
   if (dwarf == NULL) {
-    xbt_die("Your program must be compiled with -g");
+    xbt_die("Your program must be compiled with -g (%s)", info->file_name);
   }
   // For each compilation unit:
   Dwarf_Off offset = 0;
@@ -1268,7 +1268,7 @@ 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, char *name,
+mc_object_info_t MC_find_object_info(memory_map_t maps, const char *name,
                                      int executable)
 {
   mc_object_info_t result = MC_new_object_info();
index 9f3a0a7..0675eb9 100644 (file)
@@ -180,26 +180,29 @@ void MC_ignore_global_variable(const char *name)
 
   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;
+      }
     }
   }
 
index 746a410..57a83a8 100644 (file)
@@ -90,7 +90,7 @@ struct s_mc_object_info {
 void* MC_object_base_address(mc_object_info_t info);
 
 mc_object_info_t MC_new_object_info(void);
-mc_object_info_t MC_find_object_info(memory_map_t maps, char* name, int executable);
+mc_object_info_t MC_find_object_info(memory_map_t maps, const char* name, int executable);
 void MC_free_object_info(mc_object_info_t* p);
 
 dw_frame_t MC_file_object_info_find_function(mc_object_info_t info, void *ip);
index 3200b34..6b8542d 100644 (file)
@@ -1,7 +1,10 @@
 #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>
@@ -13,7 +16,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc,
                                 "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)
 {
@@ -23,75 +25,173 @@ 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 !");
 }
index c0e9c45..5ea7a48 100644 (file)
@@ -28,10 +28,9 @@ struct s_mc_process {
   pid_t pid;
   memory_map_t memory_map;
   void *maestro_stack_start, *maestro_stack_end;
-  char *libsimgrid_path;
   mc_object_info_t libsimgrid_info;
   mc_object_info_t binary_info;
-  mc_object_info_t object_infos[2];
+  mc_object_info_t* object_infos;
   size_t object_infos_size;
 };