Zig 0.17.0-dev (Split by item)
This is an example of documentation generated by
ZigDoc , an alternative to Zig's built-in
Auto Doc feature. See also
examples in other modes/formats . The project being documented here (as the example) is the Zig library itself.
Zig › std/ › debug/ › Pdb.zig › getLineNumberInfo
getLineNumberInfo
Pdb.getLineNumberInfo
pub fn getLineNumberInfo (self : *Pdb , gpa : Allocator , module : *Module , address : u64 ) !std .debug .SourceLocation
File
Code
pub fn getLineNumberInfo (self : *Pdb , gpa : Allocator , module : *Module , address : u64 ) !std .debug .SourceLocation {
std .debug .assert (module .populated );
const subsect_info = module .subsect_info ;
var sect_offset : usize = 0 ;
var skip_len : usize = undefined ;
while (sect_offset != subsect_info .len ) : (sect_offset += skip_len ) {
const subsect_hdr : *align (1 ) pdb .DebugSubsectionHeader = @ptrCast (&subsect_info [sect_offset ]);
skip_len = subsect_hdr .length ;
sect_offset += @sizeOf (pdb .DebugSubsectionHeader );
switch (subsect_hdr .kind ) {
.lines => {
var line_index = sect_offset ;
const line_hdr : *align (1 ) pdb .LineFragmentHeader = @ptrCast (&subsect_info [line_index ]);
if (line_hdr .reloc_segment == 0 )
return error .MissingDebugInfo ;
line_index += @sizeOf (pdb .LineFragmentHeader );
const frag_vaddr_start = line_hdr .reloc_offset ;
const frag_vaddr_end = frag_vaddr_start + line_hdr .code_size ;
if (address >= frag_vaddr_start and address < frag_vaddr_end ) {
// from now on. We will iterate through them, and eventually find a SourceLocation that we're interested in,
// breaking out to :subsections. If not, we will make sure to not read anything outside of this subsection.
const subsection_end_index = sect_offset + subsect_hdr .length ;
while (line_index < subsection_end_index ) {
const block_hdr : *align (1 ) pdb .LineBlockFragmentHeader = @ptrCast (&subsect_info [line_index ]);
line_index += @sizeOf (pdb .LineBlockFragmentHeader );
const start_line_index = line_index ;
const has_column = line_hdr .flags .have_columns ;
// Heuristic: we want to find the last line entry
// that has a vaddr_start <= address.
// This is done with a simple linear search.
var line_i : u32 = 0 ;
while (line_i < block_hdr .num_lines ) : (line_i += 1 ) {
const line_num_entry : *align (1 ) pdb .LineNumberEntry = @ptrCast (&subsect_info [line_index ]);
line_index += @sizeOf (pdb .LineNumberEntry );
const vaddr_start = frag_vaddr_start + line_num_entry .offset ;
if (address < vaddr_start ) {
break ;
}
}
if (line_i > 0 ) {
const file_name = try self .getFileName (gpa , module , block_hdr .name_index );
errdefer gpa .free (file_name );
const line_entry_idx = line_i - 1 ;
const column = if (has_column ) blk : {
const start_col_index = start_line_index + @sizeOf (pdb .LineNumberEntry ) * block_hdr .num_lines ;
const col_index = start_col_index + @sizeOf (pdb .ColumnNumberEntry ) * line_entry_idx ;
const col_num_entry : *align (1 ) pdb .ColumnNumberEntry = @ptrCast (&subsect_info [col_index ]);
break :blk col_num_entry .start_column ;
} else 0 ;
const found_line_index = start_line_index + line_entry_idx * @sizeOf (pdb .LineNumberEntry );
const line_num_entry : *align (1 ) pdb .LineNumberEntry = @ptrCast (&subsect_info [found_line_index ]);
return .{
.file_name = file_name ,
.line = line_num_entry .flags .start ,
.column = column ,
};
}
}
if (line_index != subsection_end_index ) {
return error .InvalidDebugInfo ;
}
}
},
else => {},
}
if (sect_offset > subsect_info .len )
return error .InvalidDebugInfo ;
}
return error .MissingDebugInfo ;
}