perf-probe: Fix to convert array type collectly
Subsystems (2)
PATCH 1/1 perf-probe: Fix to convert array type collectly
Fix to convert array element type collectly. Current perf-probe converts the type of array-elements incorrectly. It always converts the types as a pointer of array. This passes the "array" type DIE to the type converter so that it can get correct "element of array" type DIE from it.
E.g.
====
$ cat hello.c #include <stdio.h>
void foo(int a[])
{
printf("%d\n", a[1]);}
void main()
{
int a[3] = {4, 5, 6};
printf("%d\n", a[0]);
foo(a);}
$ gcc -g hello.c -o hello $ perf probe -x ./hello -D "foo a[1]" ====
Without this fix, above outputs
====
p:probe_hello/foo /tmp/hello:0x4d3 a=+4(-8(%bp)):u64
====
The "u64" means "int *", but a[1] is "int".
With this,
====
p:probe_hello/foo /tmp/hello:0x4d3 a=+4(-8(%bp)):s32
====
So, "int" correctly converted to "s32"
Fixes b2a3c12b7442 ("perf probe: Support tracing an entry of array")
Signed-off-by Masami Hiramatsu <[email protected]>
--- tools/perf/util/probe-finder.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
tools/perf/util/probe-finder.c +5 -8
@@ -423,20 +423,20 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,pr_warning ("Failed to get the type of %s.\n" , varname);return -ENOENT ; } -pr_debug2 ("Var real type: (%x)\n" , (unsigned )dwarf_dieoffset (&type)); +pr_debug2 ("Var real type: %s (%x)\n" ,dwarf_diename (&type), + (unsigned )dwarf_dieoffset (&type)); tag =dwarf_tag (&type);if (field->name[0 ] =='[' && (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) { -if (field->next) -/* Save original type for next field */ -memcpy (die_mem, &type,sizeof (*die_mem)); +/* Save original type for next field or type */ +memcpy (die_mem, &type,sizeof (*die_mem));/* Get the type of this array */ if (die_get_real_type (&type, &type) ==NULL ) {pr_warning ("Failed to get the type of %s.\n" , varname);return -ENOENT ; } -pr_debug2 ("Array real type: (%x)\n" , +pr_debug2 ("Array real type: %s (%x)\n" ,dwarf_diename (&type), (unsigned )dwarf_dieoffset (&type));if (tag == DW_TAG_pointer_type) { ref =zalloc (sizeof (struct probe_trace_arg_ref ));
@@ -448,9 +448,6 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, *ref_ptr = ref; } ref->offset +=dwarf_bytesize (&type) * field->index; -if (!field->next) -/* Save vr_die for converting types */ -memcpy (die_mem, vr_die,sizeof (*die_mem)); goto next; }else if (tag == DW_TAG_pointer_type) {/* Check the pointer and dereference */