Skip to content

Commit 77cb68a

Browse files
authored
Merge pull request #26 from polarsignals/machine-independent-addrs
Make addresses machine independent
2 parents 39eb076 + 2dcd38a commit 77cb68a

File tree

1 file changed

+19
-29
lines changed

1 file changed

+19
-29
lines changed

util/src/lib.rs

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -154,33 +154,13 @@ impl StackProfile {
154154

155155
profile.mapping.push(proto::Mapping {
156156
id: mapping_id,
157-
memory_start: u64::cast_from(mapping.memory_start),
158-
memory_limit: u64::cast_from(mapping.memory_end),
159-
file_offset: mapping.file_offset,
157+
memory_start: 0,
158+
memory_limit: 0,
159+
file_offset: 0,
160160
filename: filename_idx,
161161
build_id: build_id_idx,
162162
..Default::default()
163163
});
164-
165-
// This is a is a Polar Signals-specific extension: For correct offline symbolization
166-
// they need access to the memory offset of mappings, but the pprof format only has a
167-
// field for the file offset. So we instead encode additional information about
168-
// mappings in magic comments. There must be exactly one comment for each mapping.
169-
170-
// Take a shortcut and assume the ELF type is always `ET_DYN`. This is true for shared
171-
// libraries and for position-independent executable, so it should always be true for
172-
// any mappings we have.
173-
// Getting the actual information is annoying. It's in the ELF header (the `e_type`
174-
// field), but there is no guarantee that the full ELF header gets mapped, so we might
175-
// not be able to find it in memory. We could try to load it from disk instead, but
176-
// then we'd have to worry about blocking disk I/O.
177-
let elf_type = 3;
178-
179-
let comment = format!(
180-
"executableInfo={:x};{:x};{:x}",
181-
elf_type, mapping.file_offset, mapping.memory_offset
182-
);
183-
profile.comment.push(strings.insert(&comment));
184164
}
185165

186166
let mut location_ids = BTreeMap::new();
@@ -207,16 +187,26 @@ impl StackProfile {
207187
// tools don't seem to get confused by this.
208188
let addr = u64::cast_from(*addr) - 1;
209189

210-
let loc_id = *location_ids.entry(addr).or_insert_with(|| {
190+
// Find the mapping for this address (search once)
191+
let mapping_info = self.mappings.iter().enumerate().find(|(_, mapping)| {
192+
mapping.memory_start <= addr as usize && mapping.memory_end > addr as usize
193+
});
194+
195+
// Convert runtime address to file-relative address using found mapping data
196+
let file_relative_addr = mapping_info
197+
.map(|(_, mapping)| {
198+
(addr as usize - mapping.memory_start + mapping.file_offset as usize) as u64
199+
})
200+
.unwrap_or(addr);
201+
202+
let loc_id = *location_ids.entry(file_relative_addr).or_insert_with(|| {
211203
// profile.proto says the location id may be the address, but Polar Signals
212204
// insists that location ids are sequential, starting with 1.
213205
let id = u64::cast_from(profile.location.len()) + 1;
214206

215207
#[allow(unused_mut)] // for feature = "symbolize"
216-
let mut mapping = profile
217-
.mapping
218-
.iter_mut()
219-
.find(|m| m.memory_start <= addr && m.memory_limit > addr);
208+
let mut mapping =
209+
mapping_info.and_then(|(idx, _)| profile.mapping.get_mut(idx));
220210

221211
// If online symbolization is enabled, resolve the function and line.
222212
#[allow(unused_mut)]
@@ -268,7 +258,7 @@ impl StackProfile {
268258
profile.location.push(proto::Location {
269259
id,
270260
mapping_id: mapping.map_or(0, |m| m.id),
271-
address: addr,
261+
address: file_relative_addr,
272262
line,
273263
..Default::default()
274264
});

0 commit comments

Comments
 (0)