Skip to content

Commit

Permalink
usym: Fix order when dealing with inlined functions (#64)
Browse files Browse the repository at this point in the history
Test Plan
=========

Added tests to ensure we return frames in the right order, and catch
potential regressions with blazesym.
  • Loading branch information
javierhonduco authored Sep 5, 2024
1 parent 57fbabb commit 4e4a190
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 34 deletions.
103 changes: 69 additions & 34 deletions src/usym.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::path::PathBuf;
use std::process::Command;

use blazesym::symbolize::Elf;
use blazesym::symbolize::Input;
Expand All @@ -12,8 +11,6 @@ use tracing::error;
use crate::profiler::Frame;
use crate::profiler::FrameAddress;

const ADDR2LINE_BIN: &str = "/usr/bin/addr2line";

pub fn symbolize_native_stack_blaze(
address_pairs: Vec<FrameAddress>,
object_path: &PathBuf,
Expand Down Expand Up @@ -58,21 +55,20 @@ pub fn symbolize_native_stack_blaze(
inlined,
..
}) => {
symbols.push(Frame {
virtual_address: vaddr,
file_offset: Some(*addr),
name: name.to_string(),
inline: false,
});

for frame in inlined.iter() {
for frame in inlined.iter().rev() {
symbols.push(Frame {
virtual_address: vaddr,
file_offset: Some(*addr),
name: frame.name.to_string(),
inline: true,
});
}
symbols.push(Frame {
virtual_address: vaddr,
file_offset: Some(*addr),
name: name.to_string(),
inline: false,
});
}
Symbolized::Unknown(r) => {
symbols.push(Frame {
Expand All @@ -89,28 +85,67 @@ pub fn symbolize_native_stack_blaze(
res
}

// addr2line based symbolizer for testing and local dev
// in the future this should be done in the backend

pub fn symbolize_native_stack_addr2line(frames: Vec<u64>, object_path: &PathBuf) -> Vec<String> {
// return vec!["heh".to_string()];

let mut cmd = Command::new(ADDR2LINE_BIN);

cmd.arg("-f").arg("-e").arg(object_path);

for uaddr in frames {
cmd.arg(format!("{:x}", uaddr - 1));
}

let output = cmd.output().expect("addr2line command failed to start");

if !output.status.success() {
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
return vec!["err: addr2line failed to execute".to_string()];
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;

#[test]
fn test_blazesym() {
assert_eq!(
symbolize_native_stack_blaze(
vec![
FrameAddress {
virtual_address: 0x0,
file_offset: 0x4012d5 // main with multiple inlined nested calls
},
FrameAddress {
virtual_address: 0x0,
file_offset: 0x401058 // _start
}
],
&PathBuf::from_str("tests/testdata/main_cpp_clang_03_with_inlined_3s").unwrap()
),
vec![
vec![
Frame {
virtual_address: 0,
file_offset: Some(0x4012b0),
name: "top3()".to_string(),
inline: true
},
Frame {
virtual_address: 0,
file_offset: Some(0x4012b0),
name: "c3()".to_string(),
inline: true
},
Frame {
virtual_address: 0,
file_offset: Some(0x4012b0),
name: "b3()".to_string(),
inline: true
},
Frame {
virtual_address: 0,
file_offset: Some(0x4012b0),
name: "a3()".to_string(),
inline: true
},
Frame {
virtual_address: 0,
file_offset: Some(0x4012b0),
name: "main".to_string(),
inline: false
},
],
vec![Frame {
virtual_address: 0x0,
file_offset: Some(0x401040), // TODO investigate why this doesn't match the input value
name: "_start".to_string(),
inline: false
}]
]
);
}
let raw_out = String::from_utf8_lossy(&output.stdout);
let func_name = raw_out.split('\n').collect::<Vec<_>>();
vec![func_name.first().unwrap().to_string()]
}
Binary file added tests/testdata/main_cpp_clang_03_with_inlined_3s
Binary file not shown.

0 comments on commit 4e4a190

Please sign in to comment.