Skip to content

Commit

Permalink
Merge pull request #206 from philipc/tests
Browse files Browse the repository at this point in the history
Add self-parse tests and benchmarks for .debug_loc and .debug_ranges
  • Loading branch information
fitzgen committed Jun 13, 2017
2 parents 9f8075d + c7a869a commit f63bac1
Show file tree
Hide file tree
Showing 2 changed files with 208 additions and 4 deletions.
112 changes: 110 additions & 2 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
extern crate gimli;
extern crate test;

use gimli::{DebugAbbrev, DebugAranges, DebugInfo, DebugLine, DebugLineOffset, DebugPubNames,
DebugPubTypes, LittleEndian, EntriesTreeIter};
use gimli::{DebugAbbrev, DebugAranges, DebugInfo, DebugLine, DebugLineOffset, DebugLoc,
DebugPubNames, DebugPubTypes, DebugRanges, LittleEndian, EntriesTreeIter};
use std::env;
use std::fs::File;
use std::io::Read;
Expand Down Expand Up @@ -185,6 +185,114 @@ fn bench_executing_line_number_programs(b: &mut test::Bencher) {
});
}

#[bench]
fn bench_parsing_debug_loc(b: &mut test::Bencher) {
let debug_info = read_section("debug_info");
let debug_info = DebugInfo::<LittleEndian>::new(&debug_info);

let debug_abbrev = read_section("debug_abbrev");
let debug_abbrev = DebugAbbrev::<LittleEndian>::new(&debug_abbrev);

let debug_loc = read_section("debug_loc");
let debug_loc = DebugLoc::<LittleEndian>::new(&debug_loc);

let mut offsets = Vec::new();

let mut iter = debug_info.units();
while let Some(unit) = iter.next().expect("Should parse compilation unit") {
let abbrevs = unit.abbreviations(debug_abbrev)
.expect("Should parse abbreviations");

let mut cursor = unit.entries(&abbrevs);
cursor.next_dfs().expect("Should parse next dfs");

let mut low_pc = 0;

{
let unit_entry = cursor.current().expect("Should have a root entry");
let low_pc_attr = unit_entry
.attr_value(gimli::DW_AT_low_pc)
.expect("Should parse low_pc");
if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
low_pc = address;
}
}

while cursor.next_dfs().expect("Should parse next dfs").is_some() {
let entry = cursor.current().expect("Should have a current entry");
let mut attrs = entry.attrs();
while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
if let gimli::AttributeValue::DebugLocRef(offset) = attr.value() {
offsets.push((offset, unit.address_size(), low_pc));
}
}
}
}

b.iter(|| for &(offset, address_size, base_address) in &*offsets {
let mut locs = debug_loc
.locations(offset, address_size, base_address)
.expect("Should parse locations OK");
while let Some(loc) = locs.next().expect("Should parse next location") {
test::black_box(loc);
}
});
}

#[bench]
fn bench_parsing_debug_ranges(b: &mut test::Bencher) {
let debug_info = read_section("debug_info");
let debug_info = DebugInfo::<LittleEndian>::new(&debug_info);

let debug_abbrev = read_section("debug_abbrev");
let debug_abbrev = DebugAbbrev::<LittleEndian>::new(&debug_abbrev);

let debug_ranges = read_section("debug_ranges");
let debug_ranges = DebugRanges::<LittleEndian>::new(&debug_ranges);

let mut offsets = Vec::new();

let mut iter = debug_info.units();
while let Some(unit) = iter.next().expect("Should parse compilation unit") {
let abbrevs = unit.abbreviations(debug_abbrev)
.expect("Should parse abbreviations");

let mut cursor = unit.entries(&abbrevs);
cursor.next_dfs().expect("Should parse next dfs");

let mut low_pc = 0;

{
let unit_entry = cursor.current().expect("Should have a root entry");
let low_pc_attr = unit_entry
.attr_value(gimli::DW_AT_low_pc)
.expect("Should parse low_pc");
if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
low_pc = address;
}
}

while cursor.next_dfs().expect("Should parse next dfs").is_some() {
let entry = cursor.current().expect("Should have a current entry");
let mut attrs = entry.attrs();
while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
if let gimli::AttributeValue::DebugRangesRef(offset) = attr.value() {
offsets.push((offset, unit.address_size(), low_pc));
}
}
}
}

b.iter(|| for &(offset, address_size, base_address) in &*offsets {
let mut ranges = debug_ranges
.ranges(offset, address_size, base_address)
.expect("Should parse ranges OK");
while let Some(range) = ranges.next().expect("Should parse next range") {
test::black_box(range);
}
});
}

// See comment above `test_parse_self_eh_frame`.
#[cfg(target_pointer_width = "64")]
mod cfi {
Expand Down
100 changes: 98 additions & 2 deletions tests/parse_self.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate gimli;

use gimli::{AttributeValue, DebugAbbrev, DebugAranges, DebugInfo, DebugLine, DebugPubNames,
DebugPubTypes, DebugStr, LittleEndian};
use gimli::{AttributeValue, DebugAbbrev, DebugAranges, DebugInfo, DebugLine, DebugLoc,
DebugPubNames, DebugPubTypes, DebugRanges, DebugStr, LittleEndian};
use std::env;
use std::fs::File;
use std::io::Read;
Expand Down Expand Up @@ -123,6 +123,102 @@ fn test_parse_self_debug_line() {
}
}

#[test]
fn test_parse_self_debug_loc() {
let debug_info = read_section("debug_info");
let debug_info = DebugInfo::<LittleEndian>::new(&debug_info);

let debug_abbrev = read_section("debug_abbrev");
let debug_abbrev = DebugAbbrev::<LittleEndian>::new(&debug_abbrev);

let debug_loc = read_section("debug_loc");
let debug_loc = DebugLoc::<LittleEndian>::new(&debug_loc);

let mut iter = debug_info.units();
while let Some(unit) = iter.next().expect("Should parse compilation unit") {
let abbrevs = unit.abbreviations(debug_abbrev)
.expect("Should parse abbreviations");

let mut cursor = unit.entries(&abbrevs);
cursor.next_dfs().expect("Should parse next dfs");

let mut low_pc = 0;

{
let unit_entry = cursor.current().expect("Should have a root entry");
let low_pc_attr = unit_entry
.attr_value(gimli::DW_AT_low_pc)
.expect("Should parse low_pc");
if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
low_pc = address;
}
}

while cursor.next_dfs().expect("Should parse next dfs").is_some() {
let entry = cursor.current().expect("Should have a current entry");
let mut attrs = entry.attrs();
while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
if let AttributeValue::DebugLocRef(offset) = attr.value() {
let mut locs = debug_loc
.locations(offset, unit.address_size(), low_pc)
.expect("Should parse locations OK");
while let Some(loc) = locs.next().expect("Should parse next location") {
assert!(loc.range.begin <= loc.range.end);
}
}
}
}
}
}

#[test]
fn test_parse_self_debug_ranges() {
let debug_info = read_section("debug_info");
let debug_info = DebugInfo::<LittleEndian>::new(&debug_info);

let debug_abbrev = read_section("debug_abbrev");
let debug_abbrev = DebugAbbrev::<LittleEndian>::new(&debug_abbrev);

let debug_ranges = read_section("debug_ranges");
let debug_ranges = DebugRanges::<LittleEndian>::new(&debug_ranges);

let mut iter = debug_info.units();
while let Some(unit) = iter.next().expect("Should parse compilation unit") {
let abbrevs = unit.abbreviations(debug_abbrev)
.expect("Should parse abbreviations");

let mut cursor = unit.entries(&abbrevs);
cursor.next_dfs().expect("Should parse next dfs");

let mut low_pc = 0;

{
let unit_entry = cursor.current().expect("Should have a root entry");
let low_pc_attr = unit_entry
.attr_value(gimli::DW_AT_low_pc)
.expect("Should parse low_pc");
if let Some(gimli::AttributeValue::Addr(address)) = low_pc_attr {
low_pc = address;
}
}

while cursor.next_dfs().expect("Should parse next dfs").is_some() {
let entry = cursor.current().expect("Should have a current entry");
let mut attrs = entry.attrs();
while let Some(attr) = attrs.next().expect("Should parse entry's attribute") {
if let AttributeValue::DebugRangesRef(offset) = attr.value() {
let mut ranges = debug_ranges
.ranges(offset, unit.address_size(), low_pc)
.expect("Should parse ranges OK");
while let Some(range) = ranges.next().expect("Should parse next range") {
assert!(range.begin <= range.end);
}
}
}
}
}
}

#[test]
fn test_parse_self_debug_aranges() {
let debug_aranges = read_section("debug_aranges");
Expand Down

0 comments on commit f63bac1

Please sign in to comment.