public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Masami Hiramatsu <mhiramat@redhat.com>
To: linux-tip-commits@vger.kernel.org
Cc: mingo@redhat.com, peterz@infradead.org, fweisbec@gmail.com,
	rostedt@goodmis.org, jbaron@redhat.com, tglx@linutronix.de,
	mhiramat@redhat.com, hpa@zytor.com, fche@redhat.com,
	linux-kernel@vger.kernel.org, jkenisto@us.ibm.com,
	hch@infradead.org, ananth@in.ibm.com, srikar@linux.vnet.ibm.com,
	prasad@linux.vnet.ibm.com, mingo@elte.hu
Subject: [tip:perf/probes] perf/probes: Support function entry relative line number
Date: Thu, 29 Oct 2009 08:09:26 GMT	[thread overview]
Message-ID: <tip-b0ef07324310d66f660a311d4a8d669eda74f801@git.kernel.org> (raw)
In-Reply-To: <20091027204319.30545.30678.stgit@harusame>

Commit-ID:  b0ef07324310d66f660a311d4a8d669eda74f801
Gitweb:     http://git.kernel.org/tip/b0ef07324310d66f660a311d4a8d669eda74f801
Author:     Masami Hiramatsu <mhiramat@redhat.com>
AuthorDate: Tue, 27 Oct 2009 16:43:19 -0400
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 29 Oct 2009 08:47:49 +0100

perf/probes: Support function entry relative line number

Add function-entry relative line number specifying support to
perf-probe. This allows users to define probes by line number
from entry of the function.

 e.g.

  perf probe schedule:16

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: K.Prasad <prasad@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
LKML-Reference: <20091027204319.30545.30678.stgit@harusame>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 tools/perf/builtin-probe.c     |   14 ++++----
 tools/perf/util/probe-finder.c |   79 +++++++++++++++++++++++++++++++---------
 tools/perf/util/probe-finder.h |    2 +
 3 files changed, 70 insertions(+), 25 deletions(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 92b4c49..a99a366 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -133,17 +133,16 @@ static void parse_probe_point(char *arg, struct probe_point *pp)
 	}
 
 	/* Exclusion check */
-	if (pp->line && pp->function)
-		semantic_error("Function-relative line number is not"
-				" supported yet.");
+	if (pp->line && pp->offset)
+		semantic_error("Offset can't be used with line number.");
 	if (!pp->line && pp->file && !pp->function)
 		semantic_error("File always requires line number.");
 	if (pp->offset && !pp->function)
 		semantic_error("Offset requires an entry function.");
 	if (pp->retprobe && !pp->function)
 		semantic_error("Return probe requires an entry function.");
-	if (pp->offset && pp->retprobe)
-		semantic_error("Offset can't be used with return probe.");
+	if ((pp->offset || pp->line) && pp->retprobe)
+		semantic_error("Offset/Line can't be used with return probe.");
 
 	pr_debug("symbol:%s file:%s line:%d offset:%d, return:%d\n",
 		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe);
@@ -270,7 +269,7 @@ static const struct option options[] = {
 #ifdef NO_LIBDWARF
 		"FUNC[+OFFS|%return] [ARG ...]",
 #else
-		"FUNC[+OFFS|%return][@SRC]|SRC:LINE [ARG ...]",
+		"FUNC[+OFFS|%return|:RLN][@SRC]|SRC:ALN [ARG ...]",
 #endif
 		"probe point definition, where\n"
 		"\t\tGRP:\tGroup name (optional)\n"
@@ -282,7 +281,8 @@ static const struct option options[] = {
 		"\t\tARG:\tProbe argument (only \n"
 #else
 		"\t\tSRC:\tSource code path\n"
-		"\t\tLINE:\tLine number\n"
+		"\t\tRLN:\tRelative line number from function entry.\n"
+		"\t\tALN:\tAbsolute line number in file.\n"
 		"\t\tARG:\tProbe argument (local variable name or\n"
 #endif
 		"\t\t\tkprobe-tracer argument format is supported.)\n",
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 6d3bac9..db96186 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -114,7 +114,7 @@ static int strtailcmp(const char *s1, const char *s2)
 }
 
 /* Find the fileno of the target file. */
-static Dwarf_Unsigned die_get_fileno(Dwarf_Die cu_die, const char *fname)
+static Dwarf_Unsigned cu_find_fileno(Dwarf_Die cu_die, const char *fname)
 {
 	Dwarf_Signed cnt, i;
 	Dwarf_Unsigned found = 0;
@@ -335,6 +335,36 @@ static int attr_get_locdesc(Dwarf_Attribute attr, Dwarf_Locdesc *desc,
 	return ret;
 }
 
+/* Get decl_file attribute value (file number) */
+static Dwarf_Unsigned die_get_decl_file(Dwarf_Die sp_die)
+{
+	Dwarf_Attribute attr;
+	Dwarf_Unsigned fno;
+	int ret;
+
+	ret = dwarf_attr(sp_die, DW_AT_decl_file, &attr, &__dw_error);
+	DIE_IF(ret != DW_DLV_OK);
+	dwarf_formudata(attr, &fno, &__dw_error);
+	DIE_IF(ret != DW_DLV_OK);
+	dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+	return fno;
+}
+
+/* Get decl_line attribute value (line number) */
+static Dwarf_Unsigned die_get_decl_line(Dwarf_Die sp_die)
+{
+	Dwarf_Attribute attr;
+	Dwarf_Unsigned lno;
+	int ret;
+
+	ret = dwarf_attr(sp_die, DW_AT_decl_line, &attr, &__dw_error);
+	DIE_IF(ret != DW_DLV_OK);
+	dwarf_formudata(attr, &lno, &__dw_error);
+	DIE_IF(ret != DW_DLV_OK);
+	dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
+	return lno;
+}
+
 /*
  * Probe finder related functions
  */
@@ -501,6 +531,7 @@ static void show_probepoint(Dwarf_Die sp_die, Dwarf_Signed offs,
 	DIE_IF(ret < 0);
 	DIE_IF(ret >= MAX_PROBE_BUFFER);
 	len = ret;
+	pr_debug("Probe point found: %s\n", tmp);
 
 	/* Find each argument */
 	get_current_frame_base(sp_die, pf);
@@ -536,17 +567,16 @@ static int probeaddr_callback(struct die_link *dlink, void *data)
 }
 
 /* Find probe point from its line number */
-static void find_by_line(Dwarf_Die cu_die, struct probe_finder *pf)
+static void find_by_line(struct probe_finder *pf)
 {
-	struct probe_point *pp = pf->pp;
-	Dwarf_Signed cnt, i;
+	Dwarf_Signed cnt, i, clm;
 	Dwarf_Line *lines;
 	Dwarf_Unsigned lineno = 0;
 	Dwarf_Addr addr;
 	Dwarf_Unsigned fno;
 	int ret;
 
-	ret = dwarf_srclines(cu_die, &lines, &cnt, &__dw_error);
+	ret = dwarf_srclines(pf->cu_die, &lines, &cnt, &__dw_error);
 	DIE_IF(ret != DW_DLV_OK);
 
 	for (i = 0; i < cnt; i++) {
@@ -557,15 +587,20 @@ static void find_by_line(Dwarf_Die cu_die, struct probe_finder *pf)
 
 		ret = dwarf_lineno(lines[i], &lineno, &__dw_error);
 		DIE_IF(ret != DW_DLV_OK);
-		if (lineno != (Dwarf_Unsigned)pp->line)
+		if (lineno != pf->lno)
 			continue;
 
+		ret = dwarf_lineoff(lines[i], &clm, &__dw_error);
+		DIE_IF(ret != DW_DLV_OK);
+
 		ret = dwarf_lineaddr(lines[i], &addr, &__dw_error);
 		DIE_IF(ret != DW_DLV_OK);
-		pr_debug("Probe point found: 0x%llx\n", addr);
+		pr_debug("Probe line found: line[%d]:%u,%d addr:0x%llx\n",
+			 (int)i, (unsigned)lineno, (int)clm, addr);
 		pf->addr = addr;
 		/* Search a real subprogram including this line, */
-		ret = search_die_from_children(cu_die, probeaddr_callback, pf);
+		ret = search_die_from_children(pf->cu_die,
+					       probeaddr_callback, pf);
 		if (ret == 0)
 			die("Probe point is not found in subprograms.\n");
 		/* Continuing, because target line might be inlined. */
@@ -587,6 +622,13 @@ static int probefunc_callback(struct die_link *dlink, void *data)
 	DIE_IF(ret == DW_DLV_ERROR);
 	if (tag == DW_TAG_subprogram) {
 		if (die_compare_name(dlink->die, pp->function) == 0) {
+			if (pp->line) {	/* Function relative line */
+				pf->fno = die_get_decl_file(dlink->die);
+				pf->lno = die_get_decl_line(dlink->die)
+					 + pp->line;
+				find_by_line(pf);
+				return 1;
+			}
 			if (die_inlined_subprogram(dlink->die)) {
 				/* Inlined function, save it. */
 				ret = dwarf_die_CU_offset(dlink->die,
@@ -631,9 +673,9 @@ found:
 	return 0;
 }
 
-static void find_by_func(Dwarf_Die cu_die, struct probe_finder *pf)
+static void find_by_func(struct probe_finder *pf)
 {
-	search_die_from_children(cu_die, probefunc_callback, pf);
+	search_die_from_children(pf->cu_die, probefunc_callback, pf);
 }
 
 /* Find a probe point */
@@ -641,7 +683,6 @@ int find_probepoint(int fd, struct probe_point *pp)
 {
 	Dwarf_Half addr_size = 0;
 	Dwarf_Unsigned next_cuh = 0;
-	Dwarf_Die cu_die = 0;
 	int cu_number = 0, ret;
 	struct probe_finder pf = {.pp = pp};
 
@@ -659,25 +700,27 @@ int find_probepoint(int fd, struct probe_point *pp)
 			break;
 
 		/* Get the DIE(Debugging Information Entry) of this CU */
-		ret = dwarf_siblingof(__dw_debug, 0, &cu_die, &__dw_error);
+		ret = dwarf_siblingof(__dw_debug, 0, &pf.cu_die, &__dw_error);
 		DIE_IF(ret != DW_DLV_OK);
 
 		/* Check if target file is included. */
 		if (pp->file)
-			pf.fno = die_get_fileno(cu_die, pp->file);
+			pf.fno = cu_find_fileno(pf.cu_die, pp->file);
 
 		if (!pp->file || pf.fno) {
 			/* Save CU base address (for frame_base) */
-			ret = dwarf_lowpc(cu_die, &pf.cu_base, &__dw_error);
+			ret = dwarf_lowpc(pf.cu_die, &pf.cu_base, &__dw_error);
 			DIE_IF(ret == DW_DLV_ERROR);
 			if (ret == DW_DLV_NO_ENTRY)
 				pf.cu_base = 0;
-			if (pp->line)
-				find_by_line(cu_die, &pf);
 			if (pp->function)
-				find_by_func(cu_die, &pf);
+				find_by_func(&pf);
+			else {
+				pf.lno = pp->line;
+				find_by_line(&pf);
+			}
 		}
-		dwarf_dealloc(__dw_debug, cu_die, DW_DLA_DIE);
+		dwarf_dealloc(__dw_debug, pf.cu_die, DW_DLA_DIE);
 	}
 	ret = dwarf_finish(__dw_debug, &__dw_error);
 	DIE_IF(ret != DW_DLV_OK);
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 240d6cb..bdebca6 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -41,7 +41,9 @@ struct probe_finder {
 	/* For function searching */
 	Dwarf_Addr	addr;		/* Address */
 	Dwarf_Unsigned	fno;		/* File number */
+	Dwarf_Unsigned	lno;		/* Line number */
 	Dwarf_Off	inl_offs;	/* Inline offset */
+	Dwarf_Die	cu_die;		/* Current CU */
 
 	/* For variable searching */
 	Dwarf_Addr	cu_base;	/* Current CU base address */

  reply	other threads:[~2009-10-29  8:12 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-27 20:41 [PATCH -tip perf/probes 00/10] x86 insn decoder bugfixes Masami Hiramatsu
2009-10-27 20:42 ` [PATCH -tip perf/probes 01/10] x86: Fix SSE opcode map bug Masami Hiramatsu
2009-10-29  8:06   ` [tip:perf/probes] " tip-bot for Masami Hiramatsu
2009-10-27 20:42 ` [PATCH -tip perf/probes 02/10] x86: Merge INAT_REXPFX into INAT_PFX_* Masami Hiramatsu
2009-10-29  8:07   ` [tip:perf/probes] " tip-bot for Masami Hiramatsu
2009-10-27 20:42 ` [PATCH -tip perf/probes 03/10] x86: Add pclmulq to x86 opcode map Masami Hiramatsu
2009-10-29  8:07   ` [tip:perf/probes] " tip-bot for Masami Hiramatsu
2009-10-27 20:42 ` [PATCH -tip perf/probes 04/10] x86: AVX instruction set decoder support Masami Hiramatsu
2009-10-29  8:07   ` [tip:perf/probes] " tip-bot for Masami Hiramatsu
2009-10-27 20:42 ` [PATCH -tip perf/probes 05/10] x86: Add Intel FMA instructions to x86 opcode map Masami Hiramatsu
2009-10-29  8:08   ` [tip:perf/probes] " tip-bot for Masami Hiramatsu
2009-10-27 20:42 ` [PATCH -tip perf/probes 06/10] kprobe-tracer: Compare both of event-name and event-group to find probe Masami Hiramatsu
2009-10-29  8:08   ` [tip:perf/probes] " tip-bot for Masami Hiramatsu
2009-10-27 20:42 ` [PATCH -tip perf/probes 07/10] perf/probes: Exit searching after finding target function Masami Hiramatsu
2009-10-29  8:08   ` [tip:perf/probes] " tip-bot for Masami Hiramatsu
2009-10-27 20:43 ` [PATCH -tip perf/probes 08/10] perf/probes: Change command-line option of perf-probe Masami Hiramatsu
2009-10-29  8:08   ` [tip:perf/probes] perf/probes: Improve " tip-bot for Masami Hiramatsu
2009-10-27 20:43 ` [PATCH -tip perf/probes 09/10] perf/probes: Change probepoint syntax " Masami Hiramatsu
2009-10-29  8:09   ` [tip:perf/probes] perf/probes: Improve probe point " tip-bot for Masami Hiramatsu
2009-10-27 20:43 ` [PATCH -tip perf/probes 10/10] perf/probes: Support function entry relative line number Masami Hiramatsu
2009-10-29  8:09   ` tip-bot for Masami Hiramatsu [this message]
2009-10-29  8:53 ` [PATCH -tip perf/probes 00/10] x86 insn decoder bugfixes Ingo Molnar
2009-10-29 15:10   ` Arnaldo Carvalho de Melo
2009-10-29 16:55   ` Masami Hiramatsu
2009-10-29 20:10     ` Masami Hiramatsu
2009-10-29 20:25       ` Josh Stone
2009-10-29 20:41         ` Masami Hiramatsu
2009-11-02 21:16     ` [PATCH -tip perf/probes 00/10] x86 insn decoder bugfixes and perf-probe syntax changes Masami Hiramatsu
2009-11-02 21:26       ` Frederic Weisbecker
2009-11-02 21:56         ` Masami Hiramatsu
2009-11-03  0:36       ` Masami Hiramatsu
2009-11-03  7:32         ` Ingo Molnar
2009-11-03 15:07           ` Masami Hiramatsu
2009-10-29 17:15   ` [PATCH -tip perf/probes 00/10] x86 insn decoder bugfixes Frank Ch. Eigler
2009-10-29 19:18   ` Roland McGrath
2009-11-03  7:24     ` Ingo Molnar
2009-11-03 12:35       ` Using build-ids in perf tools was " Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-b0ef07324310d66f660a311d4a8d669eda74f801@git.kernel.org \
    --to=mhiramat@redhat.com \
    --cc=ananth@in.ibm.com \
    --cc=fche@redhat.com \
    --cc=fweisbec@gmail.com \
    --cc=hch@infradead.org \
    --cc=hpa@zytor.com \
    --cc=jbaron@redhat.com \
    --cc=jkenisto@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=prasad@linux.vnet.ibm.com \
    --cc=rostedt@goodmis.org \
    --cc=srikar@linux.vnet.ibm.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox