X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/d656f9465e7b1c36319f86eeafdcec58fe9551a4..f968cbbb699423fa252994ff42de77f8671ac7eb:/src/xbt/backtrace_linux.cpp diff --git a/src/xbt/backtrace_linux.cpp b/src/xbt/backtrace_linux.cpp index 5b23cb1974..3c8ecb3820 100644 --- a/src/xbt/backtrace_linux.cpp +++ b/src/xbt/backtrace_linux.cpp @@ -1,11 +1,14 @@ /* backtrace_linux - backtrace displaying on linux platform */ /* This file is included by ex.cpp on need (have execinfo.h, popen & addrline)*/ -/* Copyright (c) 2008-2017. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2008-2018. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include +#include +#include #include #include #include @@ -133,10 +136,14 @@ static std::string get_binary_path() return ""; } +std::vector resolveBacktrace(xbt_backtrace_location_t const* loc, std::size_t count) // deprecated +{ + return resolve_backtrace(loc, count); +} + //FIXME: This code could be greatly improved/simplifyied with // http://cairo.sourcearchive.com/documentation/1.9.4/backtrace-symbols_8c-source.html -std::vector resolveBacktrace( - xbt_backtrace_location_t const* loc, std::size_t count) +std::vector resolve_backtrace(xbt_backtrace_location_t const* loc, std::size_t count) { std::vector result; @@ -197,7 +204,7 @@ std::vector resolveBacktrace( line_func[strlen(line_func) - 1] = '\0'; } else { XBT_VERB("Cannot run fgets to look for symbol %zu, addr %s", i, addrs[i].c_str()); - strncpy(line_func, "???",3); + strncpy(line_func, "???", 4); } if (fgets(line_pos, 1024, pipe)) { line_pos[strlen(line_pos) - 1] = '\0'; @@ -215,17 +222,19 @@ std::vector resolveBacktrace( } else { /* Damn. The symbol is in a dynamic library. Let's get wild */ - char maps_buff[512]; unsigned long int offset = 0; - char* p; int found = 0; /* let's look for the offset of this library in our addressing space */ - std::string maps_name = std::string("/proc/") + std::to_string(getpid()) + "maps"; - FILE* maps = fopen(maps_name.c_str(), "r"); - - unsigned long int addr = strtoul(addrs[i].c_str(), &p, 16); - if (*p != '\0') { + std::string maps_name = std::string("/proc/") + std::to_string(getpid()) + "/maps"; + std::ifstream maps(maps_name); + if (not maps) { + XBT_CRITICAL("open(\"%s\") failed: %s", maps_name.c_str(), strerror(errno)); + continue; + } + size_t pos; + unsigned long int addr = std::stoul(addrs[i], &pos, 16); + if (pos != addrs[i].length()) { XBT_CRITICAL("Cannot parse backtrace address '%s' (addr=%#lx)", addrs[i].c_str(), addr); } XBT_DEBUG("addr=%s (as string) =%#lx (as number)", addrs[i].c_str(), addr); @@ -234,15 +243,15 @@ std::vector resolveBacktrace( unsigned long int first; unsigned long int last; - if (fgets(maps_buff, 512, maps) == nullptr) + std::string maps_buff; + if (not std::getline(maps, maps_buff)) break; if (i == 0) { - maps_buff[strlen(maps_buff) - 1] = '\0'; - XBT_DEBUG("map line: %s", maps_buff); + XBT_DEBUG("map line: %s", maps_buff.c_str()); } - sscanf(maps_buff, "%lx", &first); - p = strchr(maps_buff, '-') + 1; - sscanf(p, "%lx", &last); + first = std::stoul(maps_buff, &pos, 16); + maps_buff.erase(0, pos + 1); + last = std::stoul(maps_buff, nullptr, 16); if (first < addr && addr < last) { offset = first; found = 1; @@ -252,7 +261,7 @@ std::vector resolveBacktrace( XBT_DEBUG("Symbol found, map lines not further displayed (even if looking for next ones)"); } } - fclose(maps); + maps.close(); addrs[i].clear(); if (not found) { @@ -270,22 +279,17 @@ std::vector resolveBacktrace( XBT_DEBUG("offset=%#lx new addr=%s", offset, addrs[i].c_str()); /* Got it. We have our new address. Let's get the library path and we are set */ - p = xbt_strdup(backtrace_syms[i]); + std::string p(backtrace_syms[i]); if (p[0] == '[') { /* library path not displayed in the map file either... */ - free(p); - snprintf(line_func,3, "??"); + snprintf(line_func, 3, "??"); } else { - char* p2 = strrchr(p, '('); - if (p2) - *p2 = '\0'; - p2 = strrchr(p, ' '); - if (p2) - *p2 = '\0'; + size_t p2 = p.find_first_of("( "); + if (p2 != std::string::npos) + p.erase(p2); /* Here we go, fire an addr2line up */ std::string subcmd = std::string(ADDR2LINE) + " -f -e " + p + " " + addrs[i]; - free(p); XBT_VERB("Fire a new command: '%s'", subcmd.c_str()); FILE* subpipe = popen(subcmd.c_str(), "r"); if (not subpipe) { @@ -295,7 +299,7 @@ std::vector resolveBacktrace( line_func[strlen(line_func) - 1] = '\0'; } else { XBT_VERB("Cannot read result of subcommand %s", subcmd.c_str()); - strncpy(line_func, "???",3); + strncpy(line_func, "???", 4); } if (fgets(line_pos, 1024, subpipe)) { line_pos[strlen(line_pos) - 1] = '\0'; @@ -322,9 +326,19 @@ std::vector resolveBacktrace( addrs[i].clear(); /* Mask the bottom of the stack */ - if (not strncmp("main", line_func, strlen("main")) || - not strncmp("xbt_thread_context_wrapper", line_func, strlen("xbt_thread_context_wrapper")) || - not strncmp("smx_ctx_sysv_wrapper", line_func, strlen("smx_ctx_sysv_wrapper"))) + const char* const breakers[] = { + "main", + "_ZN7simgrid6kernel7context13ThreadContext7wrapperE", // simgrid::kernel::context::ThreadContext::wrapper + "_ZN7simgrid6kernel7context8UContext7wrapperE" // simgrid::kernel::context::UContext::wrapper + }; + bool do_break = false; + for (const char* b : breakers) { + if (strncmp(b, line_func, strlen(b)) == 0) { + do_break = true; + break; + } + } + if (do_break) break; } pclose(pipe);