DIEInfo Struct Reference

DIEInfo Struct Reference#

ROCprofiler-SDK developer API: rocprofiler::sdk::codeobj::disassembly::DIEInfo Struct Reference
ROCprofiler-SDK developer API 1.3.5
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 82 of file code_printing.hpp.

Constructor & Destructor Documentation

◆ DIEInfo()

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

Definition at line 748 of file code_printing.hpp.

749{
750 if(dwarf_tag(die) == DW_TAG_inlined_subroutine)
751 {
752 Dwarf_Addr low_pc{};
753 Dwarf_Addr high_pc{};
754
755 // Check if this inlined subroutine covers the target address
756 // First try simple contiguous range (low_pc to high_pc)
757 if(dwarf_lowpc(die, &low_pc) == 0 && dwarf_highpc(die, &high_pc) == 0)
758 {
759 addRange(DRange{low_pc, high_pc});
760 }
761 else
762 {
763 // Function may have non-contiguous ranges
764 // Check all address ranges associated with this DIE
765 Dwarf_Addr base{};
766 ptrdiff_t offset{};
767 while((offset = dwarf_ranges(die, offset, &base, &low_pc, &high_pc)) > 0)
768 addRange(DRange{low_pc, high_pc});
769 }
770
771 // Extract call site information - where this function was inlined
772 Dwarf_Attribute call_file_attr{};
773 Dwarf_Attribute call_line_attr{};
774 Dwarf_Word call_file{};
775 Dwarf_Word call_line{};
776
777 // Get the file and line number where this function was called/inlined
778 // Do not return early - children must always be traversed for nested inlining
779 if(dwarf_attr(die, DW_AT_call_file, &call_file_attr) &&
780 dwarf_attr(die, DW_AT_call_line, &call_line_attr) &&
781 dwarf_formudata(&call_file_attr, &call_file) == 0 &&
782 dwarf_formudata(&call_line_attr, &call_line) == 0)
783 {
784 // Get the compilation unit to resolve file names
785 Dwarf_Die cu_die{};
786 if(dwarf_diecu(die, &cu_die, nullptr, nullptr))
787 {
788 // Get the source files table for this compilation unit
789 Dwarf_Files* files{};
790 size_t nfiles{};
791 if(dwarf_getsrcfiles(&cu_die, &files, &nfiles) == 0 && call_file < nfiles)
792 {
793 if(const char* filename = dwarf_filesrc(files, call_file, nullptr, nullptr))
794 {
795 file_and_line = std::string(filename) + ":" + std::to_string(call_line);
796 }
797 }
798 }
799 }
800
801 // Always include this node's range so parents can find it via children_range
802 children_range = total_range;
803 }
804
805 Dwarf_Die child{};
806
807 // Traverse children (recursive part)
808 if(dwarf_child(die, &child) == 0)
809 {
810 do
811 {
812 children.emplace_back(std::make_unique<DIEInfo>(&child));
813 children_range.expand(children.back()->children_range);
814
815 } while(dwarf_siblingof(&child, &child) == 0);
816 }
817}

Member Function Documentation

◆ addRange()

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

Definition at line 133 of file code_printing.hpp.

134 {
135 all_ranges.push_back(range);
136 total_range.expand(range);
137 }

◆ 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 820 of file code_printing.hpp.

821{
822 if(!children_range.contains(addr)) return false;
823
824 bool addedOne = false;
825
826 for(auto& child : children)
827 {
828 // Only add from one of the children
829 addedOne = child->getCallStackRecursive(addr, call_stack);
830 if(addedOne) break;
831 }
832
833 if(total_range.contains(addr))
834 {
835 for(auto& range : all_ranges)
836 {
837 if(!range.contains(addr)) continue;
838
839 call_stack.emplace_back(file_and_line);
840 return true;
841 }
842 }
843
844 // Check if one of the child nodes added to the stack
845 return addedOne;
846}

Field Documentation

◆ all_ranges

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

Definition at line 123 of file code_printing.hpp.

123{};

◆ children

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

Definition at line 124 of file code_printing.hpp.

124{};

◆ children_range

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

Definition at line 129 of file code_printing.hpp.

129{};

◆ file_and_line

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

Definition at line 131 of file code_printing.hpp.

131{};

◆ total_range

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

Definition at line 127 of file code_printing.hpp.

127{};

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