#define _FILE_OFFSET_BITS 64 /* needed for pread_whole to work as expected on 32bits */
+#include <algorithm>
#include <cassert>
#include <cerrno>
#include <cstddef>
#include <cstdint>
+#include <regex>
+#include <string>
+#include <vector>
#include <sys/ptrace.h>
#include <cstdio>
#include <fcntl.h>
-#include <regex.h>
#include <sys/mman.h> // PROT_*
#include <sys/types.h>
#include <unistd.h>
#include <libunwind.h>
#include "xbt/base.h"
+#include "xbt/file.hpp"
#include "xbt/log.h"
#include <xbt/mmalloc.h>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information");
-// ***** Helper stuff
-
-#define SO_RE "\\.so[\\.0-9]*$"
-#define VERSION_RE "-[\\.0-9-]*$"
-
namespace simgrid {
namespace mc {
+// ***** Helper stuff
+
// List of library which memory segments are not considered:
-static const char* const filtered_libraries[] = {
+static const std::vector<std::string> filtered_libraries = {
#ifdef __linux__
"ld",
#elif defined __FreeBSD__
"libunwind-ptrace",
"libz"};
-static bool is_simgrid_lib(const char* libname)
+static bool is_simgrid_lib(const std::string& libname)
{
- return not strcmp(libname, "libsimgrid");
+ return libname == "libsimgrid";
}
-static bool is_filtered_lib(const char* libname)
+static bool is_filtered_lib(const std::string& libname)
{
- for (const char* const& filtered_lib : filtered_libraries)
- if (strcmp(libname, filtered_lib) == 0)
- return true;
- return false;
+ return std::find(begin(filtered_libraries), end(filtered_libraries), libname) != end(filtered_libraries);
}
-struct s_mc_memory_map_re {
- regex_t so_re;
- regex_t version_re;
-};
-
-static char* get_lib_name(const char* pathname, s_mc_memory_map_re* res)
+static std::string get_lib_name(const std::string& pathname)
{
- char* map_basename = xbt_basename(pathname);
-
- regmatch_t match;
- if (regexec(&res->so_re, map_basename, 1, &match, 0)) {
- free(map_basename);
- return nullptr;
- }
-
- char* libname = strndup(map_basename, match.rm_so);
- free(map_basename);
- map_basename = nullptr;
-
- // Strip the version suffix:
- if (libname && not regexec(&res->version_re, libname, 1, &match, 0)) {
- char* temp = libname;
- libname = strndup(temp, match.rm_so);
- free(temp);
+ static const std::regex so_re("\\.so[.0-9]*$");
+ static const std::regex version_re("-[.0-9-]*$");
+ std::string map_basename = simgrid::xbt::Path(pathname).getBasename();
+ std::string libname;
+
+ std::smatch match;
+ if (std::regex_search(map_basename, match, so_re)) {
+ libname = match.prefix();
+
+ // Strip the version suffix:
+ if (std::regex_search(libname, match, version_re))
+ libname = match.prefix();
}
return libname;
this->binary_info = nullptr;
this->libsimgrid_info = nullptr;
- 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");
-
std::vector<simgrid::xbt::VmMap> const& maps = this->memory_map_;
const char* current_name = nullptr;
continue;
const bool is_executable = not i;
- char* libname = nullptr;
+ std::string libname;
if (not is_executable) {
- libname = get_lib_name(pathname, &res);
- if (not libname)
- continue;
+ libname = get_lib_name(pathname);
if (is_filtered_lib(libname)) {
- free(libname);
continue;
}
}
this->object_infos.push_back(info);
if (is_executable)
this->binary_info = info;
- else if (libname && is_simgrid_lib(libname))
+ else if (is_simgrid_lib(libname))
this->libsimgrid_info = info;
- free(libname);
}
- regfree(&res.so_re);
- regfree(&res.version_re);
-
// Resolve time (including across different objects):
for (auto const& object_info : this->object_infos)
postProcessObjectInformation(this, object_info.get());