DIEInfo Struct Reference

DIEInfo Struct Reference#

ROCprofiler-SDK developer API: rocprofiler::sdk::codeobj::disassembly::DIEInfo Struct Reference
ROCprofiler-SDK developer API 1.0.0
ROCm Profiling API and tools
rocprofiler::sdk::codeobj::disassembly::DIEInfo Struct Reference

Extracts inlined function call stack information for a given address. More...

#include <rocprofiler-sdk/cxx/codeobj/code_printing.hpp>

+ Collaboration diagram for rocprofiler::sdk::codeobj::disassembly::DIEInfo:

Public Member Functions

 DIEInfo (Dwarf_Die *die)
 
bool getCallStackRecursive (Dwarf_Addr addr, std::vector< std::string > &call_stack)
 Recursively traverses all children DIEInfos to find inlined functions at a specific address.
 
void addRange (const DRange &range)
 

Data Fields

std::vector< DRange > all_ranges {}
 
std::vector< std::unique_ptr< DIEInfo > > children {}
 
DRange total_range {}
 
DRange children_range {}
 
std::string file_and_line {}
 

Detailed Description

Extracts inlined function call stack information for a given address.

This struct is used to recursively search through DWARF debug information to find all inlined functions that contain the specified address, building a complete call stack from the outermost function down to the innermost inlined function.

Definition at line 79 of file code_printing.hpp.

Constructor & Destructor Documentation

◆ DIEInfo()

rocprofiler::sdk::codeobj::disassembly::DIEInfo::DIEInfo ( Dwarf_Die *  die)
inline

Definition at line 526 of file code_printing.hpp.

527{
528 if(dwarf_tag(die) == DW_TAG_inlined_subroutine)
529 {
530 Dwarf_Addr low_pc{};
531 Dwarf_Addr high_pc{};
532
533 // Check if this inlined subroutine covers the target address
534 // First try simple contiguous range (low_pc to high_pc)
535 if(dwarf_lowpc(die, &low_pc) == 0 && dwarf_highpc(die, &high_pc) == 0)
536 {
537 addRange(DRange{low_pc, high_pc});
538 }
539 else
540 {
541 // Function may have non-contiguous ranges
542 // Check all address ranges associated with this DIE
543 Dwarf_Addr base{};
544 ptrdiff_t offset{};
545 while((offset = dwarf_ranges(die, offset, &base, &low_pc, &high_pc)) > 0)
546 addRange(DRange{low_pc, high_pc});
547 }
548
549 // Extract call site information - where this function was inlined
550 Dwarf_Attribute call_file_attr{};
551 Dwarf_Attribute call_line_attr{};
552 Dwarf_Word call_file{};
553 Dwarf_Word call_line{};
554
555 // Get the file and line number where this function was called/inlined
556
557 if(!dwarf_attr(die, DW_AT_call_file, &call_file_attr) ||
558 !dwarf_attr(die, DW_AT_call_line, &call_line_attr) ||
559 dwarf_formudata(&call_file_attr, &call_file) != 0 ||
560 dwarf_formudata(&call_line_attr, &call_line) != 0)
561 return; // No call site information available
562
563 // Get the compilation unit to resolve file names
564 Dwarf_Die cu_die{};
565 if(!dwarf_diecu(die, &cu_die, nullptr, nullptr)) return;
566
567 // Get the source files table for this compilation unit
568 Dwarf_Files* files{};
569 size_t nfiles{};
570 if(dwarf_getsrcfiles(&cu_die, &files, &nfiles) == 0 && call_file < nfiles)
571 {
572 if(const char* filename = dwarf_filesrc(files, call_file, nullptr, nullptr))
573 {
574 // Add "filename:line" to call stack showing where this function was inlined
575 file_and_line = std::string(filename) + ":" + std::to_string(call_line);
576 return;
577 }
578 }
579
580 children_range = total_range;
581 }
582
583 Dwarf_Die child{};
584
585 // Traverse children (recursive part)
586 if(dwarf_child(die, &child) == 0)
587 {
588 do
589 {
590 children.emplace_back(std::make_unique<DIEInfo>(&child));
591 children_range.expand(children.back()->children_range);
592
593 } while(dwarf_siblingof(&child, &child) == 0);
594 }
595}

Member Function Documentation

◆ addRange()

void rocprofiler::sdk::codeobj::disassembly::DIEInfo::addRange ( const DRange &  range)
inline

Definition at line 130 of file code_printing.hpp.

131 {
132 all_ranges.push_back(range);
133 total_range.expand(range);
134 }

◆ getCallStackRecursive()

bool rocprofiler::sdk::codeobj::disassembly::DIEInfo::getCallStackRecursive ( Dwarf_Addr  addr,
std::vector< std::string > &  call_stack 
)
inline

Recursively traverses all children DIEInfos to find inlined functions at a specific address.

This function performs a depth-first traversal of the DWARF debug information tree, checking each DIE for inlined function information that covers the specified address. It processes both the current DIE and all its children (including siblings at each level) to ensure comprehensive coverage of all possible inlined function contexts.

The traversal is necessary because inlined functions can be nested (function A inlines function B which inlines function C) and multiple inlined functions can exist at the same scope level as siblings in the DWARF tree.

Parameters
addrThe address to search for inlined function information
call_stackReference to vector that accumulates the call stack information
Returns
True if either this instance or one of the children added an entry to the stack

Definition at line 598 of file code_printing.hpp.

599{
600 if(!children_range.contains(addr)) return false;
601
602 bool addedOne = false;
603
604 for(auto& child : children)
605 {
606 // Only add from one of the children
607 addedOne = child->getCallStackRecursive(addr, call_stack);
608 if(addedOne) break;
609 }
610
611 if(total_range.contains(addr))
612 {
613 for(auto& range : all_ranges)
614 {
615 if(!range.contains(addr)) continue;
616
617 call_stack.emplace_back(file_and_line);
618 return true;
619 }
620 }
621
622 // Check if one of the child nodes added to the stack
623 return addedOne;
624}

Field Documentation

◆ all_ranges

std::vector<DRange> rocprofiler::sdk::codeobj::disassembly::DIEInfo::all_ranges {}

Definition at line 120 of file code_printing.hpp.

120{};

◆ children

std::vector<std::unique_ptr<DIEInfo> > rocprofiler::sdk::codeobj::disassembly::DIEInfo::children {}

Definition at line 121 of file code_printing.hpp.

121{};

◆ children_range

DRange rocprofiler::sdk::codeobj::disassembly::DIEInfo::children_range {}

Definition at line 126 of file code_printing.hpp.

126{};

◆ file_and_line

std::string rocprofiler::sdk::codeobj::disassembly::DIEInfo::file_and_line {}

Definition at line 128 of file code_printing.hpp.

128{};

◆ total_range

DRange rocprofiler::sdk::codeobj::disassembly::DIEInfo::total_range {}

Definition at line 124 of file code_printing.hpp.

124{};

The documentation for this struct was generated from the following file: