Skip to content

Commit cc47fca

Browse files
feat: make dwarf unwind load real-time with retry and dedup
1 parent 46743c3 commit cc47fca

4 files changed

Lines changed: 282 additions & 22 deletions

File tree

agent/crates/trace-utils/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ pub unsafe extern "C" fn unwind_table_load(table: *mut UnwindTable, pid: u32) {
6262
(*table).load(pid);
6363
}
6464

65+
#[no_mangle]
66+
pub unsafe extern "C" fn unwind_table_load_with_status(table: *mut UnwindTable, pid: u32) -> bool {
67+
(*table).load(pid)
68+
}
69+
6570
#[no_mangle]
6671
pub unsafe extern "C" fn unwind_table_unload(table: *mut UnwindTable, pid: u32) {
6772
(*table).unload(pid);

agent/crates/trace-utils/src/trace_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,8 @@ void unwind_table_destroy(unwind_table_t *table);
744744

745745
void unwind_table_load(unwind_table_t *table, uint32_t pid);
746746

747+
bool unwind_table_load_with_status(unwind_table_t *table, uint32_t pid);
748+
747749
void unwind_table_unload(unwind_table_t *table, uint32_t pid);
748750

749751
void unwind_table_unload_all(unwind_table_t *table);

agent/crates/trace-utils/src/unwind.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub struct UnwindTable {
9494
id_gen: IdGenerator,
9595
object_cache: HashMap<u64, ObjectInfo>,
9696
shard_rc: HashMap<u32, usize>,
97+
loaded_pids: HashSet<u32>,
9798

9899
process_shard_list_map_fd: i32,
99100
unwind_entry_shard_map_fd: i32,
@@ -112,12 +113,17 @@ impl UnwindTable {
112113
}
113114
}
114115

115-
pub fn load(&mut self, pid: u32) {
116+
pub fn load(&mut self, pid: u32) -> bool {
117+
if self.loaded_pids.contains(&pid) {
118+
trace!("process#{pid} dwarf entries already loaded");
119+
return true;
120+
}
121+
116122
let mm = match get_memory_mappings(pid) {
117123
Ok(m) => m,
118124
Err(e) => {
119125
debug!("failed loading maps for process#{pid}: {e}");
120-
return;
126+
return false;
121127
}
122128
};
123129
trace!("load dwarf entries for process#{pid}");
@@ -187,7 +193,9 @@ impl UnwindTable {
187193
"object {} found in cache, use loaded shards",
188194
path.display()
189195
);
190-
obj.pids.push(pid);
196+
if !obj.pids.contains(&pid) {
197+
obj.pids.push(pid);
198+
}
191199
for s in obj.shards.iter() {
192200
if shard_list.len as usize >= UNWIND_SHARDS_PER_PROCESS {
193201
warn!(
@@ -353,7 +361,7 @@ impl UnwindTable {
353361

354362
if shard_list.len == 0 {
355363
trace!("no dwarf entry shards loaded for process#{pid}");
356-
return;
364+
return false;
357365
}
358366

359367
if log::log_enabled!(log::Level::Debug) {
@@ -370,6 +378,8 @@ impl UnwindTable {
370378
(&mut shard_list.entries[..shard_list.len as usize])
371379
.sort_unstable_by_key(|e| e.offset + e.pc_min);
372380
self.update_process_shard_list(pid, &shard_list);
381+
self.loaded_pids.insert(pid);
382+
true
373383
}
374384

375385
pub fn unload(&mut self, pid: u32) {
@@ -411,6 +421,7 @@ impl UnwindTable {
411421
}
412422
});
413423
if found_process {
424+
self.loaded_pids.remove(&pid);
414425
for id in shards_to_remove.iter() {
415426
self.delete_unwind_entry_shard(*id);
416427
self.id_gen.release(*id);
@@ -426,6 +437,8 @@ impl UnwindTable {
426437
pub fn unload_all(&mut self) {
427438
trace!("unload all dwarf entries");
428439

440+
self.loaded_pids.clear();
441+
429442
let shards: Vec<u32> = self.shard_rc.drain().map(|(id, _)| id).collect();
430443
for id in shards.iter() {
431444
self.delete_unwind_entry_shard(*id);

0 commit comments

Comments
 (0)