Files
clang-p2996/lldb/source/Symbol/SaveCoreOptions.cpp
Jacob Lalonde 06edefac10 [LLDB] Make the thread list for SBSaveCoreOptions iterable (#122541)
This patch adds the ability to get a thread at a give index, based on
insertion order, for SBSaveCore Options. This is primarily to benefit
scripts using SBSaveCore, and remove the need to have both options and a
second collection if your script is tracking what threads need to be
saved. Such as if you want to collect the source of all the threads to
be saved after the Core is generated.
2025-01-16 11:49:02 -08:00

162 lines
4.5 KiB
C++

//===-- SaveCoreOptions.cpp -------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "lldb/Symbol/SaveCoreOptions.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
Status SaveCoreOptions::SetPluginName(const char *name) {
Status error;
if (!name || !name[0]) {
m_plugin_name = std::nullopt;
return error;
}
if (!PluginManager::IsRegisteredObjectFilePluginName(name)) {
return Status::FromErrorStringWithFormat(
"plugin name '%s' is not a valid ObjectFile plugin name", name);
return error;
}
m_plugin_name = name;
return error;
}
void SaveCoreOptions::SetStyle(lldb::SaveCoreStyle style) { m_style = style; }
void SaveCoreOptions::SetOutputFile(FileSpec file) { m_file = file; }
std::optional<std::string> SaveCoreOptions::GetPluginName() const {
return m_plugin_name;
}
lldb::SaveCoreStyle SaveCoreOptions::GetStyle() const {
return m_style.value_or(lldb::eSaveCoreUnspecified);
}
const std::optional<lldb_private::FileSpec>
SaveCoreOptions::GetOutputFile() const {
return m_file;
}
Status SaveCoreOptions::SetProcess(lldb::ProcessSP process_sp) {
Status error;
if (!process_sp) {
ClearProcessSpecificData();
m_process_sp.reset();
return error;
}
if (!process_sp->IsValid()) {
error = Status::FromErrorString("Cannot assign an invalid process.");
return error;
}
// Don't clear any process specific data if the process is the same.
if (m_process_sp == process_sp)
return error;
ClearProcessSpecificData();
m_process_sp = process_sp;
return error;
}
Status SaveCoreOptions::AddThread(lldb::ThreadSP thread_sp) {
Status error;
if (!thread_sp) {
error = Status::FromErrorString("invalid thread");
return error;
}
if (m_process_sp) {
if (m_process_sp != thread_sp->GetProcess()) {
error = Status::FromErrorString(
"Cannot add a thread from a different process.");
return error;
}
} else {
m_process_sp = thread_sp->GetProcess();
}
m_threads_to_save.insert(thread_sp->GetID());
return error;
}
bool SaveCoreOptions::RemoveThread(lldb::ThreadSP thread_sp) {
return thread_sp && m_threads_to_save.erase(thread_sp->GetID()) > 0;
}
bool SaveCoreOptions::ShouldThreadBeSaved(lldb::tid_t tid) const {
// If the user specified no threads to save, then we save all threads.
if (m_threads_to_save.empty())
return true;
return m_threads_to_save.count(tid) > 0;
}
bool SaveCoreOptions::HasSpecifiedThreads() const {
return !m_threads_to_save.empty();
}
void SaveCoreOptions::AddMemoryRegionToSave(
const lldb_private::MemoryRegionInfo &region) {
m_regions_to_save.Insert(region.GetRange(), /*combine=*/true);
}
const MemoryRanges &SaveCoreOptions::GetCoreFileMemoryRanges() const {
return m_regions_to_save;
}
Status
SaveCoreOptions::EnsureValidConfiguration(lldb::ProcessSP process_sp) const {
Status error;
std::string error_str;
if (!m_threads_to_save.empty() && GetStyle() == lldb::eSaveCoreFull)
error_str += "Cannot save a full core with a subset of threads\n";
if (m_process_sp && m_process_sp != process_sp)
error_str += "Cannot save core for process using supplied core options. "
"Options were constructed targeting a different process. \n";
if (!error_str.empty())
error = Status(error_str);
return error;
}
lldb_private::ThreadCollection::collection
SaveCoreOptions::GetThreadsToSave() const {
lldb_private::ThreadCollection::collection thread_collection;
// In cases where no process is set, such as when no threads are specified.
if (!m_process_sp)
return thread_collection;
ThreadList &thread_list = m_process_sp->GetThreadList();
for (const auto &tid : m_threads_to_save)
thread_collection.push_back(thread_list.FindThreadByID(tid));
return thread_collection;
}
void SaveCoreOptions::ClearProcessSpecificData() {
// Deliberately not following the formatter style here to indicate that
// this method will be expanded in the future.
m_threads_to_save.clear();
}
void SaveCoreOptions::Clear() {
m_file = std::nullopt;
m_plugin_name = std::nullopt;
m_style = std::nullopt;
m_threads_to_save.clear();
m_process_sp.reset();
m_regions_to_save.Clear();
}