Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757362AbcLAAJj (ORCPT ); Wed, 30 Nov 2016 19:09:39 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:35210 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752856AbcLAAJR (ORCPT ); Wed, 30 Nov 2016 19:09:17 -0500 From: Alexis Berlemont To: linux-kernel@vger.kernel.org Cc: Alexis Berlemont , peterz@infradead.org, mingo@redhat.com, acme@kernel.org, alexander.shishkin@linux.intel.com Subject: [PATCH] perf annotate: check that objdump correctly works Date: Thu, 1 Dec 2016 01:04:36 +0100 Message-Id: <20161201000436.10354-2-alexis.berlemont@gmail.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161201000436.10354-1-alexis.berlemont@gmail.com> References: <20161201000436.10354-1-alexis.berlemont@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4138 Lines: 152 Before disassembling, the tool objdump is called just to be sure: * objdump is available in the path; * objdump is an executable binary; * objdump has no dependency issue or anything else. This objdump "pre-"command is only necessary because the real objdump command is followed by some " | grep ..."; this prevents the shell from returning the exit code of objdump execution. Signed-off-by: Alexis Berlemont --- tools/perf/util/annotate.c | 79 +++++++++++++++++++++++++++++++++++++++++++++- tools/perf/util/annotate.h | 3 ++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 3e34ee0..9d6c3a0 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -20,9 +20,12 @@ #include "block-range.h" #include "arch/common.h" #include +#include #include #include #include +#include +#include const char *disassembler_style; const char *objdump_path; @@ -1278,6 +1281,21 @@ int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map * " --vmlinux vmlinux\n", build_id_msg ?: ""); } break; + + case SYMBOL_ANNOTATE_ERRNO__NO_OBJDUMP: + scnprintf(buf, buflen, "No objdump tool available in $PATH\n"); + break; + + case SYMBOL_ANNOTATE_ERRNO__NO_EXEC_OBJDUMP: + scnprintf(buf, buflen, + "The objdump tool found in $PATH cannot be executed\n"); + break; + + case SYMBOL_ANNOTATE_ERRNO__NO_OUTPUT: + scnprintf(buf, buflen, + "The objdump tool returned no disassembled code\n"); + break; + default: scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum); break; @@ -1321,6 +1339,61 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil return 0; } +static int annotate__check_objdump(void) +{ + char command[PATH_MAX * 2]; + int wstatus, err; + pid_t pid; + + snprintf(command, sizeof(command), + "%s -v > /dev/null 2>&1", + objdump_path ? objdump_path : "objdump"); + + pid = fork(); + if (pid < 0) { + pr_err("Failure forking to run %s\n", command); + return -1; + } + + if (pid == 0) { + execl("/bin/sh", "sh", "-c", command, NULL); + exit(-1); + } + + err = waitpid(pid, &wstatus, 0); + if (err < 0) { + pr_err("Failure calling waitpid: %s: (%s)\n", + strerror(errno), command); + return -1; + } + + pr_err("%s: %d %d\n", command, pid, WEXITSTATUS(wstatus)); + + switch (WEXITSTATUS(wstatus)) { + case 0: + /* Success */ + err = 0; + break; + case 127: + /* The shell did not find objdump in the path */ + err = SYMBOL_ANNOTATE_ERRNO__NO_OBJDUMP; + break; + default: + /* + * In the default case, we consider that objdump + * cannot be executed; so it gathers many fault + * scenarii: + * - objdump is not an executable (126); + * - objdump has some dependency issue; + * - ... + */ + err = SYMBOL_ANNOTATE_ERRNO__NO_EXEC_OBJDUMP; + break; + } + + return err; +} + static const char *annotate__norm_arch(const char *arch_name) { struct utsname uts; @@ -1351,6 +1424,10 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na if (err) return err; + err = annotate__check_objdump(); + if (err) + return err; + arch_name = annotate__norm_arch(arch_name); if (!arch_name) return -1; @@ -1482,7 +1559,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na delete_last_nop(sym); fclose(file); - err = 0; + err = nline == 0 ? SYMBOL_ANNOTATE_ERRNO__NO_OUTPUT : 0; out_remove_tmp: close(stdout_fd[0]); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 87e4cad..123f60c 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -172,6 +172,9 @@ enum symbol_disassemble_errno { __SYMBOL_ANNOTATE_ERRNO__START = -10000, SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX = __SYMBOL_ANNOTATE_ERRNO__START, + SYMBOL_ANNOTATE_ERRNO__NO_EXEC_OBJDUMP, + SYMBOL_ANNOTATE_ERRNO__NO_OBJDUMP, + SYMBOL_ANNOTATE_ERRNO__NO_OUTPUT, __SYMBOL_ANNOTATE_ERRNO__END, }; -- 2.10.2