Пример #1
0
std::string current_executable_directory() {
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
  std::string path = current_executable_path();
  return path.substr(0, path.find_last_of("/"));
#else
  // XXX: How do you do this on your platform?
  return std::string();
#endif
}
Пример #2
0
bool get_embedded_data(const char* section, embedded_data* desc,
                       const std::string& filename /*= "" */) {
  auto const fname = filename.empty() ? current_executable_path() : filename;

#if defined(__CYGWIN__) || defined(__MINGW__) || defined(_MSC_VER)
  HMODULE moduleHandle = GetModuleHandleA(fname.data());
  HGLOBAL loadedResource;
  HRSRC   resourceInfo;
  DWORD   resourceSize;

  resourceInfo = FindResource(moduleHandle, section, RT_RCDATA);
  if (!resourceInfo) {
    return false;
  }

  loadedResource = LoadResource(moduleHandle, resourceInfo);
  if (!loadedResource) {
    return false;
  }

  resourceSize = SizeofResource(moduleHandle, resourceInfo);

  desc->m_filename = fname;
  desc->m_handle = loadedResource;
  desc->m_len = resourceSize;

  return true;
#elif !defined(__APPLE__) // LINUX/ELF
  folly::symbolizer::ElfFile file;
  if (file.openNoThrow(fname.c_str()) != 0) return false;

  auto const shdr = file.getSectionByName(section);
  if (shdr == nullptr) return false;

  desc->m_filename = fname;
  desc->m_start = shdr->sh_offset;
  desc->m_len = shdr->sh_size;
  return true;
#else // __APPLE__
  const struct section_64 *sect = getsectbyname("__text", section);
  if (sect) {
    desc->m_filename = fname;
    desc->m_start = sect->offset;
    desc->m_len = sect->size;
    return !desc->m_filename.empty();
  }
#endif // __APPLE__
  return false;
}
Пример #3
0
void HeapProfileRequestHandler::handleRequest(Transport *transport) {
  const char *url = transport->getCommand().c_str();
  if (!strcmp(url, "hhprof/start")) {
    // if we can place the request, send a 200
    if (handleStartRequest(transport)) {
      transport->sendString("OK\n", 200);
    } else {
      transport->sendString("Resource Unavailable\n", 503);
    }
  } else if (!strcmp(url, "pprof/cmdline")) {
    // the first thing pprof does when you call the script is find out
    // the name of the binary running on the remote server
    transport->sendString(current_executable_path(), 200);
  } else if (!strcmp(url, "pprof/heap")) {
    // the next thing pprof does is hit this endpoint and get a profile
    // dump
    ProfileController::waitForProfile([&](const ProfileDump& dump) {
      transport->sendString(dump.toPProfFormat(), 200);
    });
  } else if (!strcmp(url, "pprof/symbol")) {
    // lastly, pprof hits this endpoint three times. the first time, it
    // hits with a HEAD request, which gives it some knowledge as to the
    // presence of the endpoint. then it hits with a GET request, and
    // expects the number of defined symbols in response. finally, it
    // hits with a POST request, with the POST data being a plus-separated
    // list of addresses for which it wants symbols
    if (transport->getMethod() == Transport::Method::HEAD) {
      transport->sendString("OK\n", 200);
    } else if (transport->getMethod() == Transport::Method::GET) {
      // actual number of sumbols is not really relevant
      // from the pprof documentation, pprof only considers values
      // that are either zero or non-zero
      transport->sendString("num_symbols: 1\n", 200);
    } else if (transport->getMethod() == Transport::Method::POST) {
      // split the post data by '+' character and resolve the symbol
      // for each
      int size;
      auto data = static_cast<const char *>(transport->getPostData(size));
      std::string res;

      std::vector<folly::StringPiece> addrs;
      folly::split('+', folly::StringPiece(data, size), addrs);
      for (const auto &addr : addrs) {
        // for each address we get from pprof, it expects a line formatted
        // like the following
        // <address>\t<symbol name>
        if (!addr.size()) {
          continue;
        }
        std::string val(addr.data(), addr.size());
        SrcKey sk = SrcKey::fromAtomicInt(
          static_cast<uint64_t>(std::stoll(val, 0, 16))
        );
        folly::toAppend(addr, "\t", sk.getSymbol(), "\n", &res);
      }
      transport->sendString(res, 200);

      if (RuntimeOption::ClientExecutionMode() &&
          RuntimeOption::HHProfServerProfileClientMode) {
        std::unique_lock<std::mutex> lock(s_clientMutex);
        s_cond = true;
        s_clientWaitq.notify_all();
      }
    }
  } else if (!strcmp(url, "hhprof/stop")) {
    // user has requested cancellation of the current profile dump
    ProfileController::cancelRequest();
    transport->sendString("OK\n", 200);
  } else {
    // the pprof server doesn't understand any other endpoints so just error
    // out
    Logger::Warning(folly::format(
      "Unknown HHProf endpoint requested, command was: {}", url
    ).str());
    transport->sendString("Not Found\n", 404);
  }
}
Пример #4
0
void StandardExtension::initMisc() {
    HHVM_FALIAS(HH\\server_warmup_status, server_warmup_status);
    HHVM_FE(connection_aborted);
    HHVM_FE(connection_status);
    HHVM_FE(connection_timeout);
    HHVM_FE(constant);
    HHVM_FE(define);
    HHVM_FE(defined);
    HHVM_FE(ignore_user_abort);
    HHVM_FE(pack);
    HHVM_FE(sleep);
    HHVM_FE(usleep);
    HHVM_FE(time_nanosleep);
    HHVM_FE(time_sleep_until);
    HHVM_FE(uniqid);
    HHVM_FE(unpack);
    HHVM_FE(sys_getloadavg);
    HHVM_FE(token_get_all);
    HHVM_FE(token_name);
    HHVM_FE(hphp_to_string);
    HHVM_FALIAS(__SystemLib\\max2, SystemLib_max2);
    HHVM_FALIAS(__SystemLib\\min2, SystemLib_min2);
    HHVM_RC_INT(PHP_MAXPATHLEN, PATH_MAX);
    Native::registerConstant<KindOfBoolean>(makeStaticString("PHP_DEBUG"),
      #if DEBUG
        true
      #else
        false
      #endif
     );
    bindTokenConstants();
    HHVM_RC_INT(T_PAAMAYIM_NEKUDOTAYIM, get_user_token_id(T_DOUBLE_COLON));

    HHVM_RC_INT(UPLOAD_ERR_OK,         0);
    HHVM_RC_INT(UPLOAD_ERR_INI_SIZE,   1);
    HHVM_RC_INT(UPLOAD_ERR_FORM_SIZE,  2);
    HHVM_RC_INT(UPLOAD_ERR_PARTIAL,    3);
    HHVM_RC_INT(UPLOAD_ERR_NO_FILE,    4);
    HHVM_RC_INT(UPLOAD_ERR_NO_TMP_DIR, 6);
    HHVM_RC_INT(UPLOAD_ERR_CANT_WRITE, 7);
    HHVM_RC_INT(UPLOAD_ERR_EXTENSION,  8);

    HHVM_RC_INT(CREDITS_GROUP,    1 << 0);
    HHVM_RC_INT(CREDITS_GENERAL,  1 << 1);
    HHVM_RC_INT(CREDITS_SAPI,     1 << 2);
    HHVM_RC_INT(CREDITS_MODULES,  1 << 3);
    HHVM_RC_INT(CREDITS_DOCS,     1 << 4);
    HHVM_RC_INT(CREDITS_FULLPAGE, 1 << 5);
    HHVM_RC_INT(CREDITS_QA,       1 << 6);
    HHVM_RC_INT(CREDITS_ALL, 0xFFFFFFFF);

    HHVM_RC_INT(INI_SYSTEM, IniSetting::PHP_INI_SYSTEM);
    HHVM_RC_INT(INI_PERDIR, IniSetting::PHP_INI_PERDIR);
    HHVM_RC_INT(INI_USER,   IniSetting::PHP_INI_USER);
    HHVM_RC_INT(INI_ALL,    IniSetting::PHP_INI_SYSTEM |
                            IniSetting::PHP_INI_PERDIR |
                            IniSetting::PHP_INI_USER);

    HHVM_RC_STR(PHP_BINARY, current_executable_path());
    HHVM_RC_STR(PHP_BINDIR, current_executable_directory());
    HHVM_RC_STR(PHP_OS, HHVM_FN(php_uname)("s").toString().toCppString());
    HHVM_RC_STR(PHP_SAPI, RuntimeOption::ExecutionMode);

    HHVM_RC_INT(PHP_INT_SIZE, sizeof(int64_t));
    HHVM_RC_INT(PHP_INT_MIN, k_PHP_INT_MIN);
    HHVM_RC_INT(PHP_INT_MAX, k_PHP_INT_MAX);

    HHVM_RC_INT_SAME(PHP_MAJOR_VERSION);
    HHVM_RC_INT_SAME(PHP_MINOR_VERSION);
    HHVM_RC_INT_SAME(PHP_RELEASE_VERSION);
    HHVM_RC_STR_SAME(PHP_EXTRA_VERSION);
    HHVM_RC_STR_SAME(PHP_VERSION);
    HHVM_RC_INT_SAME(PHP_VERSION_ID);

    // FIXME: These values are hardcoded from their previous IDL values
    // Grab their correct values from the system as appropriate
    HHVM_RC_STR(PHP_EOL, "\n");
    HHVM_RC_STR(PHP_CONFIG_FILE_PATH, "");
    HHVM_RC_STR(PHP_CONFIG_FILE_SCAN_DIR, "");
    HHVM_RC_STR(PHP_DATADIR, "");
    HHVM_RC_STR(PHP_EXTENSION_DIR, "");
    HHVM_RC_STR(PHP_LIBDIR, "");
    HHVM_RC_STR(PHP_LOCALSTATEDIR, "");
    HHVM_RC_STR(PHP_PREFIX, "");
    HHVM_RC_STR(PHP_SHLIB_SUFFIX, "so");
    HHVM_RC_STR(PHP_SYSCONFDIR, "");
    HHVM_RC_STR(PEAR_EXTENSION_DIR, "");
    HHVM_RC_STR(PEAR_INSTALL_DIR, "");

    loadSystemlib("std_misc");
  }
Пример #5
0
void DebugInfo::generatePidMapOverlay() {
  if (!m_perfMap || !pidMapOverlayStart) return;

  std::string self = current_executable_path();
  bfd* abfd = bfd_openr(self.c_str(), nullptr);
#ifdef BFD_DECOMPRESS
  abfd->flags |= BFD_DECOMPRESS;
#endif
  char **match = nullptr;
  if (!bfd_check_format(abfd, bfd_archive) &&
      bfd_check_format_matches(abfd, bfd_object, &match)) {

    std::vector<asymbol*> sorted;
    long storage_needed = bfd_get_symtab_upper_bound (abfd);

    if (storage_needed <= 0) return;

    auto symbol_table = (asymbol**)malloc(storage_needed);

    long number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);

    for (long i = 0; i < number_of_symbols; i++) {
      auto sym = symbol_table[i];
      if (sym->flags &
          (BSF_INDIRECT |
           BSF_SECTION_SYM |
           BSF_FILE |
           BSF_DEBUGGING_RELOC |
           BSF_OBJECT)) {
        continue;
      }
      auto sec = sym->section;
      if (!(sec->flags & (SEC_ALLOC|SEC_LOAD|SEC_CODE))) continue;
      auto addr = sec->vma + sym->value;
      if (addr < uintptr_t(pidMapOverlayStart) ||
          addr >= uintptr_t(pidMapOverlayEnd)) {
        continue;
      }
      sorted.push_back(sym);
    }

    std::sort(sorted.begin(), sorted.end(), [](asymbol* a, asymbol* b) {
        auto addra = a->section->vma + a->value;
        auto addrb = b->section->vma + b->value;
        if (addra != addrb) return addra < addrb;
        return strncmp("_ZN4HPHP", a->name, 8) &&
          !strncmp("_ZN4HPHP", b->name, 8);
      });

    for (size_t i = 0; i < sorted.size(); i++) {
      auto sym = sorted[i];
      auto addr = sym->section->vma + sym->value;
      int status;
      char* demangled =
        abi::__cxa_demangle(sym->name, nullptr, nullptr, &status);
      if (status != 0) demangled = const_cast<char*>(sym->name);
      unsigned size;
      if (i + 1 < sorted.size()) {
        auto s2 = sorted[i + 1];
        size = s2->section->vma + s2->value - addr;
      } else {
        size = uintptr_t(pidMapOverlayEnd) - addr;
      }
      if (!size) continue;
      fprintf(m_perfMap, "%lx %x %s\n",
              long(addr), size, demangled);
      if (status == 0) free(demangled);
    }

    free(symbol_table);
    free(match);
  }
  bfd_close(abfd);
  return;
}
Пример #6
0
void StandardExtension::initMisc() {
    HHVM_FALIAS(HH\\server_warmup_status, server_warmup_status);
    HHVM_FE(connection_aborted);
    HHVM_FE(connection_status);
    HHVM_FE(connection_timeout);
    HHVM_FE(constant);
    HHVM_FE(define);
    HHVM_FE(defined);
    HHVM_FE(ignore_user_abort);
    HHVM_FE(pack);
    HHVM_FE(sleep);
    HHVM_FE(usleep);
    HHVM_FE(time_nanosleep);
    HHVM_FE(time_sleep_until);
    HHVM_FE(uniqid);
    HHVM_FE(unpack);
    HHVM_FE(sys_getloadavg);
    HHVM_FE(token_get_all);
    HHVM_FE(token_name);
    HHVM_FE(hphp_to_string);
    HHVM_FALIAS(__SystemLib\\max2, SystemLib_max2);
    HHVM_FALIAS(__SystemLib\\min2, SystemLib_min2);
    Native::registerConstant<KindOfDouble>(makeStaticString("INF"), k_INF);
    Native::registerConstant<KindOfDouble>(makeStaticString("NAN"), k_NAN);
    Native::registerConstant<KindOfInt64>(
        makeStaticString("PHP_MAXPATHLEN"), MAXPATHLEN);
    Native::registerConstant<KindOfBoolean>(makeStaticString("PHP_DEBUG"),
      #if DEBUG
        true
      #else
        false
      #endif
     );
    bindTokenConstants();
    Native::registerConstant<KindOfInt64>(s_T_PAAMAYIM_NEKUDOTAYIM.get(),
                                          get_user_token_id(T_DOUBLE_COLON));

    HHVM_RC_STR(PHP_BINARY, current_executable_path());
    HHVM_RC_STR(PHP_BINDIR, current_executable_directory());
    HHVM_RC_STR(PHP_OS, HHVM_FN(php_uname)("s").toString().toCppString());
    HHVM_RC_STR(PHP_SAPI, RuntimeOption::ExecutionMode);

    HHVM_RC_INT(PHP_INT_SIZE, sizeof(int64_t));
    HHVM_RC_INT(PHP_INT_MIN, k_PHP_INT_MIN);
    HHVM_RC_INT(PHP_INT_MAX, k_PHP_INT_MAX);

    HHVM_RC_INT_SAME(PHP_MAJOR_VERSION);
    HHVM_RC_INT_SAME(PHP_MINOR_VERSION);
    HHVM_RC_INT_SAME(PHP_RELEASE_VERSION);
    HHVM_RC_STR_SAME(PHP_EXTRA_VERSION);
    HHVM_RC_STR_SAME(PHP_VERSION);
    HHVM_RC_INT_SAME(PHP_VERSION_ID);

    // FIXME: These values are hardcoded from their previous IDL values
    // Grab their correct values from the system as appropriate
    HHVM_RC_STR(PHP_EOL, "\n");
    HHVM_RC_STR(PHP_CONFIG_FILE_PATH, "");
    HHVM_RC_STR(PHP_CONFIG_FILE_SCAN_DIR, "");
    HHVM_RC_STR(PHP_DATADIR, "");
    HHVM_RC_STR(PHP_EXTENSION_DIR, "");
    HHVM_RC_STR(PHP_LIBDIR, "");
    HHVM_RC_STR(PHP_LOCALSTATEDIR, "");
    HHVM_RC_STR(PHP_PREFIX, "");
    HHVM_RC_STR(PHP_SHLIB_SUFFIX, "so");
    HHVM_RC_STR(PHP_SYSCONFDIR, "");
    HHVM_RC_STR(PEAR_EXTENSION_DIR, "");
    HHVM_RC_STR(PEAR_INSTALL_DIR, "");

    loadSystemlib("std_misc");
  }