示例#1
0
errval_t get_architecture_config(enum cpu_type type,
                                 genpaddr_t *arch_page_size,
                                 const char **monitor_binary,
                                 const char **cpu_binary)
{
    extern char* cmd_kernel_binary;
    extern char* cmd_monitor_binary;

    switch (type) {
    case CPU_X86_64:
    {
        *arch_page_size = X86_64_BASE_PAGE_SIZE;
        *monitor_binary = (cmd_kernel_binary == NULL) ?
                        "/" BF_BINARY_PREFIX "x86_64/sbin/monitor" :
                        get_binary_path("/" BF_BINARY_PREFIX "x86_64/sbin/%s", 
                                        cmd_monitor_binary);
        *cpu_binary = (cmd_kernel_binary == NULL) ?
                        "/" BF_BINARY_PREFIX "x86_64/sbin/cpu" :
                        get_binary_path("/" BF_BINARY_PREFIX "x86_64/sbin/%s", 
                                        cmd_kernel_binary);
    }
    break;

    case CPU_X86_32:
    {
        *arch_page_size = X86_32_BASE_PAGE_SIZE;
        *monitor_binary = (cmd_kernel_binary == NULL) ?
                        "/" BF_BINARY_PREFIX "x86_32/sbin/monitor" :
                        get_binary_path("/" BF_BINARY_PREFIX "x86_32/sbin/%s", 
                                        cmd_monitor_binary);
        *cpu_binary = (cmd_kernel_binary == NULL) ?
                        "/" BF_BINARY_PREFIX "x86_32/sbin/cpu" :
                        get_binary_path("/" BF_BINARY_PREFIX "x86_32/sbin/%s", 
                                        cmd_kernel_binary);
    }
    break;

    case CPU_K1OM:
    {
        *arch_page_size = X86_64_BASE_PAGE_SIZE;
        *monitor_binary = (cmd_kernel_binary == NULL) ?
                        "/" BF_BINARY_PREFIX "k1om/sbin/monitor" :
                        get_binary_path("/" BF_BINARY_PREFIX "k1om/sbin/%s", 
                                        cmd_monitor_binary);
        *cpu_binary = (cmd_kernel_binary == NULL) ?
                        "/" BF_BINARY_PREFIX "k1om/sbin/cpu" :
                        get_binary_path("/" BF_BINARY_PREFIX "k1om/sbin/%s", 
                                        cmd_kernel_binary);
    }
    break;

    default:
        return SPAWN_ERR_UNKNOWN_TARGET_ARCH;
    }

    return SYS_ERR_OK;
}
示例#2
0
//FIXME: This code could be greatly improved/simplifyied with
//   http://cairo.sourcearchive.com/documentation/1.9.4/backtrace-symbols_8c-source.html
std::vector<std::string> resolveBacktrace(
  xbt_backtrace_location_t const* loc, std::size_t count)
{
  std::vector<std::string> result;

  if (count == 0)
    return result;

  if (xbt_binary_name == nullptr)
    XBT_WARN("XBT not initialized, the backtrace will not be resolved.");

  // Drop the first one:
  loc++; count--;

  char** backtrace_syms = backtrace_symbols(loc, count);
  std::string binary_name = get_binary_path();

  if (binary_name.empty()) {
    for (std::size_t i = 0; i < count; i++)
      result.push_back(simgrid::xbt::string_printf("%p", loc[i]));
    return std::move(result);
  }

  // Create the system command for add2line:
  std::ostringstream stream;
  stream << ADDR2LINE << " -f -e " << binary_name << ' ';
  std::vector<std::string> addrs(count);
  for (std::size_t i = 0; i < count; i++) {
    /* retrieve this address */
    XBT_DEBUG("Retrieving address number %zd from '%s'", i, backtrace_syms[i]);
    char buff[256];
    snprintf(buff, 256, "%s", strchr(backtrace_syms[i], '[') + 1);
    char* p = strchr(buff, ']');
    *p = '\0';
    if (strcmp(buff, "(nil)"))
      addrs[i] = buff;
    else
      addrs[i] = "0x0";
    XBT_DEBUG("Set up a new address: %zd, '%s'", i, addrs[i].c_str());
    /* Add it to the command line args */
    stream << addrs[i] << ' ';
  }
  std::string cmd = stream.str();

  /* size (in char) of pointers on this arch */
  int addr_len = addrs[0].size();

  XBT_VERB("Fire a first command: '%s'", cmd.c_str());
  FILE* pipe = popen(cmd.c_str(), "r");
  if (!pipe) {
    xbt_die("Cannot fork addr2line to display the backtrace");
  }

  /* To read the output of addr2line */
  char line_func[1024], line_pos[1024];
  for (std::size_t i = 0; i < count; i++) {
    XBT_DEBUG("Looking for symbol %zd, addr = '%s'", i, addrs[i].c_str());
    if (fgets(line_func, 1024, pipe)) {
      line_func[strlen(line_func) - 1] = '\0';
    } else {
      XBT_VERB("Cannot run fgets to look for symbol %zd, addr %s", i, addrs[i].c_str());
      strncpy(line_func, "???",3);
    }
    if (fgets(line_pos, 1024, pipe)) {
      line_pos[strlen(line_pos) - 1] = '\0';
    } else {
      XBT_VERB("Cannot run fgets to look for symbol %zd, addr %s", i, addrs[i].c_str());
      strncpy(line_pos, backtrace_syms[i],1024);
    }

    if (strcmp("??", line_func) != 0) {
      auto name = simgrid::xbt::demangle(line_func);
      XBT_DEBUG("Found static symbol %s at %s", name.get(), line_pos);
      result.push_back(simgrid::xbt::string_printf(
        "%s at %s, %p", name.get(), line_pos, loc[i]
      ));
    } else {
      /* Damn. The symbol is in a dynamic library. Let's get wild */

      char maps_buff[512];
      long int offset = 0;
      char *p, *p2;
      int found = 0;

      /* let's look for the offset of this library in our addressing space */
      char* maps_name = bprintf("/proc/%d/maps", (int) getpid());
      FILE* maps = fopen(maps_name, "r");

      long int addr = strtol(addrs[i].c_str(), &p, 16);
      if (*p != '\0') {
        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);

      while (!found) {
        long int first, last;

        if (fgets(maps_buff, 512, maps) == nullptr)
          break;
        if (i == 0) {
          maps_buff[strlen(maps_buff) - 1] = '\0';
          XBT_DEBUG("map line: %s", maps_buff);
        }
        sscanf(maps_buff, "%lx", &first);
        p = strchr(maps_buff, '-') + 1;
        sscanf(p, "%lx", &last);
        if (first < addr && addr < last) {
          offset = first;
          found = 1;
        }
        if (found) {
          XBT_DEBUG("%#lx in [%#lx-%#lx]", addr, first, last);
          XBT_DEBUG("Symbol found, map lines not further displayed (even if looking for next ones)");
        }
      }
      fclose(maps);
      free(maps_name);
      addrs[i].clear();

      if (!found) {
        XBT_VERB("Problem while reading the maps file. Following backtrace will be mangled.");
        XBT_DEBUG("No dynamic. Static symbol: %s", backtrace_syms[i]);
        result.push_back(simgrid::xbt::string_printf("?? (%s)", backtrace_syms[i]));
        continue;
      }

      /* Ok, Found the offset of the maps line containing the searched symbol.
         We now need to substract this from the address we got from backtrace.
       */

      addrs[i] = simgrid::xbt::string_printf("0x%0*lx", addr_len - 2, addr - offset);
      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]);
      if (p[0] == '[') {
        /* library path not displayed in the map file either... */
        free(p);
        snprintf(line_func,3, "??");
      } else {
        p2 = strrchr(p, '(');
        if (p2)
          *p2 = '\0';
        p2 = strrchr(p, ' ');
        if (p2)
          *p2 = '\0';

        /* Here we go, fire an addr2line up */
        char* subcmd = bprintf("%s -f -e %s %s", ADDR2LINE, p, addrs[i].c_str());
        free(p);
        XBT_VERB("Fire a new command: '%s'", subcmd);
        FILE* subpipe = popen(subcmd, "r");
        if (!subpipe) {
          xbt_die("Cannot fork addr2line to display the backtrace");
        }
        if (fgets(line_func, 1024, subpipe)) {
          line_func[strlen(line_func) - 1] = '\0';
        } else {
          XBT_VERB("Cannot read result of subcommand %s", subcmd);
          strncpy(line_func, "???",3);
        }
        if (fgets(line_pos, 1024, subpipe)) {
          line_pos[strlen(line_pos) - 1] = '\0';
        } else {
          XBT_VERB("Cannot read result of subcommand %s", subcmd);
          strncpy(line_pos, backtrace_syms[i],1024);
        }
        pclose(subpipe);
        free(subcmd);
      }

      /* check whether the trick worked */
      if (strcmp("??", line_func)) {
        auto name = simgrid::xbt::demangle(line_func);
        XBT_DEBUG("Found dynamic symbol %s at %s", name.get(), line_pos);
        result.push_back(simgrid::xbt::string_printf(
          "%s at %s, %p", name.get(), line_pos, loc[i]));
      } else {
        /* damn, nothing to do here. Let's print the raw address */
        XBT_DEBUG("Dynamic symbol not found. Raw address = %s", backtrace_syms[i]);
        result.push_back(simgrid::xbt::string_printf(
          "?? at %s", backtrace_syms[i]));
      }
    }
    addrs[i].clear();

    /* Mask the bottom of the stack */
    if (!strncmp("main", line_func, strlen("main")) ||
        !strncmp("xbt_thread_context_wrapper", line_func, strlen("xbt_thread_context_wrapper"))
        || !strncmp("smx_ctx_sysv_wrapper", line_func, strlen("smx_ctx_sysv_wrapper")))
      break;
  }
  pclose(pipe);
  free(backtrace_syms);
  return result;
}