From 910500315ef51a0f48ca6f6b70b335b986d4e17b Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Thu, 4 Dec 2014 16:03:20 +0100 Subject: [PATCH] [mc] Basic support for more other libraries than libsimgrid.so --- src/mc/mc_dwarf.c | 4 +- src/mc/mc_ignore.c | 39 +++++---- src/mc/mc_object_info.h | 2 +- src/mc/mc_process.c | 182 +++++++++++++++++++++++++++++++--------- src/mc/mc_process.h | 3 +- 5 files changed, 166 insertions(+), 64 deletions(-) diff --git a/src/mc/mc_dwarf.c b/src/mc/mc_dwarf.c index b9cf927cb3..a286459ea8 100644 --- a/src/mc/mc_dwarf.c +++ b/src/mc/mc_dwarf.c @@ -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(); diff --git a/src/mc/mc_ignore.c b/src/mc/mc_ignore.c index 9f3a0a7c31..0675eb9dd2 100644 --- a/src/mc/mc_ignore.c +++ b/src/mc/mc_ignore.c @@ -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; + } } } diff --git a/src/mc/mc_object_info.h b/src/mc/mc_object_info.h index 746a4102c2..57a83a8e2d 100644 --- a/src/mc/mc_object_info.h +++ b/src/mc/mc_object_info.h @@ -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); diff --git a/src/mc/mc_process.c b/src/mc/mc_process.c index 3200b34d25..6b8542ddee 100644 --- a/src/mc/mc_process.c +++ b/src/mc/mc_process.c @@ -1,7 +1,10 @@ #include +#include +#include #include #include +#include #include // PROT_* #include @@ -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 !"); } diff --git a/src/mc/mc_process.h b/src/mc/mc_process.h index c0e9c45d4f..5ea7a48e4e 100644 --- a/src/mc/mc_process.h +++ b/src/mc/mc_process.h @@ -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; }; -- 2.20.1