aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRavi Bangoria <[email protected]>2017-10-05 14:42:34 +0530
committerArnaldo Carvalho de Melo <[email protected]>2017-10-05 10:52:54 -0300
commitc1fbc0cf81f1c464f5fda322c1104d4bb1da6711 (patch)
tree06b54ec9f8dee12c4f25efe4306335e9047ebdb9
parent1addcd55bc54d669000221b41e379458ff3e6747 (diff)
perf callchain: Compare dsos (as well) for CCKEY_FUNCTION
Two functions from different binaries can have same start address. Thus, comparing only start address in match_chain() leads to inconsistent callchains. Fix this by adding a check for dsos as well. Ex, https://www.spinics.net/lists/linux-perf-users/msg04067.html Reported-by: Alexander Pozdneev <[email protected]> Signed-off-by: Ravi Bangoria <[email protected]> Acked-by: Jiri Olsa <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Krister Johansen <[email protected]> Cc: Milian Wolff <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Yao Jin <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
-rw-r--r--tools/perf/util/callchain.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index be09d77cade0..a971caf3759d 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -685,6 +685,8 @@ static enum match_result match_chain(struct callchain_cursor_node *node,
{
struct symbol *sym = node->sym;
u64 left, right;
+ struct dso *left_dso = NULL;
+ struct dso *right_dso = NULL;
if (callchain_param.key == CCKEY_SRCLINE) {
enum match_result match = match_chain_srcline(node, cnode);
@@ -696,12 +698,14 @@ static enum match_result match_chain(struct callchain_cursor_node *node,
if (cnode->ms.sym && sym && callchain_param.key == CCKEY_FUNCTION) {
left = cnode->ms.sym->start;
right = sym->start;
+ left_dso = cnode->ms.map->dso;
+ right_dso = node->map->dso;
} else {
left = cnode->ip;
right = node->ip;
}
- if (left == right) {
+ if (left == right && left_dso == right_dso) {
if (node->branch) {
cnode->branch_count++;