diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 56007a7e0b4d7f6aadd8300e2c8c2023354c29bc..2c146d0c217bea33694a128e43b40249976afe90 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -192,14 +192,24 @@ struct comm *thread__comm(const struct thread *thread) struct comm *thread__exec_comm(const struct thread *thread) { - struct comm *comm, *last = NULL; + struct comm *comm, *last = NULL, *second_last = NULL; list_for_each_entry(comm, &thread->comm_list, list) { if (comm->exec) return comm; + second_last = last; last = comm; } + /* + * 'last' with no start time might be the parent's comm of a synthesized + * thread (created by processing a synthesized fork event). For a main + * thread, that is very probably wrong. Prefer a later comm to avoid + * that case. + */ + if (second_last && !last->start && thread->pid_ == thread->tid) + return second_last; + return last; }