summaryrefslogtreecommitdiff
path: root/rust/examples
diff options
context:
space:
mode:
authorJosh Ferrell <josh@vector35.com>2024-10-18 17:41:46 -0400
committerJosh Ferrell <josh@vector35.com>2024-10-18 17:41:46 -0400
commit36c49a4a9166c7fc8749d987d609fcd00ff226a7 (patch)
tree42dca0fc9f371ba9bfb54768c3264aca763e8b44 /rust/examples
parent62570f741c2bfb705a29389e0386541bff45dba6 (diff)
Add progress reporting to first phase of DWARF parsing
Diffstat (limited to 'rust/examples')
-rw-r--r--rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs2
-rw-r--r--rust/examples/dwarf/dwarf_import/src/lib.rs67
2 files changed, 65 insertions, 4 deletions
diff --git a/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs b/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs
index 03a237db..4c231a88 100644
--- a/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs
+++ b/rust/examples/dwarf/dwarf_import/src/dwarfdebuginfo.rs
@@ -118,6 +118,7 @@ pub(crate) struct DebugInfoBuilderContext<R: ReaderType> {
names: HashMap<TypeUID, String>,
default_address_size: usize,
pub(crate) total_die_count: usize,
+ pub(crate) total_unit_size_bytes: usize,
}
impl<R: ReaderType> DebugInfoBuilderContext<R> {
@@ -153,6 +154,7 @@ impl<R: ReaderType> DebugInfoBuilderContext<R> {
names: HashMap::new(),
default_address_size: view.address_size(),
total_die_count: 0,
+ total_unit_size_bytes: 0,
})
}
diff --git a/rust/examples/dwarf/dwarf_import/src/lib.rs b/rust/examples/dwarf/dwarf_import/src/lib.rs
index 58e66dda..e5508b40 100644
--- a/rust/examples/dwarf/dwarf_import/src/lib.rs
+++ b/rust/examples/dwarf/dwarf_import/src/lib.rs
@@ -48,6 +48,56 @@ trait ReaderType: Reader<Offset = usize> {}
impl<T: Reader<Offset = usize>> ReaderType for T {}
+pub(crate) fn split_progress<'b, F: Fn(usize, usize) -> Result<(), ()> + 'b>(
+ original_fn: F,
+ subpart: usize,
+ subpart_weights: &[f64],
+) -> Box<dyn Fn(usize, usize) -> Result<(), ()> + 'b> {
+ // Normalize weights
+ let weight_sum: f64 = subpart_weights.iter().sum();
+ if weight_sum < 0.0001 {
+ return Box::new(|_, _| Ok(()));
+ }
+
+ // Keep a running count of weights for the start
+ let mut subpart_starts = vec![];
+ let mut start = 0f64;
+ for w in subpart_weights {
+ subpart_starts.push(start);
+ start += *w;
+ }
+
+ let subpart_start = subpart_starts[subpart] / weight_sum;
+ let weight = subpart_weights[subpart] / weight_sum;
+
+ Box::new(move |cur: usize, max: usize| {
+ // Just use a large number for easy divisibility
+ let steps = 1000000f64;
+ let subpart_size = steps * weight;
+ let subpart_progress = ((cur as f64) / (max as f64)) * subpart_size;
+
+ original_fn(
+ (subpart_start * steps + subpart_progress) as usize,
+ steps as usize,
+ )
+ })
+}
+
+
+fn calculate_total_unit_bytes<R: ReaderType>(
+ dwarf: &Dwarf<R>,
+ debug_info_builder_context: &mut DebugInfoBuilderContext<R>,
+)
+{
+ let mut iter = dwarf.units();
+ let mut total_size: usize = 0;
+ while let (Ok(Some(header))) = iter.next()
+ {
+ total_size += header.length_including_self();
+ }
+ debug_info_builder_context.total_unit_size_bytes = total_size;
+}
+
fn recover_names<R: ReaderType>(
dwarf: &Dwarf<R>,
debug_info_builder_context: &mut DebugInfoBuilderContext<R>,
@@ -71,7 +121,9 @@ fn recover_names_internal<R: ReaderType>(
progress: &dyn Fn(usize, usize) -> Result<(), ()>,
) -> bool {
let mut iter = dwarf.units();
+ let mut current_byte_offset: usize = 0;
while let Ok(Some(header)) = iter.next() {
+ let unit_offset = header.offset().as_debug_info_offset().unwrap().0;
let unit = dwarf.unit(header).unwrap();
let mut namespace_qualifiers: Vec<(isize, String)> = vec![];
let mut entries = unit.entries();
@@ -86,9 +138,10 @@ fn recover_names_internal<R: ReaderType>(
while let Ok(Some((delta_depth, entry))) = entries.next_dfs() {
debug_info_builder_context.total_die_count += 1;
- if (*progress)(0, debug_info_builder_context.total_die_count).is_err() {
+ if (*progress)(current_byte_offset, debug_info_builder_context.total_unit_size_bytes).is_err() {
return false; // Parsing canceled
};
+ current_byte_offset = unit_offset + entry.offset().0;
depth += delta_depth;
if depth < 0 {
@@ -487,7 +540,13 @@ fn parse_dwarf(
debug_info_builder.set_range_data_offsets(range_data_offsets);
if let Some(mut debug_info_builder_context) = DebugInfoBuilderContext::new(view, &dwarf) {
- if !recover_names(&dwarf, &mut debug_info_builder_context, &progress)
+ calculate_total_unit_bytes(&dwarf, &mut debug_info_builder_context);
+
+ let progress_weights = [0.5, 0.5];
+ let name_progress = split_progress(&progress, 0, &progress_weights);
+ let parse_progress = split_progress(&progress, 1, &progress_weights);
+
+ if !recover_names(&dwarf, &mut debug_info_builder_context, &name_progress)
|| debug_info_builder_context.total_die_count == 0
{
return Ok(debug_info_builder);
@@ -502,7 +561,7 @@ fn parse_dwarf(
&unit,
&debug_info_builder_context,
&mut debug_info_builder,
- &progress,
+ &parse_progress,
&mut current_die_number,
);
}
@@ -513,7 +572,7 @@ fn parse_dwarf(
&unit,
&debug_info_builder_context,
&mut debug_info_builder,
- &progress,
+ &parse_progress,
&mut current_die_number,
);
}