LLDB mainline
SaveCoreOptions.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "lldb/Target/Process.h"
12#include "lldb/Target/Thread.h"
13
14using namespace lldb;
15using namespace lldb_private;
16
19 if (!name || !name[0]) {
20 m_plugin_name = std::nullopt;
21 return error;
22 }
23
24 std::vector<llvm::StringRef> plugin_names =
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
45
47
48std::optional<std::string> SaveCoreOptions::GetPluginName() const {
49 return m_plugin_name;
50}
51
55
56const std::optional<lldb_private::FileSpec>
58 return m_file;
59}
60
63 if (!process_sp) {
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
79 m_process_sp = process_sp;
80 return error;
81}
82
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()) {
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
105 return thread_sp && m_threads_to_save.erase(thread_sp->GetID()) > 0;
106}
107
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
116 return !m_threads_to_save.empty();
117}
118
120 const lldb_private::MemoryRegionInfo &region) {
121 m_regions_to_save.Insert(region.GetRange(), /*combine=*/true);
122}
123
129 std::string error_str;
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
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>
159 if (!m_process_sp)
160 return Status::FromErrorString("Requires a process to be set.").takeError();
161
163 if (error.Fail())
164 return error.takeError();
165
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() {
176 if (!m_process_sp)
177 return Status::FromErrorString("Requires a process to be set.").takeError();
178
180 if (error.Fail())
181 return error.takeError();
182
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 =
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
202 // Deliberately not following the formatter style here to indicate that
203 // this method will be expanded in the future.
204 m_threads_to_save.clear();
205}
206
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}
static llvm::raw_ostream & error(Stream &strm)
lldb_private::RangeVector< lldb::addr_t, lldb::addr_t > MemoryRanges
A file utility class.
Definition FileSpec.h:57
static std::vector< llvm::StringRef > GetSaveCorePluginNames()
Status SetProcess(lldb::ProcessSP process_sp)
lldb_private::Status SetPluginName(const char *name)
bool RemoveThread(lldb::ThreadSP thread_sp)
const std::optional< lldb_private::FileSpec > GetOutputFile() const
lldb::SaveCoreStyle GetStyle() const
Status AddThread(lldb::ThreadSP thread_sp)
std::optional< std::string > m_plugin_name
void SetStyle(lldb::SaveCoreStyle style)
void AddMemoryRegionToSave(const lldb_private::MemoryRegionInfo &region)
llvm::Expected< lldb_private::CoreFileMemoryRanges > GetMemoryRegionsToSave()
llvm::Expected< uint64_t > GetCurrentSizeInBytes()
std::optional< std::string > GetPluginName() const
const MemoryRanges & GetCoreFileMemoryRanges() const
std::optional< lldb::SaveCoreStyle > m_style
void SetOutputFile(lldb_private::FileSpec file)
lldb_private::ThreadCollection::collection GetThreadsToSave() const
std::unordered_set< lldb::tid_t > m_threads_to_save
bool ShouldThreadBeSaved(lldb::tid_t tid) const
std::optional< lldb_private::FileSpec > m_file
An error handling class.
Definition Status.h:118
llvm::Error takeError()
Definition Status.h:170
static Status FromErrorString(const char *str)
Definition Status.h:141
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
size_t PutChar(char ch)
Definition Stream.cpp:131
std::vector< lldb::ThreadSP > collection
lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update=true)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::Process > ProcessSP
uint64_t tid_t
Definition lldb-types.h:84