Skip to contentSkip to conversation

perf probe: can't find unnamed union members

PATCH Superseded Arnaldo Carvalho de Melo 3 participants 10 messages Mar 5, 2015 – Apr 3, 2015 perf events

lore
Share & tools
lore

Arnaldo Carvalho de Melo

author maintainer
#0 lore raw

Hi Masami,

[root@zoo ~]# perf probe -x ~/bin/perf -L lock__delete <lock__delete@/home/git/linux/tools/perf/util/annotate.c:0>

      0  static void lock__delete(struct ins_operands *ops)
      1  {
      2         struct ins *ins = ops->locked.ins;
         
      4         if (ins && ins->ops->free)
      5                 ins->ops->free(ops->locked.ops);
                else
      7                 ins__delete(ops->locked.ops);
         
      9         zfree(&ops->locked.ops);
     10         zfree(&ops->target.raw);
     11         zfree(&ops->target.name);
     12  }

And:

[root@zoo ~]# pahole ~/bin/perf -C ins_operands

struct ins_operands {
	char *                     raw;                  /*     0     8 */
	struct {
		char *             raw;                  /*     8     8 */
		char *             name;                 /*    16     8 */
		u64                addr;                 /*    24     8 */
		u64                offset;               /*    32     8 */
	} target;                                        /*     8    32 */
	union {
		struct {
			char *     raw;                  /*    40     8 */
			char *     name;                 /*    48     8 */
			u64        addr;                 /*    56     8 */
		} source;                                /*          24 */
		struct {
			struct ins * ins;                /*    40     8 */
			struct ins_operands * ops;       /*    48     8 */
		} locked;                                /*          16 */
	};                                               /*    40    24 */
	/* --- cacheline 1 boundary (64 bytes) --- */

	/* size: 64, cachelines: 1, members: 3 */
};

[root@zoo ~]#

But:

[root@zoo ~]# perf probe -x ~/bin/perf lock__delete ops 'locked_ops=ops->locked.ops' ops(type:ins_operands) has no member locked.
Error: Failed to add events.
[root@zoo ~]#

Yes, it has :-)

- Arnaldo

#1 lore raw

Hi,

Quoted 46 lines · Arnaldo Carvalho de Melo

Hi Masami,

[root@zoo ~]# perf probe -x ~/bin/perf -L lock__delete <lock__delete@/home/git/linux/tools/perf/util/annotate.c:0>

      0  static void lock__delete(struct ins_operands *ops)
      1  {
      2         struct ins *ins = ops->locked.ins;
         
      4         if (ins && ins->ops->free)
      5                 ins->ops->free(ops->locked.ops);
                else
      7                 ins__delete(ops->locked.ops);
         
      9         zfree(&ops->locked.ops);
     10         zfree(&ops->target.raw);
     11         zfree(&ops->target.name);
     12  }

And:

[root@zoo ~]# pahole ~/bin/perf -C ins_operands

struct ins_operands {
	char *                     raw;                  /*     0     8 */
	struct {
		char *             raw;                  /*     8     8 */
		char *             name;                 /*    16     8 */
		u64                addr;                 /*    24     8 */
		u64                offset;               /*    32     8 */
	} target;                                        /*     8    32 */
	union {
		struct {
			char *     raw;                  /*    40     8 */
			char *     name;                 /*    48     8 */
			u64        addr;                 /*    56     8 */
		} source;                                /*          24 */
		struct {
			struct ins * ins;                /*    40     8 */
			struct ins_operands * ops;       /*    48     8 */
		} locked;                                /*          16 */
	};                                               /*    40    24 */
	/* --- cacheline 1 boundary (64 bytes) --- */

	/* size: 64, cachelines: 1, members: 3 */
};

[root@zoo ~]#

Quoted 8 lines

But:

[root@zoo ~]# perf probe -x ~/bin/perf lock__delete ops 'locked_ops=ops->locked.ops' ops(type:ins_operands) has no member locked.
Error: Failed to add events.
[root@zoo ~]#

Yes, it has :-)

Oh, I see. That is not yet supported.
Here, I got the structure in debuginfo.

[ fac4e] structure_type

             name                 (strp) "ins_operands"
             byte_size            (data1) 64
             decl_file            (data1) 5
             decl_line            (data1) 16
             sibling              (ref4) [ fac79]
 [ fac5a]      member
               name                 (string) "raw"
               decl_file            (data1) 5
               decl_line            (data1) 17
               type                 (ref4) [ f8bdb]
               data_member_location (data1) 0
 [ fac66]      member
               name                 (strp) "target"
               decl_file            (data1) 5
               decl_line            (data1) 23
               type                 (ref4) [ fab9c]
               data_member_location (data1) 8
 [ fac72]      member					<= here is the unnamed one
               type                 (ref4) [ fac7f]
               data_member_location (data1) 28
 [ fac79]    pointer_type
             byte_size            (data1) 8
             type                 (ref4) [ fac4e]
 [ fac7f]    union_type
             byte_size            (data1) 24
             decl_file            (data1) 5
             decl_line            (data1) 24
             sibling              (ref4) [ fac9e]
 [ fac87]      member
               name                 (strp) "source"
               decl_file            (data1) 5
               decl_line            (data1) 29
               type                 (ref4) [ fabd5]
 [ fac92]      member					<= here is actual member
               name                 (strp) "locked"
               decl_file            (data1) 5
               decl_line            (data1) 33
               type                 (ref4) [ fac02]

Let me see how I can solve this...

Thank you for reporting!

Quoted 3 lines

- Arnaldo

Signature · 4 lines
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: [email protected]
#2 lore raw

PATCH 1/1 perf-probe: Fix to track down unnamed union/structure members

In reply to Arnaldo Carvalho de Melo

Fix perf probe to track down unnamed union/structure members. perf probe did not track down the tree of unnamed union/structure members, since it just failed to find given "name" in a parent structure/union. To solve this issue, I've introduced 2 changes.

- Fix die_find_member() to track down the type-DIE if it is unnamed, and if it contains the specified member, returns the unnamed member.
(note that we don't return found member, since unnamed member
has the offset in the parent structure)
- Fix convert_variable_fields() to track down the unnamed union/ structure (one-by-one).

With this patch, perf probe can access unnamed fields.
-----
#./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event:

    probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops)

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1
-----

The original report of this issue is: https://lkml.org/lkml/2015/3/5/431

---
 tools/perf/util/dwarf-aux.c    |   14 ++++++++++----
 tools/perf/util/probe-finder.c |    8 +++++++-
 2 files changed, 17 insertions(+), 5 deletions(-)
tools/perf/util/dwarf-aux.c +10 -4
index 780b2bc..c34e024 100644
@@ -801,10 +801,16 @@ static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
 {
 	const char *name = data;
 
-	if ((dwarf_tag(die_mem) == DW_TAG_member) &&
-	    die_compare_name(die_mem, name))
-		return DIE_FIND_CB_END;
-
+	if (dwarf_tag(die_mem) == DW_TAG_member) {
+		if (die_compare_name(die_mem, name))
+			return DIE_FIND_CB_END;
+		else if (!dwarf_diename(die_mem)) {	/* Unnamed structure */
+			Dwarf_Die type_die, tmp_die;
+			if (die_get_type(die_mem, &type_die) &&
+			    die_find_member(&type_die, name, &tmp_die))
+				return DIE_FIND_CB_END;
+		}
+	}
 	return DIE_FIND_CB_SIBLING;
 }
 
tools/perf/util/probe-finder.c +7 -1
index 46f009a..3898eba 100644
@@ -460,7 +460,8 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 			       " nor array.\n", varname);
 			return -EINVAL;
 		}
-		if (field->ref) {
+		/* While prcessing unnamed field, we don't care about this */
+		if (field->ref && !dwarf_diename(vr_die)) {
 			pr_err("Semantic error: %s must be referred by '.'\n",
 			       field->name);
 			return -EINVAL;
@@ -491,6 +492,11 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 	}
 	ref->offset += (long)offs;
 
+	/* If this member is unnamed, we need to reuse this field */
+	if (!dwarf_diename(die_mem))
+		return convert_variable_fields(die_mem, varname, field,
+						&ref, die_mem);
+
 next:
 	/* Converting next field */
 	if (field->next)
#3 lore raw

Re: [PATCH perf/core ] perf-probe: Fix to track down unnamed union/structure members

Ping?

Quoted 86 lines · Masami Hiramatsu

Fix perf probe to track down unnamed union/structure members. perf probe did not track down the tree of unnamed union/structure members, since it just failed to find given "name" in a parent structure/union. To solve this issue, I've introduced 2 changes.

- Fix die_find_member() to track down the type-DIE if it is unnamed, and if it contains the specified member, returns the unnamed member.
(note that we don't return found member, since unnamed member
has the offset in the parent structure)
- Fix convert_variable_fields() to track down the unnamed union/ structure (one-by-one).

With this patch, perf probe can access unnamed fields.
-----
#./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event:

    probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops)

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1
-----

The original report of this issue is: https://lkml.org/lkml/2015/3/5/431

---
 tools/perf/util/dwarf-aux.c    |   14 ++++++++++----
 tools/perf/util/probe-finder.c |    8 +++++++-
 2 files changed, 17 insertions(+), 5 deletions(-)
tools/perf/util/dwarf-aux.c +10 -4
index 780b2bc..c34e024 100644
@@ -801,10 +801,16 @@ static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
 {
 	const char *name = data;
 
-	if ((dwarf_tag(die_mem) == DW_TAG_member) &&
-	    die_compare_name(die_mem, name))
-		return DIE_FIND_CB_END;
-
+	if (dwarf_tag(die_mem) == DW_TAG_member) {
+		if (die_compare_name(die_mem, name))
+			return DIE_FIND_CB_END;
+		else if (!dwarf_diename(die_mem)) {	/* Unnamed structure */
+			Dwarf_Die type_die, tmp_die;
+			if (die_get_type(die_mem, &type_die) &&
+			    die_find_member(&type_die, name, &tmp_die))
+				return DIE_FIND_CB_END;
+		}
+	}
 	return DIE_FIND_CB_SIBLING;
 }
 
tools/perf/util/probe-finder.c +7 -1
index 46f009a..3898eba 100644
@@ -460,7 +460,8 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 			       " nor array.\n", varname);
 			return -EINVAL;
 		}
-		if (field->ref) {
+		/* While prcessing unnamed field, we don't care about this */
+		if (field->ref && !dwarf_diename(vr_die)) {
 			pr_err("Semantic error: %s must be referred by '.'\n",
 			       field->name);
 			return -EINVAL;
@@ -491,6 +492,11 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 	}
 	ref->offset += (long)offs;
 
+	/* If this member is unnamed, we need to reuse this field */
+	if (!dwarf_diename(die_mem))
+		return convert_variable_fields(die_mem, varname, field,
+						&ref, die_mem);
+
 next:
 	/* Converting next field */
 	if (field->next)
Signature · 4 lines
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: [email protected]
author maintainer
#4 lore raw

Re: [PATCH perf/core ] perf-probe: Fix to track down unnamed union/structure members

Em Wed, Apr 01, 2015 at 06:08:17PM +0900, Masami Hiramatsu escreveu:

Quoted 1 line

Ping?

<SNIP>

Quoted 6 lines
Quoted 5 lines

With this patch, perf probe can access unnamed fields.
-----
#./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event:

    probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops)
Quoted 6 lines
Quoted 6 lines

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1
-----

The original report of this issue is: https://lkml.org/lkml/2015/3/5/431

what am I doing wrong?

[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops' Added new event:
probe_perf:lock__delete (on lock__delete in /home/acme/bin/perf with locked_ops=ops)

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1

[root@ssdandy ~]# perf probe -d probe_perf:*
Removed event: probe_perf:lock__delete
[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops->locked' Semantic error: locked must be referred by '.'
Error: Failed to add events.
[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops.locked' Semantic error: locked must be referred by '->'
Error: Failed to add events.
[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops->locked' Semantic error: locked must be referred by '.'
Error: Failed to add events.
[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops->locked.ops' Semantic error: locked must be referred by '.'
Error: Failed to add events.
[root@ssdandy ~]#

#5 lore raw

Re: Re: [PATCH perf/core ] perf-probe: Fix to track down unnamed union/structure members

Quoted 28 lines · Arnaldo Carvalho de Melo

Em Wed, Apr 01, 2015 at 06:08:17PM +0900, Masami Hiramatsu escreveu:

Quoted 1 line

Ping?

<SNIP>

Quoted 6 lines
Quoted 5 lines

With this patch, perf probe can access unnamed fields.
-----
#./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event:

    probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops)
Quoted 6 lines
Quoted 6 lines

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1
-----

The original report of this issue is: https://lkml.org/lkml/2015/3/5/431

what am I doing wrong?

[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops' Added new event:
probe_perf:lock__delete (on lock__delete in /home/acme/bin/perf with locked_ops=ops)

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1

Quoted 15 lines

[root@ssdandy ~]# perf probe -d probe_perf:*
Removed event: probe_perf:lock__delete
[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops->locked' Semantic error: locked must be referred by '.'
Error: Failed to add events.
[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops.locked' Semantic error: locked must be referred by '->'
Error: Failed to add events.
[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops->locked' Semantic error: locked must be referred by '.'
Error: Failed to add events.
[root@ssdandy ~]# perf probe ~acme/bin/perf lock__delete 'locked_ops=ops->locked.ops' Semantic error: locked must be referred by '.'
Error: Failed to add events.
[root@ssdandy ~]#

Oops, thank you for reporting!
I must miss something...

Thank you,

Quoted 6 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Signature · 5 lines
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: [email protected]
#6 lore raw

PATCH v2 1/1 perf-probe: Fix to track down unnamed union/structure members

In reply to Arnaldo Carvalho de Melo

Fix perf probe to track down unnamed union/structure members. perf probe did not track down the tree of unnamed union/structure members, since it just failed to find given "name" in a parent structure/union. To solve this issue, I've introduced 2 changes.

- Fix die_find_member() to track down the type-DIE if it is unnamed, and if it contains the specified member, returns the unnamed member.
(note that we don't return found member, since unnamed member
has the offset in the parent structure)
- Fix convert_variable_fields() to track down the unnamed union/ structure (one-by-one).

With this patch, perf probe can access unnamed fields.
-----
#./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event:

    probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops)

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1
-----

The original report of this issue is: https://lkml.org/lkml/2015/3/5/431

---
 tools/perf/util/dwarf-aux.c    |   14 ++++++++++----
 tools/perf/util/probe-finder.c |    8 +++++++-
 2 files changed, 17 insertions(+), 5 deletions(-)
tools/perf/util/dwarf-aux.c +10 -4
index 780b2bc..c34e024 100644
@@ -801,10 +801,16 @@ static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
 {
 	const char *name = data;
 
-	if ((dwarf_tag(die_mem) == DW_TAG_member) &&
-	    die_compare_name(die_mem, name))
-		return DIE_FIND_CB_END;
-
+	if (dwarf_tag(die_mem) == DW_TAG_member) {
+		if (die_compare_name(die_mem, name))
+			return DIE_FIND_CB_END;
+		else if (!dwarf_diename(die_mem)) {	/* Unnamed structure */
+			Dwarf_Die type_die, tmp_die;
+			if (die_get_type(die_mem, &type_die) &&
+			    die_find_member(&type_die, name, &tmp_die))
+				return DIE_FIND_CB_END;
+		}
+	}
 	return DIE_FIND_CB_SIBLING;
 }
 
tools/perf/util/probe-finder.c +7 -1
index 46f009a..7831e2d 100644
@@ -460,7 +460,8 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 			       " nor array.\n", varname);
 			return -EINVAL;
 		}
-		if (field->ref) {
+		/* While prcessing unnamed field, we don't care about this */
+		if (field->ref && dwarf_diename(vr_die)) {
 			pr_err("Semantic error: %s must be referred by '.'\n",
 			       field->name);
 			return -EINVAL;
@@ -491,6 +492,11 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 	}
 	ref->offset += (long)offs;
 
+	/* If this member is unnamed, we need to reuse this field */
+	if (!dwarf_diename(die_mem))
+		return convert_variable_fields(die_mem, varname, field,
+						&ref, die_mem);
+
 next:
 	/* Converting next field */
 	if (field->next)
author maintainer
#7 lore raw

Re: [PATCH perf/core v2] perf-probe: Fix to track down unnamed union/structure members

Em Thu, Apr 02, 2015 at 04:33:12PM +0900, Masami Hiramatsu escreveu:

Quoted 17 lines

Fix perf probe to track down unnamed union/structure members. perf probe did not track down the tree of unnamed union/structure members, since it just failed to find given "name" in a parent structure/union. To solve this issue, I've introduced 2 changes.

- Fix die_find_member() to track down the type-DIE if it is unnamed, and if it contains the specified member, returns the unnamed member.
(note that we don't return found member, since unnamed member
has the offset in the parent structure)
- Fix convert_variable_fields() to track down the unnamed union/ structure (one-by-one).

With this patch, perf probe can access unnamed fields.
-----
#./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event:

Quoted 8 lines
    probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops)

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1
-----

The original report of this issue is: https://lkml.org/lkml/2015/3/5/431

Thanks a lot! Applied, built and tested, all works as expected,

Merged,

- Arnaldo

#8 lore raw

[tip:perf/core] perf probe: Fix to track down unnamed union/ structure members

In reply to Masami Hiramatsu
perf probe: Fix to track down unnamed union/structure members
Commit-ID:  c72738355b2ac79506fbfa10ffee8fe3a27e69da
Gitweb:     http://git.kernel.org/tip/c72738355b2ac79506fbfa10ffee8fe3a27e69da
Author:     Masami Hiramatsu <[email protected]>
AuthorDate: Thu, 2 Apr 2015 16:33:12 +0900
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Thu, 2 Apr 2015 13:18:44 -0300

perf probe: Fix to track down unnamed union/structure members

Fix 'perf probe' to track down unnamed union/structure members.

perf probe did not track down the tree of unnamed union/structure members, since it just failed to find given "name" in a parent structure/union. To solve this issue, I've introduced 2 changes.

- Fix die_find_member() to track down the type-DIE if it is unnamed, and if it contains the specified member, returns the unnamed member.
(note that we don't return found member, since unnamed member
has the offset in the parent structure)
- Fix convert_variable_fields() to track down the unnamed union/ structure (one-by-one).

With this patch, perf probe can access unnamed fields:
-----
#./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event:

    probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops)

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1
-----

Report-Link: https://lkml.org/lkml/2015/3/5/431

---
 tools/perf/util/dwarf-aux.c    | 14 ++++++++++----
 tools/perf/util/probe-finder.c |  8 +++++++-
 2 files changed, 17 insertions(+), 5 deletions(-)
tools/perf/util/dwarf-aux.c +10 -4
index 780b2bc..c34e024 100644
@@ -801,10 +801,16 @@ static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
 {
 	const char *name = data;
 
-	if ((dwarf_tag(die_mem) == DW_TAG_member) &&
-	    die_compare_name(die_mem, name))
-		return DIE_FIND_CB_END;
-
+	if (dwarf_tag(die_mem) == DW_TAG_member) {
+		if (die_compare_name(die_mem, name))
+			return DIE_FIND_CB_END;
+		else if (!dwarf_diename(die_mem)) {	/* Unnamed structure */
+			Dwarf_Die type_die, tmp_die;
+			if (die_get_type(die_mem, &type_die) &&
+			    die_find_member(&type_die, name, &tmp_die))
+				return DIE_FIND_CB_END;
+		}
+	}
 	return DIE_FIND_CB_SIBLING;
 }
 
tools/perf/util/probe-finder.c +7 -1
index 46f009a..7831e2d 100644
@@ -460,7 +460,8 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 			       " nor array.\n", varname);
 			return -EINVAL;
 		}
-		if (field->ref) {
+		/* While prcessing unnamed field, we don't care about this */
+		if (field->ref && dwarf_diename(vr_die)) {
 			pr_err("Semantic error: %s must be referred by '.'\n",
 			       field->name);
 			return -EINVAL;
@@ -491,6 +492,11 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 	}
 	ref->offset += (long)offs;
 
+	/* If this member is unnamed, we need to reuse this field */
+	if (!dwarf_diename(die_mem))
+		return convert_variable_fields(die_mem, varname, field,
+						&ref, die_mem);
+
 next:
 	/* Converting next field */
 	if (field->next)
#9 lore raw

Re: [PATCH perf/core ] perf-probe: Fix to track down unnamed union/structure members

In reply to Masami Hiramatsu
Quoted 63 lines · Masami Hiramatsu

Fix perf probe to track down unnamed union/structure members. perf probe did not track down the tree of unnamed union/structure members, since it just failed to find given "name" in a parent structure/union. To solve this issue, I've introduced 2 changes.

- Fix die_find_member() to track down the type-DIE if it is unnamed, and if it contains the specified member, returns the unnamed member.
(note that we don't return found member, since unnamed member
has the offset in the parent structure)
- Fix convert_variable_fields() to track down the unnamed union/ structure (one-by-one).

With this patch, perf probe can access unnamed fields.
-----
#./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event:

    probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops)

You can now use it in all perf tools, such as:

perf record -e probe_perf:lock__delete -aR sleep 1
-----

The original report of this issue is: https://lkml.org/lkml/2015/3/5/431

---
 tools/perf/util/dwarf-aux.c    |   14 ++++++++++----
 tools/perf/util/probe-finder.c |    8 +++++++-
 2 files changed, 17 insertions(+), 5 deletions(-)
tools/perf/util/dwarf-aux.c +10 -4
index 780b2bc..c34e024 100644
@@ -801,10 +801,16 @@ static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
 {
 	const char *name = data;
 
-	if ((dwarf_tag(die_mem) == DW_TAG_member) &&
-	    die_compare_name(die_mem, name))
-		return DIE_FIND_CB_END;
-
+	if (dwarf_tag(die_mem) == DW_TAG_member) {
+		if (die_compare_name(die_mem, name))
+			return DIE_FIND_CB_END;
+		else if (!dwarf_diename(die_mem)) {	/* Unnamed structure */
+			Dwarf_Die type_die, tmp_die;
+			if (die_get_type(die_mem, &type_die) &&
+			    die_find_member(&type_die, name, &tmp_die))
+				return DIE_FIND_CB_END;
+		}
+	}
 	return DIE_FIND_CB_SIBLING;
 }
 
tools/perf/util/probe-finder.c +0 -0
index 46f009a..3898eba 100644

tools/perf/util/probe-finder.c static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, · line 464

Quoted 6 lines
tools/perf/util/probe-finder.c +2 -1
@@ -460,7 +460,8 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 			       " nor array.\n", varname);
 			return -EINVAL;
 		}
-		if (field->ref) {
+		/* While prcessing unnamed field, we don't care about this */
+		if (field->ref && !dwarf_diename(vr_die)) {

^^ Oops! this should be inverted!
I've missed to include a local fix to this patch...

Thank you,

Quoted 17 lines
tools/perf/util/probe-finder.c +5 -0
 			pr_err("Semantic error: %s must be referred by '.'\n",
 			       field->name);
 			return -EINVAL;
@@ -491,6 +492,11 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 	}
 	ref->offset += (long)offs;
 
+	/* If this member is unnamed, we need to reuse this field */
+	if (!dwarf_diename(die_mem))
+		return convert_variable_fields(die_mem, varname, field,
+						&ref, die_mem);
+
 next:
 	/* Converting next field */
 	if (field->next)
Signature · 4 lines
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: [email protected]