Skip to content

[lldb][progress] Add discrete boolean flag to progress reports #69516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lldb/include/lldb/Core/Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,10 +618,16 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
/// debugger identifier that this progress should be delivered to. If this
/// optional parameter does not have a value, the progress will be
/// delivered to all debuggers.
///
/// \param [in] report_type
/// Indicates whether the operation for which this progress reporting is
/// reporting on will happen as an aggregate of multiple individual
/// progress reports or not.
static void ReportProgress(uint64_t progress_id, std::string title,
std::string details, uint64_t completed,
uint64_t total,
std::optional<lldb::user_id_t> debugger_id);
std::optional<lldb::user_id_t> debugger_id,
Progress::ProgressReportType report_type);

static void ReportDiagnosticImpl(DiagnosticEventData::Type type,
std::string message,
Expand Down
11 changes: 9 additions & 2 deletions lldb/include/lldb/Core/DebuggerEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Progress.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/StructuredData.h"

Expand All @@ -21,10 +22,11 @@ class Stream;
class ProgressEventData : public EventData {
public:
ProgressEventData(uint64_t progress_id, std::string title, std::string update,
uint64_t completed, uint64_t total, bool debugger_specific)
uint64_t completed, uint64_t total, bool debugger_specific,
Progress::ProgressReportType report_type)
: m_title(std::move(title)), m_details(std::move(update)),
m_id(progress_id), m_completed(completed), m_total(total),
m_debugger_specific(debugger_specific) {}
m_debugger_specific(debugger_specific), m_report_type(report_type) {}

static llvm::StringRef GetFlavorString();

Expand Down Expand Up @@ -52,6 +54,10 @@ class ProgressEventData : public EventData {
const std::string &GetTitle() const { return m_title; }
const std::string &GetDetails() const { return m_details; }
bool IsDebuggerSpecific() const { return m_debugger_specific; }
bool IsAggregate() const {
return m_report_type ==
Progress::ProgressReportType::eAggregateProgressReport;
}

private:
/// The title of this progress event. The value is expected to remain stable
Expand All @@ -68,6 +74,7 @@ class ProgressEventData : public EventData {
uint64_t m_completed;
const uint64_t m_total;
const bool m_debugger_specific;
const Progress::ProgressReportType m_report_type;
ProgressEventData(const ProgressEventData &) = delete;
const ProgressEventData &operator=(const ProgressEventData &) = delete;
};
Expand Down
37 changes: 32 additions & 5 deletions lldb/include/lldb/Core/Progress.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ namespace lldb_private {

class Progress {
public:
/// Enum that indicates the type of progress report
enum class ProgressReportType {
eAggregateProgressReport,
eNonAggregateProgressReport
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it might be a little easier to intuit if the enums were eAggregateProgressReport and eIndividualProgressReport? Then someone might look at this and say "oh I have a single thing I'm providing progress on, I probably want eIndividualProgressReport". I don't feel strongly that I'm correct here, just throwing it out.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe eSolitaryProgressReport

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eUmbrellaProgressReport may work here since that's what's happening when we use a single progress report that's being incrementally updated.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eUmbrellaProgressReport may work here since that's what's happening when we use a single progress report that's being incrementally updated.

What is happening multiple times a session? We only index the DWARF one time where we have N DWARF units that we index, but that doesn't happen at all for dSYM files. Symbol tables are parsed only once, but we do parse the symbol tables for each library. What is happening multiple times and how are we going to be able to group these?

Would it be better to use progress category as a string instead of a bool? I will make some inline comments to clarify this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my understanding something like symbol table parsing can happen multiple times per session if new symbol tables need to be parsed due to new libraries being added. We want to send the progress events to the IDE team who can then filter the events based on this enum.

};
Comment on lines +59 to +62
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might need to belong in lldb-enumerations if we want SBDebugger::GetProgressFromEvent(...) to have an overload where this is supplied.

/// Construct a progress object that will report information.
///
/// The constructor will create a unique progress reporting object and
Expand All @@ -63,13 +68,30 @@ class Progress {
///
/// @param [in] title The title of this progress activity.
///
/// @param [in] total The total units of work to be done if specified, if
/// set to UINT64_MAX then an indeterminate progress indicator should be
/// @param [in] report_type Enum value indicating how the progress is being
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally these start with @param [in] variable_name, and then on the next line the description starts. I see @clayborg wrote the current header in this style, maybe it was a clang-format artifact? Or possibly the preferred style has shifted while I wasn't paying attention.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've clang-formatted these files and that didn't change this comment style so I guess clang-format is just going with was already here, strange 🤔

/// reported. Progress reports considered "aggregate" are reports done for
/// operations that may happen multiple times during a debug session.
///
/// For example, when a debug session is first started it needs to parse the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the case that I attach to a running process and I find 100 binaries loaded in the process. I create Module/ObjectFile's for each binary, including parsing the symbol table, possibly looking for a dSYM or a dwp symbol file with debug information for each of those. If dSYMs are an example of additional binaries that may need to be scanned (and report progress as they're being scanned), is it sufficient to simply mention how each of the hundred binaries in the process will report a status update as its Module is created, and not mention dSYMs specifically?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd want to use this enum to indicate that parsing symbol tables and loading DWARF indices. I used the term dSYM in this example which makes it look like this is a macOS specific issue when it's more generic so I'll change this, thanks for noticing!

/// symbol tables for all files that were initially included and this
/// operation will deliver progress reports. If new symbol tables need to be
/// parsed later during the session then these will also be parsed and deliver
/// more progress reports. This type of operation would use the
/// eAggregateProgressReport enum. Using this enum would allow these progress
/// reports to be grouped together as one, even though their reports are
/// happening individually.
///
/// @param [in] total Optional total units of work to be done if specified, if
/// unset then an indeterminate progress indicator should be
/// displayed.
///
/// @param [in] debugger An optional debugger pointer to specify that this
/// progress is to be reported only to specific debuggers.
Progress(std::string title, uint64_t total = UINT64_MAX,
///
Progress(std::string title,
ProgressReportType report_type =
ProgressReportType::eNonAggregateProgressReport,
std::optional<uint64_t> total = std::nullopt,
lldb_private::Debugger *debugger = nullptr);

/// Destroy the progress object.
Expand Down Expand Up @@ -97,12 +119,17 @@ class Progress {
/// The title of the progress activity.
std::string m_title;
std::mutex m_mutex;
/// Set to eAggregateProgressReport if the progress event is aggregate;
/// meaning it will happen multiple times during a debug session as individual
/// progress events
ProgressReportType m_report_type =
ProgressReportType::eNonAggregateProgressReport;
/// A unique integer identifier for progress reporting.
const uint64_t m_id;
/// How much work ([0...m_total]) that has been completed.
uint64_t m_completed;
/// Total amount of work, UINT64_MAX for non deterministic progress.
const uint64_t m_total;
/// Total amount of work, use a std::nullopt for non deterministic progress.
const std::optional<uint64_t> m_total;
/// The optional debugger ID to report progress to. If this has no value then
/// all debuggers will receive this event.
std::optional<lldb::user_id_t> m_debugger_id;
Expand Down
17 changes: 10 additions & 7 deletions lldb/source/Core/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Progress.h"
#include "lldb/Core/StreamAsynchronousIO.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Expression/REPL.h"
Expand Down Expand Up @@ -1421,22 +1422,24 @@ void Debugger::SetDestroyCallback(
static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id,
std::string title, std::string details,
uint64_t completed, uint64_t total,
bool is_debugger_specific) {
bool is_debugger_specific,
Progress::ProgressReportType report_type) {
// Only deliver progress events if we have any progress listeners.
const uint32_t event_type = Debugger::eBroadcastBitProgress;
if (!debugger.GetBroadcaster().EventTypeHasListeners(event_type))
return;
EventSP event_sp(new Event(
event_type,
new ProgressEventData(progress_id, std::move(title), std::move(details),
completed, total, is_debugger_specific)));
event_type, new ProgressEventData(progress_id, std::move(title),
std::move(details), completed, total,
is_debugger_specific, report_type)));
debugger.GetBroadcaster().BroadcastEvent(event_sp);
}

void Debugger::ReportProgress(uint64_t progress_id, std::string title,
std::string details, uint64_t completed,
uint64_t total,
std::optional<lldb::user_id_t> debugger_id) {
std::optional<lldb::user_id_t> debugger_id,
Progress::ProgressReportType report_type) {
// Check if this progress is for a specific debugger.
if (debugger_id) {
// It is debugger specific, grab it and deliver the event if the debugger
Expand All @@ -1445,7 +1448,7 @@ void Debugger::ReportProgress(uint64_t progress_id, std::string title,
if (debugger_sp)
PrivateReportProgress(*debugger_sp, progress_id, std::move(title),
std::move(details), completed, total,
/*is_debugger_specific*/ true);
/*is_debugger_specific*/ true, report_type);
return;
}
// The progress event is not debugger specific, iterate over all debuggers
Expand All @@ -1455,7 +1458,7 @@ void Debugger::ReportProgress(uint64_t progress_id, std::string title,
DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos)
PrivateReportProgress(*(*pos), progress_id, title, details, completed,
total, /*is_debugger_specific*/ false);
total, /*is_debugger_specific*/ false, report_type);
}
}

Expand Down
1 change: 1 addition & 0 deletions lldb/source/Core/DebuggerEvents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ ProgressEventData::GetAsStructuredData(const Event *event_ptr) {
dictionary_sp->AddIntegerItem("total", progress_data->GetTotal());
dictionary_sp->AddBooleanItem("debugger_specific",
progress_data->IsDebuggerSpecific());
dictionary_sp->AddBooleanItem("is_aggregate", progress_data->IsAggregate());

return dictionary_sp;
}
Expand Down
18 changes: 11 additions & 7 deletions lldb/source/Core/Progress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Utility/StreamString.h"

#include <optional>

using namespace lldb;
using namespace lldb_private;

std::atomic<uint64_t> Progress::g_id(0);

Progress::Progress(std::string title, uint64_t total,
Progress::Progress(std::string title, ProgressReportType report_type,
std::optional<uint64_t> total,
lldb_private::Debugger *debugger)
: m_title(title), m_id(++g_id), m_completed(0), m_total(total) {
: m_title(title), m_report_type(report_type), m_id(++g_id), m_completed(0),
m_total(total) {
assert(total > 0);
if (debugger)
m_debugger_id = debugger->GetID();
Expand All @@ -31,7 +35,7 @@ Progress::~Progress() {
// destructed so it indicates the progress dialog/activity should go away.
std::lock_guard<std::mutex> guard(m_mutex);
if (!m_completed)
m_completed = m_total;
m_completed = m_total.value();
ReportProgress();
}

Expand All @@ -40,8 +44,8 @@ void Progress::Increment(uint64_t amount, std::string update) {
std::lock_guard<std::mutex> guard(m_mutex);
// Watch out for unsigned overflow and make sure we don't increment too
// much and exceed m_total.
if (amount > (m_total - m_completed))
m_completed = m_total;
if (amount > (m_total.value() - m_completed))
m_completed = m_total.value();
else
m_completed += amount;
ReportProgress(update);
Expand All @@ -52,8 +56,8 @@ void Progress::ReportProgress(std::string update) {
if (!m_complete) {
// Make sure we only send one notification that indicates the progress is
// complete.
m_complete = m_completed == m_total;
m_complete = m_completed == m_total.value();
Debugger::ReportProgress(m_id, m_title, std::move(update), m_completed,
m_total, m_debugger_id);
m_total.value(), m_debugger_id, m_report_type);
}
}
3 changes: 2 additions & 1 deletion lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2225,7 +2225,8 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
const char *file_name = file.GetFilename().AsCString("<Unknown>");
LLDB_SCOPED_TIMERF("ObjectFileMachO::ParseSymtab () module = %s", file_name);
LLDB_LOG(log, "Parsing symbol table for {0}", file_name);
Progress progress(llvm::formatv("Parsing symbol table for {0}", file_name));
Progress progress(llvm::formatv("Parsing symbol table for {0}", file_name),
Progress::ProgressReportType::eAggregateProgressReport);
Comment on lines +2228 to +2229
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a progress category as a string instead of a report type? Then this would be easy to group all of symbol table parsing into one section.

std::string category("Symbol table parsing");
Progress progress(llvm::formatv("Parsing symbol table for {0}", file_name), category);

I used a local variable for the category for clarity

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the functionality to add details to a progress report was added in LLDB we wanted to group operations under large progress reports and then incrementally update them but we found that there was no easy place to do that for symbol table and debug info operations so for now, we want to us a flag to indicate to a UI how these operations are reported.

We did find that it was possible to group Swift-based operations into their own large progress reports (swiftlang#7769) and so we'd want to have these operations be the "non-aggregate/umbrella" operations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a string to represent the category (one of a possible vector of strings for each operation even?) looks like a good idea though.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a string to represent the category (one of a possible vector of strings for each operation even?) looks like a good idea though.

Seems to me that a category string that could be anything ("Parsing symbol tables" or "Indexing DWARF" or "Parsing DWARF") would allow us to group similar notifications together in an IDE better than a single ProgressReportType::eAggregateProgressReport vs ProgressReportType::eNonAggregateProgressReport enum value. With this solution, does this mean that all notifications that with is_aggregate == true would show up in one area and is_aggregate == false would show up another area? If we use a category string, any concurrent notifications that share the same category could show up under some UI that displayed the category string and allowed it to be expanded

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention is that if is_aggregate == false then the progress report type can be grouped together in LLDB under one large umbrella progress report for that operation whereas if is_aggregate == true then the IDE could potentially filter out those progress reports since each progress report happening individually means that they look spammy in an IDE.

Instead of using a string as a category field we could have each progress report type/category be an enum in lldb_enumerations.h i.e. ProgressReportType/Category == eProgressSymbolTableParse or eProgressDWARFIndexing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we looked at how to group progress notifications by is_aggregate we found that although the symbol table/DWARF progress notifications would be grouped under is_aggregate == true, long-running operations related to Swift (importing/loading Swift modules etc.) could actually be grouped under is_aggregate == false which allows the IDE team to display and group those notifications. (swiftlang#7769). We want to integrate this enum flag into the Swift progress reports once landed.

That being said, this does group long-running LLDB notifications as all being too spammy to show since we couldn't group them together under umbrella progress reports. We don't want to keep it this way forever as ultimately we'd like to group all categories of progress reports under their own umbrella Progress objects instead of sending several individual progress reports, but this is what we're doing right now to help the IDE have more streamlined UI progress reports.

We also thought about going with the timeout approach that you suggested but ran into similar issues as you mentioned wherein if many reports were too short then they wouldn't get displayed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we do want all of the reports to be sent, this seems like a GUI / display issue that can be solved with category names. For you guys the DWARF isn't a big contributor and we want to always see those since on linux a lot of DWARF is not indexed and that is a major contributor to our startup times. Symbol table parsing takes time on mac and linux as well. So everyone is going to classify what progress is interesting in their own way. With a single enum for what Apple users might consider "aggregate" doesn't match up with what Linux or other users consider aggregate and we are now going to be hard coded this into the progress objectsd and that is what is worrying me about the current approach.

The user interface is what needs to figure out how to display these things efficiently and the category string seems to allow user interfaces to do more grouping in more efficient ways. The boolean of is_aggregate is a bit too coarse. With the category strings like "Parsing symbol tables" or "Manually Indexing DWARF" or "Loading DWARF accelerator tables", it would allow spammy stuff to be noticed on the, and then instead of displaying individual entries, it would display a single entry with the category name and a spinning progress GUI. Of course you could hard code things based on the category name all the time in Xcode so that "Parsing symbol tables" and "Loading DWARF accelerator tables" would always be grouped if desired to keep the noise down.

If no one else agrees with me here, please let me know

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clayborg I understand your point but how would a category string be different from filtering out the progress events based on the progress title string (or parts of it) ?

I see how certain progress reports could be relevant to linux where we wouldn't want to surface it on macOS. The reason we came up with this approach is precisely because we prefer having LLDB tell its clients what progress should be displayed, rather than having the filtering logic be done in the client.

May we could keep a list of blacklisted progress title / categories for every platform and either submit progress reports if they're not in that list or have an SBAPI to fetch the list of blacklisted progresses from the client ? What do you think about this ?

(also cc @JDevlieghere since he will probably have some opinions about this).

Copy link
Collaborator

@clayborg clayborg Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clayborg I understand your point but how would a category string be different from filtering out the progress events based on the progress title string (or parts of it) ?

It would stop clients from having to add logic to try and look for common substrings, but other than that not much different. It would allow progress titles to vary quite a bit more, but they don't right now.

I see how certain progress reports could be relevant to linux where we wouldn't want to surface it on macOS. The reason we came up with this approach is precisely because we prefer having LLDB tell its clients what progress should be displayed, rather than having the filtering logic be done in the client.

Not sure I follow? Are you saying if is_aggregate == true that we are letting users know they should ignore these progress reports? And we are setting to true for all progress reports except for Swift and a few other rarely used ones?

May we could keep a list of blacklisted progress title / categories for every platform and either submit progress reports if they're not in that list or have an SBAPI to fetch the list of blacklisted progresses from the client ? What do you think about this ?

One ideas is if we have categories, we could have settings that could control if the progress reports for a given category should be displayed. Those could easily be set after initializing a debugger object.

(also cc @JDevlieghere since he will probably have some opinions about this).

Sounds good

The entire idea of the progress dialogs is to provide insight for when the debugger seems to be stalled, but it is actually doing work. If we have any progress items that are not useful, we should remove them. But parsing symbol tables, even on Mac, can sometimes take a few seconds on larger binaries, so I find this useful when running LLDB from the command line. Indexing DWARF is a huge time sync for really large projects which often can take many minutes to complete and when I load them on the command line, seeing the progress in the terminal is very useful.

So a few things that seem to stand out to me:

  • Darwin will never see the Manually indexing DWARF for <path> progress dialogs, and these are needed and should always be displayed.
  • Darwin does see the Parsing symbol table for <path> progress dialogs, but many are fast and probably are part of the problem you want to fix?
  • Loading Apple DWARF index for <path> has no real work being done here, just initializing a memory buffer, seems like it should probably be removed to cut down on the noise?
  • Loading DWARF5 index for <path> is the same kind of thing for both Darwin and linux (no real work to be done, the accelerator tables are "ready to use") so maybe we should remove them?
  • Locating external symbol file for <path> seems useful if the download can take a while

I don't see any other uses in the upstream LLDB sources.

But my main point is we make Progress dialogs for a reason and we should make sure they are useful and that everyone wants them.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if we want to allow different platforms to say what is useful and what isn't we can provide commands to control these if needed. We can have an internal enumeration for the categories if needed, or we can add a string as the category to help say "please disable all symbol table parsing" progress dialogs.


llvm::MachO::symtab_command symtab_load_command = {0, 0, 0, 0, 0, 0};
llvm::MachO::linkedit_data_command function_starts_load_command = {0, 0, 0, 0};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void ManualDWARFIndex::Index() {
const uint64_t total_progress = units_to_index.size() * 2 + 8;
Progress progress(
llvm::formatv("Manually indexing DWARF for {0}", module_desc.GetData()),
total_progress);
Progress::ProgressReportType::eAggregateProgressReport, total_progress);

std::vector<IndexSet> sets(units_to_index.size());

Expand Down
6 changes: 4 additions & 2 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,8 @@ void SymbolFileDWARF::InitializeObject() {
if (apple_names.GetByteSize() > 0 || apple_namespaces.GetByteSize() > 0 ||
apple_types.GetByteSize() > 0 || apple_objc.GetByteSize() > 0) {
Progress progress(llvm::formatv("Loading Apple DWARF index for {0}",
module_desc.GetData()));
module_desc.GetData()),
Progress::ProgressReportType::eAggregateProgressReport);
m_index = AppleDWARFIndex::Create(
*GetObjectFile()->GetModule(), apple_names, apple_namespaces,
apple_types, apple_objc, m_context.getOrLoadStrData());
Expand All @@ -485,7 +486,8 @@ void SymbolFileDWARF::InitializeObject() {
LoadSectionData(eSectionTypeDWARFDebugNames, debug_names);
if (debug_names.GetByteSize() > 0) {
Progress progress(
llvm::formatv("Loading DWARF5 index for {0}", module_desc.GetData()));
llvm::formatv("Loading DWARF5 index for {0}", module_desc.GetData()),
Progress::ProgressReportType::eAggregateProgressReport);
llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> index_or =
DebugNamesDWARFIndex::Create(*GetObjectFile()->GetModule(),
debug_names,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,14 @@ def test_dwarf_symbol_loading_progress_report_structured_data(self):

event = lldbutil.fetch_next_event(self, self.listener, self.broadcaster)
progress_data = lldb.SBDebugger.GetProgressDataFromEvent(event)
message = progress_data.GetValueForKey("message").GetStringValue(100)
self.assertGreater(len(message), 0)
title = progress_data.GetValueForKey("title").GetStringValue(100)
self.assertGreater(len(title), 0)

is_aggregate = progress_data.GetValueForKey("is_aggregate")
self.assertTrue(
is_aggregate.IsValid(),
"ProgressEventData key 'is_aggregate' does not exist.",
)
self.assertTrue(
is_aggregate, "ProgressEventData key 'is_aggregate' should be true."
)