brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · 6d762a6 Raw
215 lines · cpp
1//===-- SaveCoreOptions.cpp -------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Symbol/SaveCoreOptions.h"10#include "lldb/Core/PluginManager.h"11#include "lldb/Target/Process.h"12#include "lldb/Target/Thread.h"13 14using namespace lldb;15using namespace lldb_private;16 17Status SaveCoreOptions::SetPluginName(const char *name) {18  Status error;19  if (!name || !name[0]) {20    m_plugin_name = std::nullopt;21    return error;22  }23 24  std::vector<llvm::StringRef> plugin_names =25      PluginManager::GetSaveCorePluginNames();26  if (!llvm::is_contained(plugin_names, name)) {27    StreamString stream;28    stream.Printf("plugin name '%s' is not a valid ObjectFile plugin name.",29                  name);30 31    if (!plugin_names.empty()) {32      stream.PutCString(" Valid names are: ");33      std::string plugin_names_str = llvm::join(plugin_names, ", ");34      stream.PutCString(plugin_names_str);35      stream.PutChar('.');36    }37    return Status(stream.GetString().str());38  }39 40  m_plugin_name = name;41  return error;42}43 44void SaveCoreOptions::SetStyle(lldb::SaveCoreStyle style) { m_style = style; }45 46void SaveCoreOptions::SetOutputFile(FileSpec file) { m_file = file; }47 48std::optional<std::string> SaveCoreOptions::GetPluginName() const {49  return m_plugin_name;50}51 52lldb::SaveCoreStyle SaveCoreOptions::GetStyle() const {53  return m_style.value_or(lldb::eSaveCoreUnspecified);54}55 56const std::optional<lldb_private::FileSpec>57SaveCoreOptions::GetOutputFile() const {58  return m_file;59}60 61Status SaveCoreOptions::SetProcess(lldb::ProcessSP process_sp) {62  Status error;63  if (!process_sp) {64    ClearProcessSpecificData();65    m_process_sp.reset();66    return error;67  }68 69  if (!process_sp->IsValid()) {70    error = Status::FromErrorString("Cannot assign an invalid process.");71    return error;72  }73 74  // Don't clear any process specific data if the process is the same.75  if (m_process_sp == process_sp)76    return error;77 78  ClearProcessSpecificData();79  m_process_sp = process_sp;80  return error;81}82 83Status SaveCoreOptions::AddThread(lldb::ThreadSP thread_sp) {84  Status error;85  if (!thread_sp) {86    error = Status::FromErrorString("invalid thread");87    return error;88  }89 90  if (m_process_sp) {91    if (m_process_sp != thread_sp->GetProcess()) {92      error = Status::FromErrorString(93          "Cannot add a thread from a different process.");94      return error;95    }96  } else {97    m_process_sp = thread_sp->GetProcess();98  }99 100  m_threads_to_save.insert(thread_sp->GetID());101  return error;102}103 104bool SaveCoreOptions::RemoveThread(lldb::ThreadSP thread_sp) {105  return thread_sp && m_threads_to_save.erase(thread_sp->GetID()) > 0;106}107 108bool SaveCoreOptions::ShouldThreadBeSaved(lldb::tid_t tid) const {109  // If the user specified no threads to save, then we save all threads.110  if (m_threads_to_save.empty())111    return true;112  return m_threads_to_save.count(tid) > 0;113}114 115bool SaveCoreOptions::HasSpecifiedThreads() const {116  return !m_threads_to_save.empty();117}118 119void SaveCoreOptions::AddMemoryRegionToSave(120    const lldb_private::MemoryRegionInfo &region) {121  m_regions_to_save.Insert(region.GetRange(), /*combine=*/true);122}123 124const MemoryRanges &SaveCoreOptions::GetCoreFileMemoryRanges() const {125  return m_regions_to_save;126}127Status SaveCoreOptions::EnsureValidConfiguration() const {128  Status error;129  std::string error_str;130  if (!m_threads_to_save.empty() && GetStyle() == lldb::eSaveCoreFull)131    error_str += "Cannot save a full core with a subset of threads\n";132 133  if (!m_process_sp)134    error_str += "Need to assign a valid process\n";135 136  if (!error_str.empty())137    error = Status(error_str);138 139  return error;140}141 142lldb_private::ThreadCollection::collection143SaveCoreOptions::GetThreadsToSave() const {144  lldb_private::ThreadCollection::collection thread_collection;145  // In cases where no process is set, such as when no threads are specified.146  if (!m_process_sp)147    return thread_collection;148 149  ThreadList &thread_list = m_process_sp->GetThreadList();150  for (const auto &tid : m_threads_to_save)151    thread_collection.push_back(thread_list.FindThreadByID(tid));152 153  return thread_collection;154}155 156llvm::Expected<lldb_private::CoreFileMemoryRanges>157SaveCoreOptions::GetMemoryRegionsToSave() {158  Status error;159  if (!m_process_sp)160    return Status::FromErrorString("Requires a process to be set.").takeError();161 162  error = EnsureValidConfiguration();163  if (error.Fail())164    return error.takeError();165 166  CoreFileMemoryRanges ranges;167  error = m_process_sp->CalculateCoreFileSaveRanges(*this, ranges);168  if (error.Fail())169    return error.takeError();170 171  return ranges;172}173 174llvm::Expected<uint64_t> SaveCoreOptions::GetCurrentSizeInBytes() {175  Status error;176  if (!m_process_sp)177    return Status::FromErrorString("Requires a process to be set.").takeError();178 179  error = EnsureValidConfiguration();180  if (error.Fail())181    return error.takeError();182 183  CoreFileMemoryRanges ranges;184  error = m_process_sp->CalculateCoreFileSaveRanges(*this, ranges);185  if (error.Fail())186    return error.takeError();187 188  llvm::Expected<lldb_private::CoreFileMemoryRanges> core_file_ranges_maybe =189      GetMemoryRegionsToSave();190  if (!core_file_ranges_maybe)191    return core_file_ranges_maybe.takeError();192  const lldb_private::CoreFileMemoryRanges &core_file_ranges =193      *core_file_ranges_maybe;194  uint64_t total_in_bytes = 0;195  for (const auto &core_range : core_file_ranges)196    total_in_bytes += core_range.data.range.size();197 198  return total_in_bytes;199}200 201void SaveCoreOptions::ClearProcessSpecificData() {202  // Deliberately not following the formatter style here to indicate that203  // this method will be expanded in the future.204  m_threads_to_save.clear();205}206 207void SaveCoreOptions::Clear() {208  m_file = std::nullopt;209  m_plugin_name = std::nullopt;210  m_style = std::nullopt;211  m_threads_to_save.clear();212  m_process_sp.reset();213  m_regions_to_save.Clear();214}215