Skip to content

Commit 3bdc4c7

Browse files
kevinfreiKevin Frei
and
Kevin Frei
authored
Gsymutil aggregation similar to DwarfDump --verify (#81154)
GsymUtil, like DwarfDump --verify, spews a *lot* of data necessary to understand/diagnose issues with DWARF data. The trouble is that the kind of information necessary to make the messages useful also makes them nearly impossible to easily categorize. I put together a similar output categorizer (#79648) that will emit a summary of issues identified at the bottom of the (very verbose) output, enabling easier tracking of issues as they arise or are addressed. There's a single output change, where a message "warning: Unable to retrieve DWO .debug_info section for some object files. (Remove the --quiet flag for full output)" was being dumped the first time it was encountered (in what looks like an attempt to make something easily grep-able), but rather than keep the output in the same order, that message is now a 'category' so gets emitted at the end of the output. The test 'tools/llvm-gsymutil/X86/elf-dwo.yaml' was changed to reflect this difference. --------- Co-authored-by: Kevin Frei <[email protected]>
1 parent a38152e commit 3bdc4c7

File tree

10 files changed

+366
-233
lines changed

10 files changed

+366
-233
lines changed

llvm/include/llvm/DebugInfo/GSYM/DwarfTransformer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace gsym {
2222
struct CUInfo;
2323
struct FunctionInfo;
2424
class GsymCreator;
25+
class OutputAggregator;
2526

2627
/// A class that transforms the DWARF in a DWARFContext into GSYM information
2728
/// by populating the GsymCreator object that it is constructed with. This
@@ -52,9 +53,9 @@ class DwarfTransformer {
5253
///
5354
/// \returns An error indicating any fatal issues that happen when parsing
5455
/// the DWARF, or Error::success() if all goes well.
55-
llvm::Error convert(uint32_t NumThreads, raw_ostream *OS);
56+
llvm::Error convert(uint32_t NumThreads, OutputAggregator &OS);
5657

57-
llvm::Error verify(StringRef GsymPath, raw_ostream &OS);
58+
llvm::Error verify(StringRef GsymPath, OutputAggregator &OS);
5859

5960
private:
6061

@@ -79,7 +80,7 @@ class DwarfTransformer {
7980
/// information.
8081
///
8182
/// \param Die The DWARF debug info entry to parse.
82-
void handleDie(raw_ostream *Strm, CUInfo &CUI, DWARFDie Die);
83+
void handleDie(OutputAggregator &Strm, CUInfo &CUI, DWARFDie Die);
8384

8485
DWARFContext &DICtx;
8586
GsymCreator &Gsym;

llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace llvm {
2828

2929
namespace gsym {
3030
class FileWriter;
31+
class OutputAggregator;
3132

3233
/// GsymCreator is used to emit GSYM data to a stand alone file or section
3334
/// within a file.
@@ -360,7 +361,7 @@ class GsymCreator {
360361
/// function infos, and function infos that were merged or removed.
361362
/// \returns An error object that indicates success or failure of the
362363
/// finalize.
363-
llvm::Error finalize(llvm::raw_ostream &OS);
364+
llvm::Error finalize(OutputAggregator &OS);
364365

365366
/// Set the UUID value.
366367
///

llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@
1313

1414
namespace llvm {
1515

16-
class raw_ostream;
17-
1816
namespace object {
1917
class ObjectFile;
2018
}
2119

2220
namespace gsym {
2321

2422
class GsymCreator;
23+
class OutputAggregator;
2524

2625
class ObjectFileTransformer {
2726
public:
@@ -40,8 +39,8 @@ class ObjectFileTransformer {
4039
///
4140
/// \returns An error indicating any fatal issues that happen when parsing
4241
/// the DWARF, or Error::success() if all goes well.
43-
static llvm::Error convert(const object::ObjectFile &Obj, raw_ostream *Log,
44-
GsymCreator &Gsym);
42+
static llvm::Error convert(const object::ObjectFile &Obj,
43+
OutputAggregator &Output, GsymCreator &Gsym);
4544
};
4645

4746
} // namespace gsym
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//===- DwarfTransformer.h ---------------------------------------*- 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+
9+
#ifndef LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H
10+
#define LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H
11+
12+
#include "llvm/ADT/StringRef.h"
13+
#include "llvm/DebugInfo/GSYM/ExtractRanges.h"
14+
15+
#include <map>
16+
#include <string>
17+
18+
namespace llvm {
19+
20+
class raw_ostream;
21+
22+
namespace gsym {
23+
24+
class OutputAggregator {
25+
protected:
26+
// A std::map is preferable over an llvm::StringMap for presenting results
27+
// in a predictable order.
28+
std::map<std::string, unsigned> Aggregation;
29+
raw_ostream *Out;
30+
31+
public:
32+
OutputAggregator(raw_ostream *out) : Out(out) {}
33+
34+
size_t GetNumCategories() const { return Aggregation.size(); }
35+
36+
void Report(StringRef s, std::function<void(raw_ostream &o)> detailCallback) {
37+
Aggregation[std::string(s)]++;
38+
if (GetOS())
39+
detailCallback(*Out);
40+
}
41+
42+
void EnumerateResults(
43+
std::function<void(StringRef, unsigned)> handleCounts) const {
44+
for (auto &&[name, count] : Aggregation)
45+
handleCounts(name, count);
46+
}
47+
48+
raw_ostream *GetOS() const { return Out; }
49+
50+
// You can just use the stream, and if it's null, nothing happens.
51+
// Don't do a lot of stuff like this, but it's convenient for silly stuff.
52+
// It doesn't work with things that have custom insertion operators, though.
53+
template <typename T> OutputAggregator &operator<<(T &&value) {
54+
if (Out != nullptr)
55+
*Out << value;
56+
return *this;
57+
}
58+
59+
// For multi-threaded usage, we can collect stuff in another aggregator,
60+
// then merge it in here
61+
void Merge(const OutputAggregator &other) {
62+
for (auto &&[name, count] : other.Aggregation) {
63+
auto it = Aggregation.find(name);
64+
if (it == Aggregation.end())
65+
Aggregation.emplace(name, count);
66+
else
67+
it->second += count;
68+
}
69+
}
70+
};
71+
72+
} // namespace gsym
73+
} // namespace llvm
74+
75+
#endif // LLVM_DEBUGINFO_GSYM_OUTPUTAGGREGATOR_H

0 commit comments

Comments
 (0)