[breakpad] Add MINIDUMP_THREAD_NAME_LIST support

Change-Id: I84205358ae48e757fa3b836747eadc32c2671756
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3690389
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: Ivan Penkov <ivanpe@chromium.org>
This commit is contained in:
Ben Hamilton 2022-06-06 19:01:15 -06:00 committed by Joshua Peraza
parent 737e2cd338
commit 4d85225467
10 changed files with 399 additions and 3 deletions

View file

@ -370,6 +370,86 @@ class MinidumpThreadList : public MinidumpStream {
DISALLOW_COPY_AND_ASSIGN(MinidumpThreadList);
};
// MinidumpThreadName contains the name of a thread.
class MinidumpThreadName : public MinidumpObject {
public:
virtual ~MinidumpThreadName();
const MDRawThreadName* thread_name() const {
return valid_ ? &thread_name_ : NULL;
}
// Gets the thread ID.
virtual bool GetThreadID(uint32_t* thread_id) const;
// Print a human-readable representation of the object to stdout.
void Print();
// Returns the name of the thread.
virtual std::string GetThreadName() const;
protected:
explicit MinidumpThreadName(Minidump* minidump);
private:
// These objects are managed by MinidumpThreadNameList.
friend class MinidumpThreadNameList;
// This works like MinidumpStream::Read, but is driven by
// MinidumpThreadNameList. No size checking is done, because
// MinidumpThreadNameList handles that directly.
bool Read();
// Reads indirectly-referenced data, including the thread name.
bool ReadAuxiliaryData();
// True after a successful Read. This is different from valid_, which is not
// set true until ReadAuxiliaryData also completes successfully.
// thread_name_valid_ is only used by ReadAuxiliaryData and the functions it
// calls to determine whether the object is ready for auxiliary data to be
// read.
bool thread_name_valid_;
MDRawThreadName thread_name_;
// Cached thread name.
const string* name_;
};
// MinidumpThreadNameList contains all of the names of the threads (as
// MinidumpThreadNames) in a process.
class MinidumpThreadNameList : public MinidumpStream {
public:
virtual ~MinidumpThreadNameList();
virtual unsigned int thread_name_count() const {
return valid_ ? thread_name_count_ : 0;
}
// Sequential access to thread names.
virtual MinidumpThreadName* GetThreadNameAtIndex(unsigned int index) const;
// Print a human-readable representation of the object to stdout.
void Print();
protected:
explicit MinidumpThreadNameList(Minidump* aMinidump);
private:
friend class Minidump;
typedef vector<MinidumpThreadName> MinidumpThreadNames;
static const uint32_t kStreamType = MD_THREAD_NAME_LIST_STREAM;
bool Read(uint32_t aExpectedSize) override;
// The list of thread names.
MinidumpThreadNames* thread_names_;
uint32_t thread_name_count_;
DISALLOW_COPY_AND_ASSIGN(MinidumpThreadNameList);
};
// MinidumpModule wraps MDRawModule, which contains information about loaded
// code modules. Access is provided to various data referenced indirectly
@ -1188,6 +1268,7 @@ class Minidump {
// to avoid exposing an ugly API (GetStream needs to accept a garbage
// parameter).
virtual MinidumpThreadList* GetThreadList();
virtual MinidumpThreadNameList* GetThreadNameList();
virtual MinidumpModuleList* GetModuleList();
virtual MinidumpMemoryList* GetMemoryList();
virtual MinidumpException* GetException();

View file

@ -56,9 +56,13 @@ enum ProcessResult {
PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS, // There was more than one
// requesting thread.
PROCESS_SYMBOL_SUPPLIER_INTERRUPTED // The dump processing was
PROCESS_SYMBOL_SUPPLIER_INTERRUPTED, // The dump processing was
// interrupted by the
// SymbolSupplier(not fatal).
PROCESS_ERROR_GETTING_THREAD_NAME, // There was an error getting one
// thread's name from the dump.
};
} // namespace google_breakpad

View file

@ -111,6 +111,7 @@ class ProcessState {
const vector<MemoryRegion*>* thread_memory_regions() const {
return &thread_memory_regions_;
}
const vector<string>* thread_names() const { return &thread_names_; }
const SystemInfo* system_info() const { return &system_info_; }
const CodeModules* modules() const { return modules_; }
const CodeModules* unloaded_modules() const { return unloaded_modules_; }
@ -176,6 +177,12 @@ class ProcessState {
vector<CallStack*> threads_;
vector<MemoryRegion*> thread_memory_regions_;
// Names of each thread at the time of the crash, one for each entry in
// threads_. Note that a thread's name might be empty if there was no
// corresponding ThreadNamesStream in the minidump, or if a particular thread
// ID was not present in the THREAD_NAME_LIST.
vector<string> thread_names_;
// OS and CPU information.
SystemInfo system_info_;