perf probe: Use right type to access array elements
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"
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Tom Zanussi <tom.zanussi@linux.intel.com>
Cc: linux-kselftest@vger.kernel.org
Cc: linux-trace-users@vger.kernel.org
Fixes: b2a3c12b74
("perf probe: Support tracing an entry of array")
Link: http://lkml.kernel.org/r/152129114502.31874.2474068470011496356.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
4c9cb2c2b4
commit
d0461794a1
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user