diff options
Diffstat (limited to 'ripple/minitrace/src/main.rs')
-rw-r--r-- | ripple/minitrace/src/main.rs | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/ripple/minitrace/src/main.rs b/ripple/minitrace/src/main.rs index 0f9cb0d..9d9a790 100644 --- a/ripple/minitrace/src/main.rs +++ b/ripple/minitrace/src/main.rs @@ -20,7 +20,7 @@ use { env, ffi::CString, fmt::{self, Debug}, - fs::File, + fs::{self, File}, io::{self, BufRead, Seek, SeekFrom}, os::unix::process::CommandExt, process::Command, @@ -96,15 +96,41 @@ impl Process { } fn read_mappings(&self) -> Result<Vec<maps_file::Mapping>> { - let contents = std::fs::read_to_string(format!("/proc/{}/maps", self.tgid.0))?; + let pid = self.tgid.as_pid(); + let contents = fs::read_to_string(format!("/proc/{pid}/maps"))?; // TODO(edef): consult /proc/$pid/map_files/* for pathnames, since /proc/$pid/maps is unreliable with odd paths // we'll want to verify the two against each other, just to be sure they're congruent - let mappings = contents + let mut mappings = contents .lines() .map(maps_file::parse_mapping_line) .collect::<Result<_, _>>()?; + + for &mut maps_file::Mapping { + start, + end, + ref mut pathname, + .. + } in &mut mappings + { + if pathname.starts_with('[') && pathname.ends_with(']') { + // these won't exist in map_files + continue; + } + + let map_path = format!("/proc/{pid}/map_files/{start:x}-{end:x}"); + let target = fs::read_link(&map_path) + .with_context(|| { + format!("Cannot readlink({map_path:?}) (expected target: {pathname:?})") + })? + .into_os_string() + .into_string() + .expect("path is not valid UTF-8"); + assert_eq!(*pathname, maps_file::escape_path(&target), "escaping bug?"); + *pathname = target; + } + Ok(mappings) } } |