Skip to content

Commit e00dd13

Browse files
committed
Make addresses machine independent
This patch makes addresses machine independent, and perhaps more importantly communicates to backends that it has done so by setting mapping start, limit and file offset to 0. This signals to tooling, like the pprof toolchain that addresses don't have to be adjusted any further.
1 parent 39eb076 commit e00dd13

File tree

1 file changed

+21
-29
lines changed

1 file changed

+21
-29
lines changed

util/src/lib.rs

Lines changed: 21 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,28 @@ 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
192+
.mappings
193+
.iter()
194+
.enumerate()
195+
.find(|(_, mapping)| mapping.memory_start <= addr as usize && mapping.memory_end > addr as usize);
196+
197+
// Convert runtime address to file-relative address using found mapping data
198+
let file_relative_addr = mapping_info
199+
.map(|(_, mapping)| {
200+
(addr as usize - mapping.memory_start + mapping.file_offset as usize) as u64
201+
})
202+
.unwrap_or(addr);
203+
204+
let loc_id = *location_ids.entry(file_relative_addr).or_insert_with(|| {
211205
// profile.proto says the location id may be the address, but Polar Signals
212206
// insists that location ids are sequential, starting with 1.
213207
let id = u64::cast_from(profile.location.len()) + 1;
214208

215209
#[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);
210+
let mut mapping = mapping_info
211+
.and_then(|(idx, _)| profile.mapping.get_mut(idx));
220212

221213
// If online symbolization is enabled, resolve the function and line.
222214
#[allow(unused_mut)]
@@ -268,7 +260,7 @@ impl StackProfile {
268260
profile.location.push(proto::Location {
269261
id,
270262
mapping_id: mapping.map_or(0, |m| m.id),
271-
address: addr,
263+
address: file_relative_addr,
272264
line,
273265
..Default::default()
274266
});

0 commit comments

Comments
 (0)