lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAM9d7chU_qSHoN7X=bbDFx=cuXRj08AFLLPH2-DsEHNnxO7qMg@mail.gmail.com>
Date:   Mon, 15 Aug 2022 22:11:41 -0700
From:   Namhyung Kim <namhyung@...nel.org>
To:     Raul Silvera <rsilvera@...gle.com>
Cc:     Peter Zijlstra <peterz@...radead.org>,
        Ingo Molnar <mingo@...hat.com>,
        Arnaldo Carvalho de Melo <acme@...nel.org>,
        Mark Rutland <mark.rutland@....com>,
        Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
        Jiri Olsa <jolsa@...nel.org>,
        Adrian Hunter <adrian.hunter@...el.com>,
        James Clark <james.clark@....com>,
        linux-perf-users <linux-perf-users@...r.kernel.org>,
        linux-kernel <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v4] perf inject: Add a command line option to specify
 build ids.

Hello,

On Mon, Aug 15, 2022 at 3:59 PM Raul Silvera <rsilvera@...gle.com> wrote:
>
> This commit adds the option --known-build-ids to perf inject.
> It allows the user to explicitly specify the build id for a given
> path, instead of retrieving it from the current system. This is
> useful in cases where a perf.data file is processed on a different
> system from where it was collected, or if some of the binaries are
> no longer available.
>
> The build ids and paths are specified in pairs in the command line.
> Using the file:// specifier, build ids can be loaded from a file
> directly generated by perf buildid-list. This is convenient to copy
> build ids from one perf.data file to another.
>
> ** Example: In this example we use perf record to create two
> perf.data files, one with build ids and another without, and use
> perf buildid-list and perf inject to copy the build ids from the
> first file to the second.
>
>  $ perf record ls /tmp
>  $ perf record --no-buildid -o perf.data.no-buildid ls /tmp
>  $ perf buildid-list > build-ids.txt
>  $ perf inject -b --known-build-ids='file://build-ids.txt' \
>         -i perf.data.no-buildid -o perf.data.buildid
>
> Signed-off-by: Raul Silvera <rsilvera@...gle.com>

Acked-by: Namhyung Kim <namhyung@...nel.org>

Thanks,
Namhyung


> ---
>
>   V3 -> V4: Perform upfront validation of build ids
>   V2 -> V3: Added documentation and removed unnecessary temps
>   V1 -> V2: Cleaned up patch description, deleted the strlist during
>             cleanup, and updated validation of the build id strings
>
>  tools/perf/Documentation/perf-inject.txt |  7 +-
>  tools/perf/builtin-inject.c              | 85 ++++++++++++++++++++++++
>  2 files changed, 91 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt
> index ffc293fdf61d..70e2ac3cc91a 100644
> --- a/tools/perf/Documentation/perf-inject.txt
> +++ b/tools/perf/Documentation/perf-inject.txt
> @@ -27,9 +27,14 @@ OPTIONS
>  --build-ids::
>          Inject build-ids into the output stream
>
> ---buildid-all:
> +--buildid-all::
>         Inject build-ids of all DSOs into the output stream
>
> +--known-build-ids=::
> +       Override build-ids to inject using these comma-separated pairs of
> +       build-id and path. Understands file://filename to read these pairs
> +       from a file, which can be generated with perf buildid-list.
> +
>  -v::
>  --verbose::
>         Be more verbose.
> diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
> index 2a0f992ca0be..8ec955402488 100644
> --- a/tools/perf/builtin-inject.c
> +++ b/tools/perf/builtin-inject.c
> @@ -21,6 +21,7 @@
>  #include "util/data.h"
>  #include "util/auxtrace.h"
>  #include "util/jit.h"
> +#include "util/string2.h"
>  #include "util/symbol.h"
>  #include "util/synthetic-events.h"
>  #include "util/thread.h"
> @@ -38,6 +39,7 @@
>  #include <linux/string.h>
>  #include <linux/zalloc.h>
>  #include <linux/hash.h>
> +#include <ctype.h>
>  #include <errno.h>
>  #include <signal.h>
>  #include <inttypes.h>
> @@ -123,6 +125,7 @@ struct perf_inject {
>         char                    event_copy[PERF_SAMPLE_MAX_SIZE];
>         struct perf_file_section secs[HEADER_FEAT_BITS];
>         struct guest_session    guest_session;
> +       struct strlist          *known_build_ids;
>  };
>
>  struct event_entry {
> @@ -634,9 +637,73 @@ static int dso__read_build_id(struct dso *dso)
>         return dso->has_build_id ? 0 : -1;
>  }
>
> +static struct strlist *perf_inject__parse_known_build_ids(
> +       const char *known_build_ids_string)
> +{
> +       struct str_node *pos, *tmp;
> +       struct strlist *known_build_ids;
> +       int bid_len;
> +
> +       known_build_ids = strlist__new(known_build_ids_string, NULL);
> +       if (known_build_ids == NULL)
> +               return NULL;
> +       strlist__for_each_entry_safe(pos, tmp, known_build_ids) {
> +               const char *build_id, *dso_name;
> +
> +               build_id = skip_spaces(pos->s);
> +               dso_name = strchr(build_id, ' ');
> +               if (dso_name == NULL) {
> +                       strlist__remove(known_build_ids, pos);
> +                       continue;
> +               }
> +               bid_len = dso_name - pos->s;
> +               dso_name = skip_spaces(dso_name);
> +               if (bid_len % 2 != 0 || bid_len >= SBUILD_ID_SIZE) {
> +                       strlist__remove(known_build_ids, pos);
> +                       continue;
> +               }
> +               for (int ix = 0; 2 * ix + 1 < bid_len; ++ix) {
> +                       if (!isxdigit(build_id[2 * ix]) ||
> +                           !isxdigit(build_id[2 * ix + 1])) {
> +                               strlist__remove(known_build_ids, pos);
> +                               break;
> +                       }
> +               }
> +       }
> +       return known_build_ids;
> +}
> +
> +static bool perf_inject__lookup_known_build_id(struct perf_inject *inject,
> +                                              struct dso *dso)
> +{
> +       struct str_node *pos;
> +       int bid_len;
> +
> +       strlist__for_each_entry(pos, inject->known_build_ids) {
> +               const char *build_id, *dso_name;
> +
> +               build_id = skip_spaces(pos->s);
> +               dso_name = strchr(build_id, ' ');
> +               bid_len = dso_name - pos->s;
> +               dso_name = skip_spaces(dso_name);
> +               if (strcmp(dso->long_name, dso_name))
> +                       continue;
> +               for (int ix = 0; 2 * ix + 1 < bid_len; ++ix) {
> +                       dso->bid.data[ix] = (hex(build_id[2 * ix]) << 4 |
> +                                            hex(build_id[2 * ix + 1]));
> +               }
> +               dso->bid.size = bid_len / 2;
> +               dso->has_build_id = 1;
> +               return true;
> +       }
> +       return false;
> +}
> +
>  static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
>                                 struct machine *machine, u8 cpumode, u32 flags)
>  {
> +       struct perf_inject *inject = container_of(tool, struct perf_inject,
> +                                                 tool);
>         int err;
>
>         if (is_anon_memory(dso->long_name) || flags & MAP_HUGETLB)
> @@ -644,6 +711,10 @@ static int dso__inject_build_id(struct dso *dso, struct perf_tool *tool,
>         if (is_no_dso_memory(dso->long_name))
>                 return 0;
>
> +       if (inject->known_build_ids != NULL &&
> +           perf_inject__lookup_known_build_id(inject, dso))
> +               return 1;
> +
>         if (dso__read_build_id(dso) < 0) {
>                 pr_debug("no build_id found for %s\n", dso->long_name);
>                 return -1;
> @@ -2112,12 +2183,16 @@ int cmd_inject(int argc, const char **argv)
>         };
>         int ret;
>         bool repipe = true;
> +       const char *known_build_ids = NULL;
>
>         struct option options[] = {
>                 OPT_BOOLEAN('b', "build-ids", &inject.build_ids,
>                             "Inject build-ids into the output stream"),
>                 OPT_BOOLEAN(0, "buildid-all", &inject.build_id_all,
>                             "Inject build-ids of all DSOs into the output stream"),
> +               OPT_STRING(0, "known-build-ids", &known_build_ids,
> +                          "buildid path [,buildid path...]",
> +                          "build-ids to use for given paths"),
>                 OPT_STRING('i', "input", &inject.input_name, "file",
>                            "input file name"),
>                 OPT_STRING('o', "output", &inject.output.path, "file",
> @@ -2257,6 +2332,15 @@ int cmd_inject(int argc, const char **argv)
>                  */
>                 inject.tool.ordered_events = true;
>                 inject.tool.ordering_requires_timestamps = true;
> +               if (known_build_ids != NULL) {
> +                       inject.known_build_ids =
> +                               perf_inject__parse_known_build_ids(known_build_ids);
> +
> +                       if (inject.known_build_ids == NULL) {
> +                               pr_err("Couldn't parse known build ids.\n");
> +                               goto out_delete;
> +                       }
> +               }
>         }
>
>         if (inject.sched_stat) {
> @@ -2285,6 +2369,7 @@ int cmd_inject(int argc, const char **argv)
>         guest_session__exit(&inject.guest_session);
>
>  out_delete:
> +       strlist__delete(inject.known_build_ids);
>         zstd_fini(&(inject.session->zstd_data));
>         perf_session__delete(inject.session);
>  out_close_output:
> --
> 2.37.1.595.g718a3a8f04-goog
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ