From nobody Wed Nov 27 04:55:39 2024 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3D2CC195809; Sat, 12 Oct 2024 14:15:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728742508; cv=none; b=FfmV1l9UqUX7/aI8jOLMRZFhMZVT4nFWJ91abQo6pAwr716Ixg+Ocv5+8WwwoaUvxuoiIzlKS0PkEf62xwiKb/twQear6m9tdcnWFCFaYadcjCWxqIQb+R7zydOwuHO3EMpjVQemvRYpuihdwcc3KG8V1e0LCglw+YjZZvxbMEY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728742508; c=relaxed/simple; bh=CJkF3zBomhtzLlCt1D+413uZmOsbuYAGu4PXv44SuGE=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=VLrZ2dLsuw8JREb0evsL+8hH3TL27NxRC9eRWhnZnqJK5evzpplJO5/ecfAyAc8doc+HMmsQSUaNatMoTD4v+XF1IIavmtq8wyLdjxTO8wYsaqSmR0a6GWsFJVq1Bu159OcA3YPn0/lKoHfetLKLzbRTHvv2PyVXwzIkuf1G3vc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E4268DA7; Sat, 12 Oct 2024 07:15:28 -0700 (PDT) Received: from e132581.cambridge.arm.com (e132581.arm.com [10.2.76.71]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8BD453F71E; Sat, 12 Oct 2024 07:14:57 -0700 (PDT) From: Leo Yan To: Arnaldo Carvalho de Melo , Masami Hiramatsu , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Leo Yan Subject: [PATCH] perf probe: Correct demangled symbols in C++ program Date: Sat, 12 Oct 2024 15:14:32 +0100 Message-Id: <20241012141432.877894-1-leo.yan@arm.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" An issue can be observed when probe C++ demangled symbol with steps: # nm test_cpp_mangle | grep print_data 0000000000000c94 t _GLOBAL__sub_I__Z10print_datai 0000000000000afc T _Z10print_datai 0000000000000b38 T _Z10print_dataR5Point # perf probe -x /home/niayan01/test_cpp_mangle -F --demangle ... print_data(Point&) print_data(int) ... # perf --debug verbose=3D3 probe -x test_cpp_mangle --add "test=3Dprint_d= ata(int)" probe-definition(0): test=3Dprint_data(int) symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null) 0 arguments Open Debuginfo file: /home/niayan01/test_cpp_mangle Try to find probe point from debuginfo. Symbol print_data(int) address found : afc Matched function: print_data [2ccf] Probe point found: print_data+0 Found 1 probe_trace_events. Opening /sys/kernel/tracing//uprobe_events write=3D1 Opening /sys/kernel/tracing//README write=3D0 Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_man= gle:0xb38 ... When tried to probe symbol "print_data(int)", the log shows: Symbol print_data(int) address found : afc The found address is 0xafc - which is right with verifying the output result from nm. Afterwards when write event, the command uses offset 0xb38 in the last log, which is a wrong address. The dwarf_diename() gets a common function name, in above case, it returns string "print_data". As a result, the tool parses the offset based on the common name. This leads to probe at the wrong symbol "print_data(Point&)". To fix the issue, use the die_get_linkage_name() function to retrieve the distinct linkage name - this is the mangled name for the C++ case. Based on this unique name, the tool can get a correct offset for probing. Based on DWARF doc, it is possible the linkage name is missed in the DIE, it rolls back to use dwarf_diename(). After: # perf --debug verbose=3D3 probe -x test_cpp_mangle --add "test=3Dprint_d= ata(int)" probe-definition(0): test=3Dprint_data(int) symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null) 0 arguments Open Debuginfo file: /home/niayan01/test_cpp_mangle Try to find probe point from debuginfo. Symbol print_data(int) address found : afc Matched function: print_data [2d06] Probe point found: print_data+0 Found 1 probe_trace_events. Opening /sys/kernel/tracing//uprobe_events write=3D1 Opening /sys/kernel/tracing//README write=3D0 Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_man= gle:0xafc Added new event: probe_test_cpp_mangle:test (on print_data(int) in /home/niayan01/test= _cpp_mangle) You can now use it in all perf tools, such as: perf record -e probe_test_cpp_mangle:test -aR sleep 1 # perf --debug verbose=3D3 probe -x test_cpp_mangle --add "test2=3Dprint_= data(Point&)" probe-definition(0): test2=3Dprint_data(Point&) symbol:print_data(Point&) file:(null) line:0 offset:0 return:0 lazy:(nu= ll) 0 arguments Open Debuginfo file: /home/niayan01/test_cpp_mangle Try to find probe point from debuginfo. Symbol print_data(Point&) address found : b38 Matched function: print_data [2ccf] Probe point found: print_data+0 Found 1 probe_trace_events. Opening /sys/kernel/tracing//uprobe_events write=3D1 Parsing probe_events: p:probe_test_cpp_mangle/test /home/niayan01/test_= cpp_mangle:0x0000000000000afc Group:probe_test_cpp_mangle Event:test probe:p Opening /sys/kernel/tracing//README write=3D0 Writing event: p:probe_test_cpp_mangle/test2 /home/niayan01/test_cpp_ma= ngle:0xb38 Added new event: probe_test_cpp_mangle:test2 (on print_data(Point&) in /home/niayan01/= test_cpp_mangle) You can now use it in all perf tools, such as: perf record -e probe_test_cpp_mangle:test2 -aR sleep 1 Fixes: fb1587d869a3 ("perf probe: List probes with line number and file nam= e") Signed-off-by: Leo Yan Acked-by: Masami Hiramatsu (Google) --- tools/perf/util/probe-finder.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 630e16c54ed5..498ccfb0be6f 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1583,8 +1583,21 @@ int debuginfo__find_probe_point(struct debuginfo *db= g, u64 addr, =20 /* Find a corresponding function (name, baseline and baseaddr) */ if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { - /* Get function entry information */ - func =3D basefunc =3D dwarf_diename(&spdie); + /* + * Get function entry information. + * + * As described in the document DWARF Debugging Information + * Format Version 5, section 2.22 Linkage Names, "mangled names, + * are used in various ways, ... to distinguish multiple + * entities that have the same name". + * + * Firstly try to get distinct linkage name, if fail then + * rollback to get associated name in DIE. + */ + func =3D basefunc =3D die_get_linkage_name(&spdie); + if (!func) + func =3D basefunc =3D dwarf_diename(&spdie); + if (!func || die_entrypc(&spdie, &baseaddr) !=3D 0 || dwarf_decl_line(&spdie, &baseline) !=3D 0) { --=20 2.25.1