[PATCH 04/12] perf, tools: Store variable name and register for dwarf variable lists

From: Andi Kleen
Date: Mon Nov 27 2017 - 19:26:12 EST


From: Andi Kleen <ak@xxxxxxxxxxxxxxx>

Extend the strlist returned by debuginfo__find_available_vars_at to also
directly include the variable name and the location of the resolved
variables in each node. This makes it easier to use for callers that parse the output
instead of just printing it.

Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>
---
tools/perf/util/probe-finder.c | 29 +++++++++++++++++++++++++----
tools/perf/util/probe-finder.h | 7 +++++++
2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index a5731de0e5eb..0149428d453e 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1368,9 +1368,12 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
tag = dwarf_tag(die_mem);
if (tag == DW_TAG_formal_parameter ||
tag == DW_TAG_variable) {
+ struct probe_trace_arg ta;
+
+ memset(&ta, 0, sizeof(struct probe_trace_arg));
ret = convert_variable_location(die_mem, af->pf.addr,
af->pf.fb_ops, &af->pf.sp_die,
- af->pf.machine, NULL);
+ af->pf.machine, &ta);
if (ret == 0 || ret == -ERANGE) {
int ret2;
bool externs = !af->child;
@@ -1400,8 +1403,23 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)

pr_debug("Add new var: %s\n", buf.buf);
if (ret2 == 0) {
- strlist__add(vl->vars,
- strbuf_detach(&buf, NULL));
+ struct str_node *sn;
+
+ /* Will get confused with shadowed variables */
+ sn = strlist__add_node(vl->vars,
+ strbuf_detach(&buf, NULL));
+ if (sn) {
+ struct variable_node *vn =
+ container_of(sn, struct variable_node, snode);
+ if (dwarf_diename(die_mem))
+ strlcpy(vn->name, dwarf_diename(die_mem), sizeof(vn->name));
+ else
+ vn->name[0] = 0;
+ if (ta.value)
+ strlcpy(vn->value, ta.value, sizeof(vn->value));
+ else
+ vn->value[0] = 0;
+ }
}
strbuf_release(&buf);
}
@@ -1420,6 +1438,7 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
/* Add a found vars into available variables list */
static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
{
+ static struct strlist_config sconfig = STRLIST_CONFIG_DEFAULT;
struct available_var_finder *af =
container_of(pf, struct available_var_finder, pf);
struct perf_probe_point *pp = &pf->pev->point;
@@ -1427,6 +1446,8 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
Dwarf_Die die_mem;
int ret;

+ sconfig.node_size = sizeof(struct variable_node);
+
/* Check number of tevs */
if (af->nvls == af->max_vls) {
pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
@@ -1444,7 +1465,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
vl->point.offset);

/* Find local variables */
- vl->vars = strlist__new(NULL, NULL);
+ vl->vars = strlist__new(NULL, &sconfig);
if (vl->vars == NULL)
return -ENOMEM;
af->child = true;
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 16252980ff00..6368e95a5d16 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -4,6 +4,7 @@

#include <stdbool.h>
#include "intlist.h"
+#include "strlist.h"
#include "probe-event.h"
#include "sane_ctype.h"

@@ -117,6 +118,12 @@ struct line_finder {
int found;
};

+struct variable_node {
+ struct str_node snode;
+ char value[64];
+ char name[256];
+};
+
#endif /* HAVE_DWARF_SUPPORT */

#endif /*_PROBE_FINDER_H */
--
2.13.6