Skip to content

Commit 36c49a4

Browse files
committed
Add progress reporting to first phase of DWARF parsing
1 parent 62570f7 commit 36c49a4

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ pub(crate) struct DebugInfoBuilderContext<R: ReaderType> {
118118
names: HashMap<TypeUID, String>,
119119
default_address_size: usize,
120120
pub(crate) total_die_count: usize,
121+
pub(crate) total_unit_size_bytes: usize,
121122
}
122123

123124
impl<R: ReaderType> DebugInfoBuilderContext<R> {
@@ -153,6 +154,7 @@ impl<R: ReaderType> DebugInfoBuilderContext<R> {
153154
names: HashMap::new(),
154155
default_address_size: view.address_size(),
155156
total_die_count: 0,
157+
total_unit_size_bytes: 0,
156158
})
157159
}
158160

rust/examples/dwarf/dwarf_import/src/lib.rs

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,56 @@ trait ReaderType: Reader<Offset = usize> {}
4848
impl<T: Reader<Offset = usize>> ReaderType for T {}
4949

5050

51+
pub(crate) fn split_progress<'b, F: Fn(usize, usize) -> Result<(), ()> + 'b>(
52+
original_fn: F,
53+
subpart: usize,
54+
subpart_weights: &[f64],
55+
) -> Box<dyn Fn(usize, usize) -> Result<(), ()> + 'b> {
56+
// Normalize weights
57+
let weight_sum: f64 = subpart_weights.iter().sum();
58+
if weight_sum < 0.0001 {
59+
return Box::new(|_, _| Ok(()));
60+
}
61+
62+
// Keep a running count of weights for the start
63+
let mut subpart_starts = vec![];
64+
let mut start = 0f64;
65+
for w in subpart_weights {
66+
subpart_starts.push(start);
67+
start += *w;
68+
}
69+
70+
let subpart_start = subpart_starts[subpart] / weight_sum;
71+
let weight = subpart_weights[subpart] / weight_sum;
72+
73+
Box::new(move |cur: usize, max: usize| {
74+
// Just use a large number for easy divisibility
75+
let steps = 1000000f64;
76+
let subpart_size = steps * weight;
77+
let subpart_progress = ((cur as f64) / (max as f64)) * subpart_size;
78+
79+
original_fn(
80+
(subpart_start * steps + subpart_progress) as usize,
81+
steps as usize,
82+
)
83+
})
84+
}
85+
86+
87+
fn calculate_total_unit_bytes<R: ReaderType>(
88+
dwarf: &Dwarf<R>,
89+
debug_info_builder_context: &mut DebugInfoBuilderContext<R>,
90+
)
91+
{
92+
let mut iter = dwarf.units();
93+
let mut total_size: usize = 0;
94+
while let (Ok(Some(header))) = iter.next()
95+
{
96+
total_size += header.length_including_self();
97+
}
98+
debug_info_builder_context.total_unit_size_bytes = total_size;
99+
}
100+
51101
fn recover_names<R: ReaderType>(
52102
dwarf: &Dwarf<R>,
53103
debug_info_builder_context: &mut DebugInfoBuilderContext<R>,
@@ -71,7 +121,9 @@ fn recover_names_internal<R: ReaderType>(
71121
progress: &dyn Fn(usize, usize) -> Result<(), ()>,
72122
) -> bool {
73123
let mut iter = dwarf.units();
124+
let mut current_byte_offset: usize = 0;
74125
while let Ok(Some(header)) = iter.next() {
126+
let unit_offset = header.offset().as_debug_info_offset().unwrap().0;
75127
let unit = dwarf.unit(header).unwrap();
76128
let mut namespace_qualifiers: Vec<(isize, String)> = vec![];
77129
let mut entries = unit.entries();
@@ -86,9 +138,10 @@ fn recover_names_internal<R: ReaderType>(
86138
while let Ok(Some((delta_depth, entry))) = entries.next_dfs() {
87139
debug_info_builder_context.total_die_count += 1;
88140

89-
if (*progress)(0, debug_info_builder_context.total_die_count).is_err() {
141+
if (*progress)(current_byte_offset, debug_info_builder_context.total_unit_size_bytes).is_err() {
90142
return false; // Parsing canceled
91143
};
144+
current_byte_offset = unit_offset + entry.offset().0;
92145

93146
depth += delta_depth;
94147
if depth < 0 {
@@ -487,7 +540,13 @@ fn parse_dwarf(
487540
debug_info_builder.set_range_data_offsets(range_data_offsets);
488541

489542
if let Some(mut debug_info_builder_context) = DebugInfoBuilderContext::new(view, &dwarf) {
490-
if !recover_names(&dwarf, &mut debug_info_builder_context, &progress)
543+
calculate_total_unit_bytes(&dwarf, &mut debug_info_builder_context);
544+
545+
let progress_weights = [0.5, 0.5];
546+
let name_progress = split_progress(&progress, 0, &progress_weights);
547+
let parse_progress = split_progress(&progress, 1, &progress_weights);
548+
549+
if !recover_names(&dwarf, &mut debug_info_builder_context, &name_progress)
491550
|| debug_info_builder_context.total_die_count == 0
492551
{
493552
return Ok(debug_info_builder);
@@ -502,7 +561,7 @@ fn parse_dwarf(
502561
&unit,
503562
&debug_info_builder_context,
504563
&mut debug_info_builder,
505-
&progress,
564+
&parse_progress,
506565
&mut current_die_number,
507566
);
508567
}
@@ -513,7 +572,7 @@ fn parse_dwarf(
513572
&unit,
514573
&debug_info_builder_context,
515574
&mut debug_info_builder,
516-
&progress,
575+
&parse_progress,
517576
&mut current_die_number,
518577
);
519578
}

0 commit comments

Comments
 (0)