Thread (13 messages) 13 messages, 5 authors, 2025-11-13

Re: [PATCH v16 4/4] perf tools: Merge deferred user callchains

From: Namhyung Kim <namhyung@kernel.org>
Date: 2025-11-13 21:43:01
Also in: bpf, lkml

Hello,

Sorry for the delay.  And I'm happy that the kernel part is merge to the
tip tree! :)

On Fri, Oct 24, 2025 at 03:02:03PM +0200, Peter Zijlstra wrote:
On Thu, Oct 02, 2025 at 01:49:38PM -0400, Steven Rostedt wrote:
quoted
On Mon, 08 Sep 2025 13:53:23 -0400
Steven Rostedt [off-list ref] wrote:
quoted
+static int evlist__deliver_deferred_samples(struct evlist *evlist,
+					    const struct perf_tool *tool,
+					    union  perf_event *event,
+					    struct perf_sample *sample,
+					    struct machine *machine)
+{
+	struct deferred_event *de, *tmp;
+	struct evsel *evsel;
+	int ret = 0;
+
+	if (!tool->merge_deferred_callchains) {
+		evsel = evlist__id2evsel(evlist, sample->id);
+		return tool->callchain_deferred(tool, event, sample,
+						evsel, machine);
+	}
+
+	list_for_each_entry_safe(de, tmp, &evlist->deferred_samples, list) {
+		struct perf_sample orig_sample;
orig_sample is not initialized and can then contain junk.
Yep.
quoted
quoted
+
+		ret = evlist__parse_sample(evlist, de->event, &orig_sample);
But here you call evlist__parse_sample() and evsel__parse_sample() which
should initialize the sample properly.

quoted
quoted
+		if (ret < 0) {
+			pr_err("failed to parse original sample\n");
+			break;
+		}
+
+		if (sample->tid != orig_sample.tid)
+			continue;
+
+		if (event->callchain_deferred.cookie == orig_sample.deferred_cookie)
+			sample__merge_deferred_callchain(&orig_sample, sample);
The sample__merge_deferred_callchain() initializes both
orig_sample.deferred_callchain and the callchain. But now that it's not
being called, it can cause the below free to happen with junk as the
callchain. This needs:

		else
			orig_sample.deferred_callchain = false;
Ah, so I saw crashes from here and just deleted both free()s and got on
with things ;-)
I don't understand how it can have the garbage.  But having the else
part would be safer.

Thanks,
Namhyung
quoted
quoted
+
+		evsel = evlist__id2evsel(evlist, orig_sample.id);
+		ret = evlist__deliver_sample(evlist, tool, de->event,
+					     &orig_sample, evsel,> machine); +
+		if (orig_sample.deferred_callchain)
+			free(orig_sample.callchain);
+
+		list_del(&de->list);
+		free(de);
+
+		if (ret)
+			break;
+	}
+	return ret;
+}
-- Steve
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help