Messages in this thread Patch in this message | | | From | kan.liang@intel ... | Subject | [PATCH] perf tools: ignore zombie process for user profile | Date | Wed, 14 Dec 2016 12:48:05 -0500 |
| |
From: Kan Liang <kan.liang@intel.com>
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 <kan.liang@intel.com> --- 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
| |