@@ -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