示例#1
0
Error ModuleCache::GetAndPut(const FileSpec &root_dir_spec,
                             const char *hostname,
                             const ModuleSpec &module_spec,
                             const ModuleDownloader &module_downloader,
                             const SymfileDownloader &symfile_downloader,
                             lldb::ModuleSP &cached_module_sp,
                             bool *did_create_ptr) {
  const auto module_spec_dir =
      GetModuleDirectory(root_dir_spec, module_spec.GetUUID());
  auto error = MakeDirectory(module_spec_dir);
  if (error.Fail())
    return error;

  ModuleLock lock(root_dir_spec, module_spec.GetUUID(), error);
  if (error.Fail())
    return Error("Failed to lock module %s: %s",
                 module_spec.GetUUID().GetAsString().c_str(),
                 error.AsCString());

  const auto escaped_hostname(GetEscapedHostname(hostname));
  // Check local cache for a module.
  error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec,
              cached_module_sp, did_create_ptr);
  if (error.Success())
    return error;

  const auto tmp_download_file_spec = JoinPath(module_spec_dir, kTempFileName);
  error = module_downloader(module_spec, tmp_download_file_spec);
  llvm::FileRemover tmp_file_remover(tmp_download_file_spec.GetPath().c_str());
  if (error.Fail())
    return Error("Failed to download module: %s", error.AsCString());

  // Put downloaded file into local module cache.
  error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
              tmp_download_file_spec, module_spec.GetFileSpec());
  if (error.Fail())
    return Error("Failed to put module into cache: %s", error.AsCString());

  tmp_file_remover.releaseFile();
  error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec,
              cached_module_sp, did_create_ptr);
  if (error.Fail())
    return error;

  // Fetching a symbol file for the module
  const auto tmp_download_sym_file_spec =
      JoinPath(module_spec_dir, kTempSymFileName);
  error = symfile_downloader(cached_module_sp, tmp_download_sym_file_spec);
  llvm::FileRemover tmp_symfile_remover(
      tmp_download_sym_file_spec.GetPath().c_str());
  if (error.Fail())
    // Failed to download a symfile but fetching the module was successful. The
    // module might
    // contain the necessary symbols and the debugging is also possible without
    // a symfile.
    return Error();

  error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
              tmp_download_sym_file_spec,
              GetSymbolFileSpec(module_spec.GetFileSpec()));
  if (error.Fail())
    return Error("Failed to put symbol file into cache: %s", error.AsCString());

  tmp_symfile_remover.releaseFile();

  FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec());
  cached_module_sp->SetSymbolFileFileSpec(symfile_spec);
  return Error();
}
示例#2
0
Error
ModuleCache::GetAndPut (const FileSpec &root_dir_spec,
                        const char *hostname,
                        const ModuleSpec &module_spec,
                        const ModuleDownloader &module_downloader,
                        const SymfileDownloader &symfile_downloader,
                        lldb::ModuleSP &cached_module_sp,
                        bool *did_create_ptr)
{
    const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_spec.GetUUID ());
    auto error = MakeDirectory (module_spec_dir);
    if (error.Fail ())
        return error;

    // Open lock file.
    const auto lock_file_spec = JoinPath (module_spec_dir, kLockFileName);
    File lock_file (lock_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec);
    if (!lock_file)
    {
        error.SetErrorToErrno ();
        return Error("Failed to open lock file %s: %s", lock_file_spec.GetPath ().c_str (), error.AsCString ());
    }
    LockFile lock (lock_file.GetDescriptor ());
    error = lock.WriteLock (0, 1);
    if (error.Fail ())
        return Error("Failed to lock file %s:%s", lock_file_spec.GetPath ().c_str (), error.AsCString ());

    // Check local cache for a module.
    error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr);
    if (error.Success ())
        return error;

    const auto tmp_download_file_spec = JoinPath (module_spec_dir, kTempFileName);
    error = module_downloader (module_spec, tmp_download_file_spec);
    llvm::FileRemover tmp_file_remover (tmp_download_file_spec.GetPath ().c_str ());
    if (error.Fail ())
        return Error("Failed to download module: %s", error.AsCString ());

    // Put downloaded file into local module cache.
    error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec, module_spec.GetFileSpec ());
    if (error.Fail ())
        return Error ("Failed to put module into cache: %s", error.AsCString ());

    tmp_file_remover.releaseFile ();
    error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr);
    if (error.Fail ())
        return error;

    // Fetching a symbol file for the module
    const auto tmp_download_sym_file_spec = JoinPath (module_spec_dir, kTempSymFileName);
    error = symfile_downloader (cached_module_sp, tmp_download_sym_file_spec);
    llvm::FileRemover tmp_symfile_remover (tmp_download_sym_file_spec.GetPath ().c_str ());
    if (error.Fail ())
        // Failed to download a symfile but fetching the module was successful. The module might
        // contain the neccessary symbols and the debugging is also possible without a symfile.
        return Error ();

    FileSpec symfile_spec = GetSymbolFileSpec (cached_module_sp->GetFileSpec ());
    error = Put (root_dir_spec, hostname, module_spec, tmp_download_sym_file_spec, symfile_spec);
    if (error.Fail ())
        return Error ("Failed to put symbol file into cache: %s", error.AsCString ());
    
    tmp_symfile_remover.releaseFile();

    cached_module_sp->SetSymbolFileFileSpec (symfile_spec);
    return Error ();
}