Re: [PATCH 2/4] perf,uprobes: fix user stack traces in the presence of pending uretprobes
From: Peter Zijlstra <peterz@infradead.org>
Date: 2024-05-15 09:30:27
Also in:
bpf, linux-perf-users
On Wed, May 08, 2024 at 02:26:03PM -0700, Andrii Nakryiko wrote:
+static void fixup_uretprobe_trampoline_entries(struct perf_callchain_entry *entry,
+ int start_entry_idx)
+{
+#ifdef CONFIG_UPROBES
+ struct uprobe_task *utask = current->utask;
+ struct return_instance *ri;
+ __u64 *cur_ip, *last_ip, tramp_addr;
+
+ if (likely(!utask || !utask->return_instances))
+ return;
+
+ cur_ip = &entry->ip[start_entry_idx];
+ last_ip = &entry->ip[entry->nr - 1];
+ ri = utask->return_instances;
+ tramp_addr = uprobe_get_trampoline_vaddr();
+
+ /* If there are pending uretprobes for current thread, they areComment style fail. Also 'for *the* current thread'.
+ * recorded in a list inside utask->return_instances; each such + * pending uretprobe replaces traced user function's return address on + * the stack, so when stack trace is captured, instead of seeing + * actual function's return address, we'll have one or many uretprobe + * trampoline addresses in the stack trace, which are not helpful and + * misleading to users.
I would beg to differ, what if the uprobe is causing the performance issue? While I do think it makes sense to fix the unwind in the sense that we should be able to continue the unwind, I don't think it makes sense to completely hide the presence of uprobes.
+ * So here we go over the pending list of uretprobes, and each
+ * encountered trampoline address is replaced with actual return
+ * address.
+ */
+ while (ri && cur_ip <= last_ip) {
+ if (*cur_ip == tramp_addr) {
+ *cur_ip = ri->orig_ret_vaddr;
+ ri = ri->next;
+ }
+ cur_ip++;
+ }
+#endif
+}