All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Namhyung Kim <namhyung@kernel.org>
Cc: Ian Rogers <irogers@google.com>, Jiri Olsa <jolsa@kernel.org>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-perf-users@vger.kernel.org,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Stephane Eranian <eranian@google.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	linux-toolchains@vger.kernel.org,
	linux-trace-devel@vger.kernel.org
Subject: Re: [PATCH 08/23] perf annotate-data: Add debug messages
Date: Tue, 19 Mar 2024 11:05:16 -0300	[thread overview]
Message-ID: <ZfmbnBBn5qqzQd5D@x1> (raw)
In-Reply-To: <20240319055115.4063940-9-namhyung@kernel.org>

On Mon, Mar 18, 2024 at 10:51:00PM -0700, Namhyung Kim wrote:
> Add a new debug option "type-profile" to enable the detailed info during
> the type analysis especially for instruction tracking.  You can use this
> before the command name like 'report' or 'annotate'.
> 
>   $ perf --debug type-profile annotate --data-type

Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>

First get some memory events:

  $ perf mem record ls

Then, without data-type profiling debug:

  $ perf annotate --data-type | head
  Annotate type: 'struct rtld_global' in /usr/lib64/ld-linux-x86-64.so.2 (1 samples):
  ============================================================================
      samples     offset       size  field
            1          0       4336  struct rtld_global  {
            0          0          0      struct link_namespaces*        _dl_ns;
            0       2560          8      size_t _dl_nns;
            0       2568         40      __rtld_lock_recursive_t        _dl_load_lock {
            0       2568         40          pthread_mutex_t    mutex {
            0       2568         40              struct __pthread_mutex_s       __data {
            0       2568          4                  int        __lock;
  $

And with only data-type profiling:

  $ perf --debug type-profile annotate --data-type | head
  -----------------------------------------------------------
  find_data_type_die [1e67] for reg13873052 (PC) offset=0x150e2 in dl_main
  CU die offset: 0x29cd3
  found PC-rel by addr=0x34020 offset=0x20
  -----------------------------------------------------------
  find_data_type_die [2e] for reg12 offset=0 in __GI___readdir64
  CU die offset: 0x137a45
  frame base: cfa=1 fbreg=-1
  found "__futex" in scope=2/2 (die: 0x137ad5) 0(reg12) type=int (die:2a)
  -----------------------------------------------------------
  find_data_type_die [52] for reg5 offset=0 in __memmove_avx_unaligned_erms
  CU die offset: 0x1124ed
  no variable found
  Annotate type: 'struct rtld_global' in /usr/lib64/ld-linux-x86-64.so.2 (1 samples):
  ============================================================================
      samples     offset       size  field
            1          0       4336  struct rtld_global  {
            0          0          0      struct link_namespaces*        _dl_ns;
            0       2560          8      size_t _dl_nns;
            0       2568         40      __rtld_lock_recursive_t        _dl_load_lock {
            0       2568         40          pthread_mutex_t    mutex {
            0       2568         40              struct __pthread_mutex_s       __data {
            0       2568          4                  int        __lock;
  $
 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
>  tools/perf/util/annotate-data.c | 74 +++++++++++++++++++++++++++++----
>  tools/perf/util/debug.c         |  3 ++
>  tools/perf/util/debug.h         |  1 +
>  3 files changed, 71 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
> index ff81d164aa57..f482ccfdaa91 100644
> --- a/tools/perf/util/annotate-data.c
> +++ b/tools/perf/util/annotate-data.c
> @@ -23,6 +23,29 @@
>  #include "symbol.h"
>  #include "symbol_conf.h"
>  
> +#define pr_debug_dtp(fmt, ...)					\
> +do {								\
> +	if (debug_type_profile)					\
> +		pr_info(fmt, ##__VA_ARGS__);			\
> +	else							\
> +		pr_debug3(fmt, ##__VA_ARGS__);			\
> +} while (0)
> +
> +static void pr_debug_type_name(Dwarf_Die *die)
> +{
> +	struct strbuf sb;
> +	char *str;
> +
> +	if (!debug_type_profile && verbose < 3)
> +		return;
> +
> +	strbuf_init(&sb, 32);
> +	die_get_typename_from_type(die, &sb);
> +	str = strbuf_detach(&sb, NULL);
> +	pr_info(" type=%s (die:%lx)\n", str, (long)dwarf_dieoffset(die));
> +	free(str);
> +}
> +
>  /*
>   * Compare type name and size to maintain them in a tree.
>   * I'm not sure if DWARF would have information of a single type in many
> @@ -201,7 +224,7 @@ static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset,
>  
>  	/* Get the type of the variable */
>  	if (die_get_real_type(var_die, type_die) == NULL) {
> -		pr_debug("variable has no type\n");
> +		pr_debug_dtp("variable has no type\n");
>  		ann_data_stat.no_typeinfo++;
>  		return -1;
>  	}
> @@ -215,7 +238,7 @@ static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset,
>  		if ((dwarf_tag(type_die) != DW_TAG_pointer_type &&
>  		     dwarf_tag(type_die) != DW_TAG_array_type) ||
>  		    die_get_real_type(type_die, type_die) == NULL) {
> -			pr_debug("no pointer or no type\n");
> +			pr_debug_dtp("no pointer or no type\n");
>  			ann_data_stat.no_typeinfo++;
>  			return -1;
>  		}
> @@ -223,14 +246,15 @@ static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset,
>  
>  	/* Get the size of the actual type */
>  	if (dwarf_aggregate_size(type_die, &size) < 0) {
> -		pr_debug("type size is unknown\n");
> +		pr_debug_dtp("type size is unknown\n");
>  		ann_data_stat.invalid_size++;
>  		return -1;
>  	}
>  
>  	/* Minimal sanity check */
>  	if ((unsigned)offset >= size) {
> -		pr_debug("offset: %d is bigger than size: %" PRIu64 "\n", offset, size);
> +		pr_debug_dtp("offset: %d is bigger than size: %"PRIu64"\n",
> +			     offset, size);
>  		ann_data_stat.bad_offset++;
>  		return -1;
>  	}
> @@ -251,6 +275,19 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
>  	int fb_offset = 0;
>  	bool is_fbreg = false;
>  	u64 pc;
> +	char buf[64];
> +
> +	if (dloc->op->multi_regs)
> +		snprintf(buf, sizeof(buf), " or reg%d", dloc->op->reg2);
> +	else if (dloc->op->reg1 == DWARF_REG_PC)
> +		snprintf(buf, sizeof(buf), " (PC)");
> +	else
> +		buf[0] = '\0';
> +
> +	pr_debug_dtp("-----------------------------------------------------------\n");
> +	pr_debug_dtp("%s [%"PRIx64"] for reg%d%s offset=%#x in %s\n",
> +		     __func__, dloc->ip - dloc->ms->sym->start,
> +		     dloc->op->reg1, buf, dloc->op->offset, dloc->ms->sym->name);
>  
>  	/*
>  	 * IP is a relative instruction address from the start of the map, as
> @@ -261,7 +298,7 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
>  
>  	/* Get a compile_unit for this address */
>  	if (!find_cu_die(dloc->di, pc, &cu_die)) {
> -		pr_debug("cannot find CU for address %" PRIx64 "\n", pc);
> +		pr_debug_dtp("cannot find CU for address %"PRIx64"\n", pc);
>  		ann_data_stat.no_cuinfo++;
>  		return -1;
>  	}
> @@ -269,12 +306,17 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
>  	reg = loc->reg1;
>  	offset = loc->offset;
>  
> +	pr_debug_dtp("CU die offset: %#lx\n", (long)dwarf_dieoffset(&cu_die));
> +
>  	if (reg == DWARF_REG_PC) {
>  		if (die_find_variable_by_addr(&cu_die, dloc->var_addr, &var_die,
>  					      &offset)) {
>  			ret = check_variable(&var_die, type_die, offset,
>  					     /*is_pointer=*/false);
>  			dloc->type_offset = offset;
> +
> +			pr_debug_dtp("found PC-rel by addr=%#"PRIx64" offset=%#x\n",
> +				     dloc->var_addr, offset);
>  			goto out;
>  		}
>  
> @@ -310,6 +352,9 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
>  			default:
>  				break;
>  			}
> +
> +			pr_debug_dtp("frame base: cfa=%d fbreg=%d\n",
> +				     dloc->fb_cfa, fbreg);
>  		}
>  	}
>  
> @@ -334,6 +379,19 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
>  		/* Found a variable, see if it's correct */
>  		ret = check_variable(&var_die, type_die, offset,
>  				     reg != DWARF_REG_PC && !is_fbreg);
> +		if (ret == 0) {
> +			pr_debug_dtp("found \"%s\" in scope=%d/%d (die: %#lx) ",
> +				     dwarf_diename(&var_die), i+1, nr_scopes,
> +				     (long)dwarf_dieoffset(&scopes[i]));
> +			if (reg == DWARF_REG_PC)
> +				pr_debug_dtp("%#x(PC) offset=%#x", loc->offset, offset);
> +			else if (reg == DWARF_REG_FB || is_fbreg)
> +				pr_debug_dtp("%#x(reg%d) stack fb_offset=%#x offset=%#x",
> +					     loc->offset, reg, fb_offset, offset);
> +			else
> +				pr_debug_dtp("%#x(reg%d)", loc->offset, reg);
> +			pr_debug_type_name(type_die);
> +		}
>  		dloc->type_offset = offset;
>  		goto out;
>  	}
> @@ -343,8 +401,10 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
>  		goto retry;
>  	}
>  
> -	if (ret < 0)
> +	if (ret < 0) {
> +		pr_debug_dtp("no variable found\n");
>  		ann_data_stat.no_var++;
> +	}
>  
>  out:
>  	free(scopes);
> @@ -373,7 +433,7 @@ struct annotated_data_type *find_data_type(struct data_loc_info *dloc)
>  
>  	dloc->di = debuginfo__new(dso->long_name);
>  	if (dloc->di == NULL) {
> -		pr_debug("cannot get the debug info\n");
> +		pr_debug_dtp("cannot get the debug info\n");
>  		return NULL;
>  	}
>  
> diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
> index c39ee0fcb8cf..d633d15329fa 100644
> --- a/tools/perf/util/debug.c
> +++ b/tools/perf/util/debug.c
> @@ -41,6 +41,7 @@ static int redirect_to_stderr;
>  int debug_data_convert;
>  static FILE *_debug_file;
>  bool debug_display_time;
> +int debug_type_profile;
>  
>  FILE *debug_file(void)
>  {
> @@ -231,6 +232,7 @@ static struct sublevel_option debug_opts[] = {
>  	{ .name = "data-convert",	.value_ptr = &debug_data_convert },
>  	{ .name = "perf-event-open",	.value_ptr = &debug_peo_args },
>  	{ .name = "kmaps",		.value_ptr = &debug_kmaps },
> +	{ .name = "type-profile",	.value_ptr = &debug_type_profile },
>  	{ .name = NULL, }
>  };
>  
> @@ -270,6 +272,7 @@ int perf_quiet_option(void)
>  	redirect_to_stderr = 0;
>  	debug_peo_args = 0;
>  	debug_kmaps = 0;
> +	debug_type_profile = 0;
>  
>  	return 0;
>  }
> diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
> index 35a7a5ae762e..a4026d1fd6a3 100644
> --- a/tools/perf/util/debug.h
> +++ b/tools/perf/util/debug.h
> @@ -14,6 +14,7 @@ extern int debug_peo_args;
>  extern bool quiet, dump_trace;
>  extern int debug_ordered_events;
>  extern int debug_data_convert;
> +extern int debug_type_profile;
>  
>  #ifndef pr_fmt
>  #define pr_fmt(fmt) fmt
> -- 
> 2.44.0.291.gc1ea87d7ee-goog
> 

  reply	other threads:[~2024-03-19 14:05 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-19  5:50 [PATCHSET 00/23] Remaining bits of data type profiling (v7) Namhyung Kim
2024-03-19  5:50 ` [PATCH 01/23] perf dwarf-aux: Remove unused pc argument Namhyung Kim
2024-03-19 13:43   ` Arnaldo Carvalho de Melo
2024-03-19 17:39     ` Namhyung Kim
2024-03-19  5:50 ` [PATCH 02/23] perf dwarf-aux: Add die_collect_vars() Namhyung Kim
2024-03-19 13:45   ` Arnaldo Carvalho de Melo
2024-03-19  5:50 ` [PATCH 03/23] perf dwarf-aux: Handle type transfer for memory access Namhyung Kim
2024-03-19 13:55   ` Arnaldo Carvalho de Melo
2024-03-19 17:41     ` Namhyung Kim
2024-03-19  5:50 ` [PATCH 04/23] perf dwarf-aux: Add die_find_func_rettype() Namhyung Kim
2024-03-19 13:56   ` Arnaldo Carvalho de Melo
2024-03-19 17:42     ` Namhyung Kim
2024-03-19 18:19       ` Arnaldo Carvalho de Melo
2024-03-19 20:33         ` Namhyung Kim
2024-03-19  5:50 ` [PATCH 05/23] perf map: Add map__objdump_2rip() Namhyung Kim
2024-03-19  5:50 ` [PATCH 06/23] perf annotate-data: Introduce struct data_loc_info Namhyung Kim
2024-03-19  5:50 ` [PATCH 07/23] perf annotate: Add annotate_get_basic_blocks() Namhyung Kim
2024-03-19  5:51 ` [PATCH 08/23] perf annotate-data: Add debug messages Namhyung Kim
2024-03-19 14:05   ` Arnaldo Carvalho de Melo [this message]
2024-03-19  5:51 ` [PATCH 09/23] perf annotate-data: Maintain variable type info Namhyung Kim
2024-03-19 14:07   ` Arnaldo Carvalho de Melo
2024-03-19 17:44     ` Namhyung Kim
2024-03-19 18:12       ` Arnaldo Carvalho de Melo
2024-03-19 20:34         ` Namhyung Kim
2024-03-19  5:51 ` [PATCH 10/23] perf annotate-data: Add update_insn_state() Namhyung Kim
2024-03-19  5:51 ` [PATCH 11/23] perf annotate-data: Add get_global_var_type() Namhyung Kim
2024-03-19  5:51 ` [PATCH 12/23] perf annotate-data: Handle global variable access Namhyung Kim
2024-03-19  5:51 ` [PATCH 13/23] perf annotate-data: Handle call instructions Namhyung Kim
2024-03-19  5:51 ` [PATCH 14/23] perf annotate-data: Implement instruction tracking Namhyung Kim
2024-03-19  5:51 ` [PATCH 15/23] perf annotate-data: Check register state for type Namhyung Kim
2024-03-19  5:51 ` [PATCH 16/23] perf annotate: Parse x86 segment register location Namhyung Kim
2024-03-19  5:51 ` [PATCH 17/23] perf annotate-data: Handle this-cpu variables in kernel Namhyung Kim
2024-03-19  5:51 ` [PATCH 18/23] perf annotate-data: Track instructions with a this-cpu variable Namhyung Kim
2024-03-19  5:51 ` [PATCH 19/23] perf annotate-data: Support general per-cpu access Namhyung Kim
2024-03-19  5:51 ` [PATCH 20/23] perf annotate-data: Handle ADD instructions Namhyung Kim
2024-03-19  5:51 ` [PATCH 21/23] perf annotate-data: Add stack canary type Namhyung Kim
2024-03-19  5:51 ` [PATCH 22/23] perf annotate-data: Add a cache for global variable types Namhyung Kim
2024-03-19 18:05   ` Namhyung Kim
2024-03-19 18:07     ` Arnaldo Carvalho de Melo
2024-03-19 18:09       ` Arnaldo Carvalho de Melo
2024-03-19 18:09       ` Namhyung Kim
2024-03-19  5:51 ` [PATCH 23/23] perf annotate-data: Do not retry for invalid types Namhyung Kim
2024-03-19 14:17 ` [PATCHSET 00/23] Remaining bits of data type profiling (v7) Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZfmbnBBn5qqzQd5D@x1 \
    --to=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=eranian@google.com \
    --cc=irogers@google.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-toolchains@vger.kernel.org \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.