Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Basic support for more other libraries than libsimgrid.so
[simgrid.git] / src / mc / mc_process.c
index 3200b34..6b8542d 100644 (file)
@@ -1,7 +1,10 @@
 #include <stddef.h>
 #include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
 
 #include <sys/types.h>
 #include <unistd.h>
 
 #include <sys/types.h>
 #include <unistd.h>
+#include <regex.h>
 #include <sys/mman.h> // PROT_*
 
 #include <libgen.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);
                                 "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)
 {
 
 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);
     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;
 }
 
 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;
   MC_free_memory_map(process->memory_map);
   process->memory_map = NULL;
+
   process->maestro_stack_start = NULL;
   process->maestro_stack_end = 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)
 {
 }
 
 /** @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->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;
 
 
   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]);
     map_region_t reg = &(maps->regions[i]);
+    const char* pathname = maps->regions[i].pathname;
+
+    // Nothing to do
     if (maps->regions[i].pathname == NULL) {
     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 !");
 }
 
   XBT_INFO("Get debug information done !");
 }