summary refs log tree commit diff
path: root/ripple/minitrace/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ripple/minitrace/src/main.rs')
-rw-r--r--ripple/minitrace/src/main.rs32
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)
 	}
 }