Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cca13bd authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo
Browse files

perf probe: Improve error message when %return is on inlined function



perf probe shows more precisely message when it finds given
%return target function is inlined.

Without this fix:
  ----
  # ./perf probe -V getname_flags%return
  Return probe must be on the head of a real function.
  Debuginfo analysis failed.
    Error: Failed to show vars.
  ----

With this fix:
  ----
  # ./perf probe -V getname_flags%return
  Failed to find "getname_flags%return",
   because getname_flags is an inlined function and has no return point.
  Debuginfo analysis failed.
    Error: Failed to show vars.
  ----

Suggested-by: default avatarArnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/20150930164137.3733.55055.stgit@localhost.localdomain


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 20f49859
Loading
Loading
Loading
Loading
+9 −4
Original line number Original line Diff line number Diff line
@@ -594,6 +594,7 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
/* Convert subprogram DIE to trace point */
/* Convert subprogram DIE to trace point */
static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
				  Dwarf_Addr paddr, bool retprobe,
				  Dwarf_Addr paddr, bool retprobe,
				  const char *function,
				  struct probe_trace_point *tp)
				  struct probe_trace_point *tp)
{
{
	Dwarf_Addr eaddr, highaddr;
	Dwarf_Addr eaddr, highaddr;
@@ -637,8 +638,10 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
	/* Return probe must be on the head of a subprogram */
	/* Return probe must be on the head of a subprogram */
	if (retprobe) {
	if (retprobe) {
		if (eaddr != paddr) {
		if (eaddr != paddr) {
			pr_warning("Return probe must be on the head of"
			pr_warning("Failed to find \"%s%%return\",\n"
				   " a real function.\n");
				   " because %s is an inlined function and"
				   " has no return point.\n", function,
				   function);
			return -EINVAL;
			return -EINVAL;
		}
		}
		tp->retprobe = true;
		tp->retprobe = true;
@@ -1178,6 +1181,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
{
{
	struct trace_event_finder *tf =
	struct trace_event_finder *tf =
			container_of(pf, struct trace_event_finder, pf);
			container_of(pf, struct trace_event_finder, pf);
	struct perf_probe_point *pp = &pf->pev->point;
	struct probe_trace_event *tev;
	struct probe_trace_event *tev;
	struct perf_probe_arg *args;
	struct perf_probe_arg *args;
	int ret, i;
	int ret, i;
@@ -1192,7 +1196,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)


	/* Trace point should be converted from subprogram DIE */
	/* Trace point should be converted from subprogram DIE */
	ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
	ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr,
				     pf->pev->point.retprobe, &tev->point);
				     pp->retprobe, pp->function, &tev->point);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


@@ -1322,6 +1326,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
{
{
	struct available_var_finder *af =
	struct available_var_finder *af =
			container_of(pf, struct available_var_finder, pf);
			container_of(pf, struct available_var_finder, pf);
	struct perf_probe_point *pp = &pf->pev->point;
	struct variable_list *vl;
	struct variable_list *vl;
	Dwarf_Die die_mem;
	Dwarf_Die die_mem;
	int ret;
	int ret;
@@ -1335,7 +1340,7 @@ static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)


	/* Trace point should be converted from subprogram DIE */
	/* Trace point should be converted from subprogram DIE */
	ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
	ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr,
				     pf->pev->point.retprobe, &vl->point);
				     pp->retprobe, pp->function, &vl->point);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;