[llvm] Added --report=debugger option to llvm-debuginfo-analyzer (PR #159853)
Carlos Alberto Enciso via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 9 01:47:00 PDT 2025
================
@@ -516,13 +517,181 @@ Error LVReader::doPrint() {
if (options().getReportParents() || options().getReportView())
if (Error Err = printScopes())
return Err;
-
+ // Requested debugger report
+ if (options().getReportDebugger())
+ if (Error Err = printDebugger())
+ return Err;
return Error::success();
}
return printScopes();
}
+namespace {
+
+struct DebuggerViewPrinter {
+ std::vector<const LVLine *> Lines;
+ std::unordered_map<LVAddress, std::vector<const LVLocation *>> LifetimeBegins;
+ std::unordered_map<LVAddress, std::vector<const LVLocation *>>
+ LifetimeEndsExclusive;
+ raw_ostream &OS;
+
+ const bool IncludeRanges = false;
+
+ void Walk(raw_ostream &OS, const LVScope *Scope) {
+ if (Scope->scopeCount()) {
+ for (const LVScope *ChildScope : *Scope->getScopes())
+ Walk(OS, ChildScope);
+ }
+ if (Scope->lineCount()) {
+ for (const LVLine *Line : *Scope->getLines()) {
+ Lines.push_back(Line);
+ }
+ }
+ if (Scope->symbolCount()) {
+ for (const LVSymbol *Symbol : *Scope->getSymbols()) {
+ LVLocations SymbolLocations;
+ Symbol->getLocations(SymbolLocations);
+ if (SymbolLocations.empty())
+ continue;
+
+ if (IncludeRanges)
+ OS << "{Range}: " << Symbol->getName() << " (line "
+ << Symbol->getLineNumber() << ")" << ": ";
+
+ for (const LVLocation *Loc : SymbolLocations) {
+ if (Loc->getIsGapEntry())
+ continue;
+
+ LVAddress Begin = Loc->getLowerAddress();
+ LVAddress End = Loc->getUpperAddress();
+ LifetimeBegins[Begin].push_back(Loc);
+ LifetimeEndsExclusive[End].push_back(Loc);
+
+ if (IncludeRanges)
+ OS << "[" << hexValue(Begin) << ":" << hexValue(End) << "] ";
+ }
+
+ if (IncludeRanges)
+ OS << "\n";
+ }
+ }
+ }
+
+ DebuggerViewPrinter(raw_ostream &OS, const LVScopeFunction *Fn) : OS(OS) {
+ Walk(OS, Fn);
+ std::sort(Lines.begin(), Lines.end(),
+ [](const LVLine *a, const LVLine *b) -> bool {
+ if (a->getAddress() != b->getAddress())
+ return a->getAddress() < b->getAddress();
+ if (a->getIsLineDebug() != b->getIsLineDebug())
+ return a->getIsLineDebug();
+ return a->getID() < b->getID();
+ });
+ }
+
+ static void PrintIndent(raw_ostream &OS, int Indent) {
+ for (int i = 0; i < Indent; i++)
+ OS << " ";
+ }
+
+ static void PrintCallstack(raw_ostream &OS, const LVScope *Scope) {
+ const LVScope *PrevScope = nullptr;
+ while (Scope) {
+ if (Scope->getIsFunction() || Scope->getIsInlinedFunction()) {
+ OS << "[" << Scope->getName();
+ if (PrevScope && PrevScope->getIsInlinedFunction()) {
+ OS << ":"
+ << cast<LVScopeFunctionInlined>(PrevScope)->getCallLineNumber();
+ }
+ OS << "]";
+ PrevScope = Scope;
+ }
+ Scope = Scope->getParentScope();
+ }
+ }
+
+ static bool IsChildScopeOf(const LVScope *A, const LVScope *B) {
+ while (A) {
+ A = A->getParentScope();
+ if (A == B)
+ return true;
+ }
+ return false;
+ }
+
+ void Print() {
+ const bool IncludeVars = options().getPrintSymbols();
+ const bool IncludeCode = options().getPrintInstructions();
+ SetVector<const LVLocation *>
+ LiveSymbols; // This needs to be ordered since we're iterating over it.
+ for (const LVLine *Line : Lines) {
+ const LVScope *Scope = Line->getParentScope();
+ // Update live list: Add lives
+ for (auto Loc : LifetimeBegins[Line->getAddress()])
+ LiveSymbols.insert(Loc);
+ // Update live list: remove dead
+ for (auto Loc : LifetimeEndsExclusive[Line->getAddress()])
+ LiveSymbols.remove(Loc);
+
+ if (Line->getIsNewStatement() && Line->getIsLineDebug() &&
+ Line->getLineNumber() != 0) {
+ auto LineDebug = cast<LVLineDebug>(Line);
+
+ PrintIndent(OS, 1);
+ OS << "{Line}: " << " [" << hexValue(LineDebug->getAddress()) << "] "
+ << LineDebug->getPathname() << ":" << LineDebug->getLineNumber()
+ << " ";
+ PrintCallstack(OS, Scope);
+ OS << "\n";
+ if (IncludeVars) {
+ for (auto SymLoc : LiveSymbols) {
+ const LVSymbol *Sym = SymLoc->getParentSymbol();
+ auto SymScope = Sym->getParentScope();
+ auto LineScope = LineDebug->getParentScope();
+ if (SymScope != LineScope && !IsChildScopeOf(LineScope, SymScope))
+ continue;
+ PrintIndent(OS, 2);
+ OS << "{Variable}: " << Sym->getName() << ": "
+ << Sym->getType()->getName() << " : ";
+ SymLoc->printLocations(OS);
+ OS << " (line " << Sym->getLineNumber() << ")";
+ OS << "\n";
+ }
+ }
+
+ } else if (IncludeCode && Line->getIsLineAssembler()) {
+ OS << " {Code}: " << " [" << hexValue(Line->getAddress()) << "] "
+ << Line->getName() << "\n";
+ }
+ }
+ }
+};
+
+} // namespace
+
+Error LVReader::printDebugger() {
+ auto *CU = getCompileUnit();
+ if (!CU)
+ return createStringError(std::make_error_code(std::errc::invalid_argument),
+ "Error: No compute unit found.");
----------------
CarlosAlbertoEnciso wrote:
May be: `compile unit`?
https://github.com/llvm/llvm-project/pull/159853
More information about the llvm-commits
mailing list