Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753610AbcLNRty (ORCPT ); Wed, 14 Dec 2016 12:49:54 -0500 Received: from mga02.intel.com ([134.134.136.20]:52063 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753453AbcLNRtx (ORCPT ); Wed, 14 Dec 2016 12:49:53 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,347,1477983600"; d="scan'208";a="912194360" From: kan.liang@intel.com To: acme@kernel.org, linux-kernel@vger.kernel.org Cc: mingo@redhat.com, peterz@infradead.org, jolsa@kernel.org, adrian.hunter@intel.com, andi@firstfloor.org, Kan Liang Subject: [PATCH] perf tools: ignore zombie process for user profile Date: Wed, 14 Dec 2016 12:48:05 -0500 Message-Id: <1481737685-24595-1-git-send-email-kan.liang@intel.com> X-Mailer: git-send-email 2.4.3 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2023 Lines: 87 From: Kan Liang If user has zombie process, the perf record -u will error out. Here is an example. $ ./testd & [1] 23796 $ sudo perf record -e cycles -u kan Error: The sys_perf_event_open() syscall returned with 3 (No such process) for event (cycles). /bin/dmesg may provide additional information. No CONFIG_PERF_EVENTS=y kernel support configured? The source code of testd is as below. int main() { if (fork()) { while (1); } return 0; } Zombie process is dead process. It is meaningless to profile it. It's better to ignore it for user profile. Signed-off-by: Kan Liang --- tools/perf/util/thread_map.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 40585f5..4643b69 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -89,6 +89,39 @@ struct thread_map *thread_map__new_by_tid(pid_t tid) return threads; } +static bool is_zombie_process(pid_t pid) +{ + char filename[PATH_MAX]; + char comm[PATH_MAX]; + char bf[BUFSIZ]; + char s_state; + int s_pid; + FILE *fp; + ssize_t n; + + snprintf(filename, sizeof(filename), "/proc/%d/stat", pid); + fp = fopen(filename, "r"); + if (!fp) { + pr_warning("couldn't open %s\n", filename); + return false; + } + if (fgets(bf, sizeof(bf), fp) == NULL) { + pr_warning("Couldn't read stat for pid %d\n", pid); + fclose(fp); + return false; + } + fclose(fp); + + n = sscanf(bf, "%d %s %c ", &s_pid, comm, &s_state); + if (n < 3) + return false; + + if (s_state == 'Z') + return true; + + return false; +} + struct thread_map *thread_map__new_by_uid(uid_t uid) { DIR *proc; @@ -124,6 +157,9 @@ struct thread_map *thread_map__new_by_uid(uid_t uid) if (st.st_uid != uid) continue; + if (is_zombie_process(pid)) + continue; + snprintf(path, sizeof(path), "/proc/%d/task", pid); items = scandir(path, &namelist, filter, NULL); if (items <= 0) -- 2.4.3