From nobody Sun Nov 24 16:00:14 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D5241C07CF; Mon, 4 Nov 2024 16:17:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730737042; cv=none; b=btsFOjvUfsPtHGiES6RTZBtC8UvRqsv22Ua+VgAESjw7lqo2TbWT5g6jEZid7IYSY3Gfvzx9jdA+rrG1P0EIkqt+GIpk6d26oUu8hPwgnwrh67gNJXx4LCooLQ8EJYjKG9BmpF3wcUPM0ueAsuZmSOvaUkRsBRHaD8YGgsonTxY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730737042; c=relaxed/simple; bh=eb4OfohM415xwWSX2GTo7qtBT4UuudlHKe11OO6YLzw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dJhrw5rTYsVapr/XWEAOnijJ2bWOWwn0zdJlpqG1+T9mHsJ2denyXL4R6vBLPGoJqkk/X/KTJ0uyQDgprBmJAlBCQSImZ6mWToNOAqImzzrcsvab4WrBg5fJ54XP2BhcZHbGKRYGCGGP1vFDQjFHZ8wvwHC06l5UIb7TuzR1FDA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ErPOQQuf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ErPOQQuf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D2B08C4CECE; Mon, 4 Nov 2024 16:17:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1730737041; bh=eb4OfohM415xwWSX2GTo7qtBT4UuudlHKe11OO6YLzw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ErPOQQuftN/PNxxttrpC21fgyOuxkFmUo7C8V23N0jTh8XpHeMoGiYdMpdvrJXMSh xKBAXHbnSBHLFDxnVIuU5y1buyAgcRvDPiZBhcN41kkPD3OiR1m90nXPAPygMfli54 qwhaZ2CR7LF43VJLnrlbBr03Yi0575mSkYP7f4laFWHyNeXdI72T7wC0kpLbVckQZ+ 4FydJ+jWY10aV3a8JOKbEcWipgG4A/unAOva63klUpyUPyN08zRmVq3AtxiwCSbEdT B5fJyEmEGO9xyCODginjhReOaw1ZWXRL7NJABa/1oOI6pk9mII3gGHv442cR6L1AqM XgAWaR1CVWr3w== From: "Masami Hiramatsu (Google)" To: Arnaldo Carvalho de Melo , Namhyung Kim Cc: Peter Zijlstra , Ingo Molnar , Masami Hiramatsu , Ian Rogers , Dima Kogan , Alexander Lobakin , Przemek Kitszel , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] perf-probe: Fix to ignore escaped characters in --lines option Date: Tue, 5 Nov 2024 01:17:18 +0900 Message-ID: <173073703801.2098439.2570890674739658493.stgit@mhiramat.roam.corp.google.com> X-Mailer: git-send-email 2.47.0.163.g1226f6d8fa-goog In-Reply-To: <173073702882.2098439.13342508872190995896.stgit@mhiramat.roam.corp.google.com> References: <173073702882.2098439.13342508872190995896.stgit@mhiramat.roam.corp.google.com> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Masami Hiramatsu (Google) Use strbprk_esc() and strdup_esc() to ignore escaped characters in --lines option. This has been done for other options, but only --lines option doesn't. Signed-off-by: Masami Hiramatsu (Google) --- tools/perf/util/probe-event.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a17c9b8a7a79..665dcce482e1 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1355,7 +1355,7 @@ int parse_line_range_desc(const char *arg, struct lin= e_range *lr) lr->start =3D 0; lr->end =3D INT_MAX; =20 - range =3D strchr(name, ':'); + range =3D strpbrk_esc(name, ":"); if (range) { *range++ =3D '\0'; =20 @@ -1396,16 +1396,16 @@ int parse_line_range_desc(const char *arg, struct l= ine_range *lr) } } =20 - file =3D strchr(name, '@'); + file =3D strpbrk_esc(name, "@"); if (file) { *file =3D '\0'; - lr->file =3D strdup(++file); + lr->file =3D strdup_esc(++file); if (lr->file =3D=3D NULL) { err =3D -ENOMEM; goto err; } lr->function =3D name; - } else if (strchr(name, '/') || strchr(name, '.')) + } else if (strpbrk_esc(name, "/.")) lr->file =3D name; else if (is_c_func_name(name))/* We reuse it for checking funcname */ lr->function =3D name; From nobody Sun Nov 24 16:00:14 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E401D1C07CF; Mon, 4 Nov 2024 16:17:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730737051; cv=none; b=I5hcNZpHh5GrkD6qJVQTIprytBWn8BuICO7Kb1gvoqkzksP/hKI4Tq0hHOYQSuchYGJCTqqlH2ZVrrsL5xv0Aoy3J1rnp3JHLS4UC4arEaVdVKRTHPI9+HUm7C0O3PJS1TTgNFdS+n3RyPj/kWg1ieNeeoafF0umArztU8bXyfI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730737051; c=relaxed/simple; bh=t3T04Wte+t+ObVSyXqcE2uwcXfkKIa22kFNTw53IGZ8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Sbu0hZhHaTHD4OWgQQLy+H16Akrhy7QarcltDq6h003AsU/nZokzTuHZaxKYlXeUJE6QpSB+LXefsiohICQAFoeSjAl7UDphBDEMcBGsLb2RCMvAtCwTOGchYEQZ8jr9Q568d34XfcsATx3F7LAY4woLyO/mCexP3bY4Y0humks= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RpHA46wf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RpHA46wf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B6FC3C4CECE; Mon, 4 Nov 2024 16:17:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1730737050; bh=t3T04Wte+t+ObVSyXqcE2uwcXfkKIa22kFNTw53IGZ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RpHA46wfQmfg7GQ7fqpUIldQARXWKLCmWlkovYqeE07kGwgvB9QdhLDjA7Z8GbD0c 48BeUf8UESVlcdYWtFf3klmza2ovzNxGMLTCvCZfb3oXQGybEyQM/KLPXzJ4/vmRML f9ysVSZpZIZv8kLmFKPbeoyAY4cKiHQIJarUJO3TUNivu6BzbfIwZ3iAKOHu9a1JEk 4wT9mFQ0AxJCRP3axJaVQIvSD3H+JPrzPtqi00I4ye/MmQjx6EQjY8im8DIcRAP1f2 7dBx3kgQC+oDAm9m5z3l6YS7K9GLvmmVsJ0JpJPiaNkIsh3h3rx9jJjg7u+g1Z3oz8 sbXG9BXmiu2yw== From: "Masami Hiramatsu (Google)" To: Arnaldo Carvalho de Melo , Namhyung Kim Cc: Peter Zijlstra , Ingo Molnar , Masami Hiramatsu , Ian Rogers , Dima Kogan , Alexander Lobakin , Przemek Kitszel , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] perf-probe: Require '@' prefix for filename always Date: Tue, 5 Nov 2024 01:17:26 +0900 Message-ID: <173073704685.2098439.2208365513857043203.stgit@mhiramat.roam.corp.google.com> X-Mailer: git-send-email 2.47.0.163.g1226f6d8fa-goog In-Reply-To: <173073702882.2098439.13342508872190995896.stgit@mhiramat.roam.corp.google.com> References: <173073702882.2098439.13342508872190995896.stgit@mhiramat.roam.corp.google.com> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Masami Hiramatsu (Google) Currently perf probe allows user to specify probing place without '@' prefix, for example, both `-V file:line` and `-V function:line` are allowed. But this makes a problem if a (demangled) function name is hard to be distinguished from a file name. This changes the perf-probe to require '@' prefix for filename even without function name. For example, `-V @file:line` and `-V function:line` are acceptable. With this change, users can specify filename or function correctly. Signed-off-by: Masami Hiramatsu (Google) --- tools/perf/util/probe-event.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 665dcce482e1..913a27cbb5d9 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1341,7 +1341,7 @@ static bool is_c_func_name(const char *name) * Stuff 'lr' according to the line range described by 'arg'. * The line range syntax is described by: * - * SRC[:SLN[+NUM|-ELN]] + * @SRC[:SLN[+NUM|-ELN]] * FNC[@SRC][:SLN[+NUM|-ELN]] */ int parse_line_range_desc(const char *arg, struct line_range *lr) @@ -1404,16 +1404,10 @@ int parse_line_range_desc(const char *arg, struct l= ine_range *lr) err =3D -ENOMEM; goto err; } + if (*name !=3D '\0') + lr->function =3D name; + } else lr->function =3D name; - } else if (strpbrk_esc(name, "/.")) - lr->file =3D name; - else if (is_c_func_name(name))/* We reuse it for checking funcname */ - lr->function =3D name; - else { /* Invalid name */ - semantic_error("'%s' is not a valid function name.\n", name); - err =3D -EINVAL; - goto err; - } =20 return 0; err: @@ -1463,7 +1457,7 @@ static int parse_perf_probe_point(char *arg, struct p= erf_probe_event *pev) =20 /* * - * perf probe [GRP:][EVENT=3D]SRC[:LN|;PTN] + * perf probe [GRP:][EVENT=3D]@SRC[:LN|;PTN] * perf probe [GRP:][EVENT=3D]FUNC[@SRC][+OFFS|%return|:LN|;PAT] * perf probe %[GRP:]SDT_EVENT */ @@ -1516,19 +1510,12 @@ static int parse_perf_probe_point(char *arg, struct= perf_probe_event *pev) /* * Check arg is function or file name and copy it. * - * We consider arg to be a file spec if and only if it satisfies - * all of the below criteria:: - * - it does not include any of "+@%", - * - it includes one of ":;", and - * - it has a period '.' in the name. - * + * We consider arg to be a file spec if it starts with '@'. * Otherwise, we consider arg to be a function specification. */ - if (!strpbrk_esc(arg, "+@%")) { - ptr =3D strpbrk_esc(arg, ";:"); - /* This is a file spec if it includes a '.' before ; or : */ - if (ptr && memchr(arg, '.', ptr - arg)) - file_spec =3D true; + if (*arg =3D=3D '@') { + file_spec =3D true; + arg++; } =20 ptr =3D strpbrk_esc(arg, ";:+@%"); From nobody Sun Nov 24 16:00:14 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBC8D1BF80C; Mon, 4 Nov 2024 16:17:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730737060; cv=none; b=VEs5Brk/ncB6XLralyZP7WYgI74wlAxu+b19md36/yo3rn2qEmnY4rN8CtIX9y+308yxzbfS466huM1TpILmz4Qde07vMFMezee2wXPxaTR3hxkJ0viezNGzaVFh8bZBk//s+Zm6bUYQda8eg1pm1FN45drQ4g/EzkSK4cElbYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730737060; c=relaxed/simple; bh=6Izm756VW1TxbakOu4qbxSkidS4sK4VxpC1eBAYg/JA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=mXVnHUWwKQTRxmAztcf1kXxqOgHHa8ZWq4to7jkujYQHGQ15o9GK1zm6qYWsVukH3225MkBAloXgEqlEIYpxkF7nk9ibR+ALq7MqpG3thfd9nygsnH1so76l5dt/GC/iWIaHESoEG9+ONBqSWdb0SFFsj6nP/dczT31MuvZgQOg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YD4TzWrD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YD4TzWrD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BCBA1C4CECE; Mon, 4 Nov 2024 16:17:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1730737059; bh=6Izm756VW1TxbakOu4qbxSkidS4sK4VxpC1eBAYg/JA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YD4TzWrD1w7okufgMQlAUyHQqjd08nM7wdMHWoHJ9a6RxG13C8NQ3uIAgg6wftkmG lfQLKdJZFt2KVvCkdbkkE9iZy9lr2GFy8HQnCCikuLC7rfxRsY7cHK0OAX3C5Tof58 453d2PECMVAxuDnjk1RdzX21885odNSDI6pwDecjYITOgxU6Jjkmbu0cKM68Whu2gZ l9DdTYNonboibmqfkudCQtz3/ldRMzCjHhU7c1Z1rpEXAb/W6acp2AN2htLQ48b+Qn NzYlBpA9F7Lm2gm0z9oqeACgu9vnjdjk7dSol68Xj1uhZXNO39QNFBuZX24Y1ZFUe3 PTdGUb/jSpo7g== From: "Masami Hiramatsu (Google)" To: Arnaldo Carvalho de Melo , Namhyung Kim Cc: Peter Zijlstra , Ingo Molnar , Masami Hiramatsu , Ian Rogers , Dima Kogan , Alexander Lobakin , Przemek Kitszel , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/4] perf-probe: Introduce quotation marks support Date: Tue, 5 Nov 2024 01:17:35 +0900 Message-ID: <173073705572.2098439.4076465830484831945.stgit@mhiramat.roam.corp.google.com> X-Mailer: git-send-email 2.47.0.163.g1226f6d8fa-goog In-Reply-To: <173073702882.2098439.13342508872190995896.stgit@mhiramat.roam.corp.google.com> References: <173073702882.2098439.13342508872190995896.stgit@mhiramat.roam.corp.google.com> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Masami Hiramatsu (Google) In non-C languages, it is possible to have ':' in the function names. It is possible to escape it with backslashes, but if there are too many backslashes, it is annoying. This introduce quotation marks (`"` or `'`) support. For example, without quotes, we have to pass it as below $ perf probe -x cro3 -L "cro3\:\:cmd\:\:servo\:\:run_show" 0 fn run_show(args: &ArgsShow) -> Result<()> { 1 let list =3D ServoList::discover()?; 2 let s =3D list.find_by_serial(&args.servo)?; 3 if args.json { 4 println!("{s}"); With quotes, we can more naturally write the function name as below; $ ./perf probe -x cro3 -L \"cro3::cmd::servo::run_show\" 0 fn run_show(args: &ArgsShow) -> Result<()> { 1 let list =3D ServoList::discover()?; 2 let s =3D list.find_by_serial(&args.servo)?; 3 if args.json { 4 println!("{s}"); Signed-off-by: Masami Hiramatsu (Google) --- tools/perf/util/probe-event.c | 76 ++++++++++++++++-------------- tools/perf/util/probe-finder.c | 3 + tools/perf/util/string.c | 100 ++++++++++++++++++++++++++++++++++++= ++++ tools/perf/util/string2.h | 2 + 4 files changed, 145 insertions(+), 36 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 913a27cbb5d9..bcba8273204d 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1065,6 +1065,7 @@ static int __show_line_range(struct line_range *lr, c= onst char *module, =20 ret =3D debuginfo__find_line_range(dinfo, lr); if (!ret) { /* Not found, retry with an alternative */ + pr_debug2("Failed to find line range in debuginfo. Fallback to alternati= ve\n"); ret =3D get_alternative_line_range(dinfo, lr, module, user); if (!ret) ret =3D debuginfo__find_line_range(dinfo, lr); @@ -1078,7 +1079,7 @@ static int __show_line_range(struct line_range *lr, c= onst char *module, pr_warning("Specified source line is not found.\n"); return -ENOENT; } else if (ret < 0) { - pr_warning("Debuginfo analysis failed.\n"); + pr_warning("Debuginfo analysis failed (%d).\n", ret); return ret; } =20 @@ -1187,7 +1188,7 @@ static int show_available_vars_at(struct debuginfo *d= info, pr_err("Failed to find the address of %s\n", buf); ret =3D -ENOENT; } else - pr_warning("Debuginfo analysis failed.\n"); + pr_warning("Debuginfo analysis failed(2).\n"); goto end; } =20 @@ -1343,30 +1344,39 @@ static bool is_c_func_name(const char *name) * * @SRC[:SLN[+NUM|-ELN]] * FNC[@SRC][:SLN[+NUM|-ELN]] + * + * SRC and FUNC can be quoted by double/single quotes. */ int parse_line_range_desc(const char *arg, struct line_range *lr) { - char *range, *file, *name =3D strdup(arg); + char *buf =3D strdup(arg); + char *p; int err; =20 - if (!name) + if (!buf) return -ENOMEM; =20 lr->start =3D 0; lr->end =3D INT_MAX; =20 - range =3D strpbrk_esc(name, ":"); - if (range) { - *range++ =3D '\0'; + pr_debug2("Input line range: %s\n", buf); + p =3D strpbrk_esq(buf, ":"); + if (p) { + if (p =3D=3D buf) { + semantic_error("No file/function name in '%s'.\n", p); + err =3D -EINVAL; + goto err; + } + *(p++) =3D '\0'; =20 - err =3D parse_line_num(&range, &lr->start, "start line"); + err =3D parse_line_num(&p, &lr->start, "start line"); if (err) goto err; =20 - if (*range =3D=3D '+' || *range =3D=3D '-') { - const char c =3D *range++; + if (*p =3D=3D '+' || *p =3D=3D '-') { + const char c =3D *(p++); =20 - err =3D parse_line_num(&range, &lr->end, "end line"); + err =3D parse_line_num(&p, &lr->end, "end line"); if (err) goto err; =20 @@ -1390,28 +1400,22 @@ int parse_line_range_desc(const char *arg, struct l= ine_range *lr) " than end line.\n"); goto err; } - if (*range !=3D '\0') { - semantic_error("Tailing with invalid str '%s'.\n", range); + if (*p !=3D '\0') { + semantic_error("Tailing with invalid str '%s'.\n", p); goto err; } } =20 - file =3D strpbrk_esc(name, "@"); - if (file) { - *file =3D '\0'; - lr->file =3D strdup_esc(++file); - if (lr->file =3D=3D NULL) { - err =3D -ENOMEM; - goto err; - } - if (*name !=3D '\0') - lr->function =3D name; - } else - lr->function =3D name; + p =3D strpbrk_esq(buf, "@"); + if (p) { + *(p++) =3D '\0'; + lr->file =3D strdup_esq(p); + } + lr->function =3D strdup_esq(buf); + err =3D 0; =20 - return 0; err: - free(name); + free(buf); return err; } =20 @@ -1419,19 +1423,19 @@ static int parse_perf_probe_event_name(char **arg, = struct perf_probe_event *pev) { char *ptr; =20 - ptr =3D strpbrk_esc(*arg, ":"); + ptr =3D strpbrk_esq(*arg, ":"); if (ptr) { *ptr =3D '\0'; if (!pev->sdt && !is_c_func_name(*arg)) goto ng_name; - pev->group =3D strdup_esc(*arg); + pev->group =3D strdup_esq(*arg); if (!pev->group) return -ENOMEM; *arg =3D ptr + 1; } else pev->group =3D NULL; =20 - pev->event =3D strdup_esc(*arg); + pev->event =3D strdup_esq(*arg); if (pev->event =3D=3D NULL) return -ENOMEM; =20 @@ -1470,7 +1474,7 @@ static int parse_perf_probe_point(char *arg, struct p= erf_probe_event *pev) arg++; } =20 - ptr =3D strpbrk_esc(arg, ";=3D@+%"); + ptr =3D strpbrk_esq(arg, ";=3D@+%"); if (pev->sdt) { if (ptr) { if (*ptr !=3D '@') { @@ -1484,7 +1488,7 @@ static int parse_perf_probe_point(char *arg, struct p= erf_probe_event *pev) pev->target =3D build_id_cache__origname(tmp); free(tmp); } else - pev->target =3D strdup_esc(ptr + 1); + pev->target =3D strdup_esq(ptr + 1); if (!pev->target) return -ENOMEM; *ptr =3D '\0'; @@ -1518,7 +1522,7 @@ static int parse_perf_probe_point(char *arg, struct p= erf_probe_event *pev) arg++; } =20 - ptr =3D strpbrk_esc(arg, ";:+@%"); + ptr =3D strpbrk_esq(arg, ";:+@%"); if (ptr) { nc =3D *ptr; *ptr++ =3D '\0'; @@ -1527,7 +1531,7 @@ static int parse_perf_probe_point(char *arg, struct p= erf_probe_event *pev) if (arg[0] =3D=3D '\0') tmp =3D NULL; else { - tmp =3D strdup_esc(arg); + tmp =3D strdup_esq(arg); if (tmp =3D=3D NULL) return -ENOMEM; } @@ -1565,7 +1569,7 @@ static int parse_perf_probe_point(char *arg, struct p= erf_probe_event *pev) return -ENOMEM; break; } - ptr =3D strpbrk_esc(arg, ";:+@%"); + ptr =3D strpbrk_esq(arg, ";:+@%"); if (ptr) { nc =3D *ptr; *ptr++ =3D '\0'; @@ -1592,7 +1596,7 @@ static int parse_perf_probe_point(char *arg, struct p= erf_probe_event *pev) semantic_error("SRC@SRC is not allowed.\n"); return -EINVAL; } - pp->file =3D strdup_esc(arg); + pp->file =3D strdup_esq(arg); if (pp->file =3D=3D NULL) return -ENOMEM; break; diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 630e16c54ed5..5462b5541a6d 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1796,6 +1796,7 @@ int debuginfo__find_line_range(struct debuginfo *dbg,= struct line_range *lr) struct dwarf_callback_param line_range_param =3D { .data =3D (void *)&lf, .retval =3D 0}; =20 + pr_debug2("Start searching function '%s' in getpubname\n", lr->function); dwarf_getpubnames(dbg->dbg, pubname_search_cb, &pubname_param, 0); if (pubname_param.found) { @@ -1803,8 +1804,10 @@ int debuginfo__find_line_range(struct debuginfo *dbg= , struct line_range *lr) if (lf.found) goto found; } + pr_debug2("Not found, use DIE tree\n"); } =20 + pr_debug2("Search function '%s' in DIE tree\n", lr->function); /* Loop on CUs (Compilation Unit) */ while (!lf.found && ret >=3D 0) { if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 116a642ad99d..308fc7ec88cc 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -263,6 +263,34 @@ char *strpbrk_esc(char *str, const char *stopset) return ptr; } =20 +/* Like strpbrk_esc(), but not break if it is quoted with single/double qu= otes */ +char *strpbrk_esq(char *str, const char *stopset) +{ + char *_stopset =3D NULL; + char *ptr; + const char *squote =3D "'"; + const char *dquote =3D "\""; + + if (asprintf(&_stopset, "%s%c%c", stopset, *squote, *dquote) < 0) + return NULL; + + do { + ptr =3D strpbrk_esc(str, _stopset); + if (!ptr) + break; + if (*ptr =3D=3D *squote) + ptr =3D strpbrk_esc(ptr + 1, squote); + else if (*ptr =3D=3D *dquote) + ptr =3D strpbrk_esc(ptr + 1, dquote); + else + break; + str =3D ptr + 1; + } while (ptr); + + free(_stopset); + return ptr; +} + /* Like strdup, but do not copy a single backslash */ char *strdup_esc(const char *str) { @@ -293,6 +321,78 @@ char *strdup_esc(const char *str) return ret; } =20 +/* Remove backslash right before quote and return next quote address. */ +static char *remove_consumed_esc(char *str, int len, int quote) +{ + char *ptr =3D str, *end =3D str + len; + + while (*ptr !=3D quote && ptr < end) { + if (*ptr =3D=3D '\\' && *(ptr + 1) =3D=3D quote) { + memmove(ptr, ptr + 1, end - (ptr + 1)); + /* now *ptr is `quote`. */ + end--; + } + ptr++; + } + + return *ptr =3D=3D quote ? ptr : NULL; +} + +/* + * Like strdup_esc, but keep quoted string as it is (and single backslash + * before quote is removed). If there is no closed quote, return NULL. + */ +char *strdup_esq(const char *str) +{ + char *d, *ret; + + /* If there is no quote, return normal strdup_esc() */ + d =3D strpbrk_esc((char *)str, "\"'"); + if (!d) + return strdup_esc(str); + + ret =3D strdup(str); + if (!ret) + return NULL; + + d =3D ret; + do { + d =3D strpbrk(d, "\\\"\'"); + if (!d) + break; + + if (*d =3D=3D '"' || *d =3D=3D '\'') { + /* This is non-escaped quote */ + int quote =3D *d; + int len =3D strlen(d + 1) + 1; + + /* + * Remove the start quote and remove consumed escape (backslash + * before quote) and remove the end quote. If there is no end + * quote, it is the input error. + */ + memmove(d, d + 1, len); + d =3D remove_consumed_esc(d, len, quote); + if (!d) + goto error; + memmove(d, d + 1, strlen(d + 1) + 1); + } + if (*d =3D=3D '\\') { + memmove(d, d + 1, strlen(d + 1) + 1); + if (*d =3D=3D '\\') { + /* double backslash -- keep the second one. */ + d++; + } + } + } while (*d !=3D '\0'); + + return ret; + +error: + free(ret); + return NULL; +} + unsigned int hex(char c) { if (c >=3D '0' && c <=3D '9') diff --git a/tools/perf/util/string2.h b/tools/perf/util/string2.h index 52cb8ba057c7..4c8bff47cfd3 100644 --- a/tools/perf/util/string2.h +++ b/tools/perf/util/string2.h @@ -37,6 +37,8 @@ char *asprintf__tp_filter_pids(size_t npids, pid_t *pids); =20 char *strpbrk_esc(char *str, const char *stopset); char *strdup_esc(const char *str); +char *strpbrk_esq(char *str, const char *stopset); +char *strdup_esq(const char *str); =20 unsigned int hex(char c); char *strreplace_chars(char needle, const char *haystack, const char *repl= ace); From nobody Sun Nov 24 16:00:14 2024 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 073461C0DF3; Mon, 4 Nov 2024 16:17:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730737069; cv=none; b=tBoJSjs/WNff5UGKk0Qe1esMNYGQJTAzGMJzcdg6zCIX+SCDksILk9zrvLL6ecO6hejpuwYuyLG9hutRQGHKwFC9SwnTBLcqHiA0Aladejcs4XFoOr1jokyjDpPUhD5hHlY6lA5b4vpKG5JZDzl+uVT4B2/UF+lB4TqZYL+ySys= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730737069; c=relaxed/simple; bh=s0rFQsc8Fk5VmusC9Ynn6fQiZSmTBCPyClyZxGlMnzY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tswkbrrHlznd0rTpVzU6v25fWNDOKp2i862BUuBX/vKLtMJ8yk/GNByOhLqWWlD54F4alYsrnl2pxrlbBIc+BCUp7CTHVbw5jgPYY0YPjh85k4+cQVgPTr3B0BbMUVrA2ZFB8SyEDBv3dsSndGqDXETtS77ofzWFOWfmU8RrVLo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XEynCGUn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XEynCGUn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E06D1C4CED2; Mon, 4 Nov 2024 16:17:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1730737068; bh=s0rFQsc8Fk5VmusC9Ynn6fQiZSmTBCPyClyZxGlMnzY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XEynCGUnA4Y/vTns4NqC81E4gprYs/74nrDaG1zbUwn4nKGqhWFrpl35jg3IAs3pR nLoVg0vSqWwo7utrDHrkwiTfkH1rwhvcVhTvk9+hD2QAxPxVKobpqUxA1PGRp5LZZL oHzaNeIFy+4AeZfRLFYruSORzQhLWjuw23lsjBQSk5UrlB7C/FjsWK0Gmmna1qNQQC GhLG8uQafukfasJ5nY+2mO0polTH4olOliT3Yg1apI2BoBOdLENcCcXzXLKLNZ26lR w9qa7aC1NKoSIFzRANnHQIPsPpa4jsgbonChQiYJEbpVpKseH8brPkqLlJkdxliPzr g0A3jv3ZgzVsg== From: "Masami Hiramatsu (Google)" To: Arnaldo Carvalho de Melo , Namhyung Kim Cc: Peter Zijlstra , Ingo Molnar , Masami Hiramatsu , Ian Rogers , Dima Kogan , Alexander Lobakin , Przemek Kitszel , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] perf-probe: Replace unacceptable characters when generating event name Date: Tue, 5 Nov 2024 01:17:44 +0900 Message-ID: <173073706473.2098439.14379969075482451249.stgit@mhiramat.roam.corp.google.com> X-Mailer: git-send-email 2.47.0.163.g1226f6d8fa-goog In-Reply-To: <173073702882.2098439.13342508872190995896.stgit@mhiramat.roam.corp.google.com> References: <173073702882.2098439.13342508872190995896.stgit@mhiramat.roam.corp.google.com> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Masami Hiramatsu (Google) Replace unacceptable characters with '_' when generating event name from the probing function name. This is not for C program. For the C program, it will continue to remove suffixes. For example. $ ./perf probe -x cro3 -D \"cro3::cmd::servo::run_show\" p:probe_cro3/cro3_cmd_servo_run_show /work/cro3/target/x86_64-unknown-linux= -gnu/debug/cro3:0x197530 $ ./perf probe -x /work/go/example/outyet/main -D 'main.(*Server).poll' p:probe_main/main_Server_poll /work/go/example/outyet/main:0x353040 Signed-off-by: Masami Hiramatsu (Google) --- tools/perf/util/probe-event.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index bcba8273204d..27698b9a8c95 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2729,7 +2729,7 @@ int show_perf_probe_events(struct strfilter *filter) =20 static int get_new_event_name(char *buf, size_t len, const char *base, struct strlist *namelist, bool ret_event, - bool allow_suffix) + bool allow_suffix, bool is_C_symname) { int i, ret; char *p, *nbase; @@ -2740,10 +2740,24 @@ static int get_new_event_name(char *buf, size_t len= , const char *base, if (!nbase) return -ENOMEM; =20 - /* Cut off the dot suffixes (e.g. .const, .isra) and version suffixes */ - p =3D strpbrk(nbase, ".@"); - if (p && p !=3D nbase) - *p =3D '\0'; + if (is_C_symname) { + /* Cut off the dot suffixes (e.g. .const, .isra) and version suffixes */ + p =3D strpbrk(nbase, ".@"); + if (p && p !=3D nbase) + *p =3D '\0'; + } else { + /* Replace non-alnum with '_' */ + char *s, *d; + + s =3D d =3D nbase; + do { + if (*s && !isalnum(*s)) { + if (d !=3D nbase && *(d - 1) !=3D '_') + *d++ =3D '_'; + } else + *d++ =3D *s; + } while (*s++); + } =20 /* Try no suffix number */ ret =3D e_snprintf(buf, len, "%s%s", nbase, ret_event ? "__return" : ""); @@ -2832,6 +2846,7 @@ static int probe_trace_event__set_name(struct probe_t= race_event *tev, bool allow_suffix) { const char *event, *group; + bool is_C_symname =3D false; char buf[64]; int ret; =20 @@ -2846,8 +2861,16 @@ static int probe_trace_event__set_name(struct probe_= trace_event *tev, (strncmp(pev->point.function, "0x", 2) !=3D 0) && !strisglob(pev->point.function)) event =3D pev->point.function; - else + else { event =3D tev->point.realname; + /* + * `realname` comes from real symbol, which can have a suffix. + * However, if we see some glab-like wildcard in the symbol, it + * might not be a C program. + */ + if (!strisglob(event)) + is_C_symname =3D true; + } } if (pev->group && !pev->sdt) group =3D pev->group; @@ -2858,7 +2881,7 @@ static int probe_trace_event__set_name(struct probe_t= race_event *tev, =20 /* Get an unused new event name */ ret =3D get_new_event_name(buf, sizeof(buf), event, namelist, - tev->point.retprobe, allow_suffix); + tev->point.retprobe, allow_suffix, is_C_symname); if (ret < 0) return ret;