[PATCH 3/4] perf list: Don't write to const memory

Arnaldo Carvalho de Melo posted 4 patches 2 weeks, 3 days ago
[PATCH 3/4] perf list: Don't write to const memory
Posted by Arnaldo Carvalho de Melo 2 weeks, 3 days ago
From: Arnaldo Carvalho de Melo <acme@redhat.com>

Something now detected on fedora 44, where strchr() returns const if it
is passed a const pointer:

  util/print-events.c: In function 'print_sdt_events':
  util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
     89 |                 char *bid = strchr(sdt_name->s, '@');
        |                             ^~~~~~

Fix it by using strnchr() if strchr finds the separator instead of
temporarily scrubbing it with '\0'.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/print-events.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
index 8f3ed83853a9e468..898cf426509790cd 100644
--- a/tools/perf/util/print-events.c
+++ b/tools/perf/util/print-events.c
@@ -97,14 +97,11 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
 		} else {
 			next_sdt_name = strlist__next(sdt_name);
 			if (next_sdt_name) {
-				char *bid2 = strchr(next_sdt_name->s, '@');
-
-				if (bid2)
-					*bid2 = '\0';
-				if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
-					show_detail = true;
-				if (bid2)
-					*bid2 = '@';
+				const char *bid2 = strchr(next_sdt_name->s, '@');
+
+				show_detail = bid2 ?
+						strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0 :
+						strcmp(sdt_name->s, next_sdt_name->s) == 0;
 			}
 		}
 		last_sdt_name = sdt_name->s;
-- 
2.52.0
Re: [PATCH 3/4] perf list: Don't write to const memory
Posted by David Laight 2 weeks, 2 days ago
On Tue, 20 Jan 2026 19:08:59 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> From: Arnaldo Carvalho de Melo <acme@redhat.com>
> 
> Something now detected on fedora 44, where strchr() returns const if it
> is passed a const pointer:
> 
>   util/print-events.c: In function 'print_sdt_events':
>   util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
>      89 |                 char *bid = strchr(sdt_name->s, '@');
>         |                             ^~~~~~
> 
> Fix it by using strnchr() if strchr finds the separator instead of
> temporarily scrubbing it with '\0'.

I've just looked at the full function to see WTF it is doing.
You've fixed the second strchr() not the one the compiler bleated about.
Line 89 is followed by:
	if (bid)
		*bid++ = 0;
but if it is NULL there is a fair chance the code will just explode a bit later on.
I suspect it is an error if the strings aren't "name@bar"

'show_detail' seems to be set if either the previous or next entries in the
list/tree have the same "name" - which seems strange to me.

The while thing needs more work :-(

	David

> 
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
>  tools/perf/util/print-events.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> index 8f3ed83853a9e468..898cf426509790cd 100644
> --- a/tools/perf/util/print-events.c
> +++ b/tools/perf/util/print-events.c
> @@ -97,14 +97,11 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
>  		} else {
>  			next_sdt_name = strlist__next(sdt_name);
>  			if (next_sdt_name) {
> -				char *bid2 = strchr(next_sdt_name->s, '@');
> -
> -				if (bid2)
> -					*bid2 = '\0';
> -				if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
> -					show_detail = true;
> -				if (bid2)
> -					*bid2 = '@';
> +				const char *bid2 = strchr(next_sdt_name->s, '@');
> +
> +				show_detail = bid2 ?
> +						strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0 :
> +						strcmp(sdt_name->s, next_sdt_name->s) == 0;
>  			}
>  		}
>  		last_sdt_name = sdt_name->s;
Re: [PATCH 3/4] perf list: Don't write to const memory
Posted by Arnaldo Carvalho de Melo 2 weeks, 2 days ago
On Wed, Jan 21, 2026 at 10:17:13PM +0000, David Laight wrote:
> On Tue, 20 Jan 2026 19:08:59 -0300
> Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> 
> > From: Arnaldo Carvalho de Melo <acme@redhat.com>
> > 
> > Something now detected on fedora 44, where strchr() returns const if it
> > is passed a const pointer:
> > 
> >   util/print-events.c: In function 'print_sdt_events':
> >   util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
> >      89 |                 char *bid = strchr(sdt_name->s, '@');
> >         |                             ^~~~~~
> > 
> > Fix it by using strnchr() if strchr finds the separator instead of
> > temporarily scrubbing it with '\0'.
> 
> I've just looked at the full function to see WTF it is doing.
> You've fixed the second strchr() not the one the compiler bleated about.

It complained about both, no?

> Line 89 is followed by:
> 	if (bid)
> 		*bid++ = 0;
> but if it is NULL there is a fair chance the code will just explode a bit later on.

Why, can you elaborate?

> I suspect it is an error if the strings aren't "name@bar"
 
> 'show_detail' seems to be set if either the previous or next entries in the
> list/tree have the same "name" - which seems strange to me.

All this is strange, a corner case, it looks as if we may have multiple
binaries, differentiated by buildids, that would have different SDTs.

The code seems to be trying to reduce the amount of info (not showing
the buildid if there are no more at that point multiple versions of a
DSO with SDTs in place).

Further analysis of the changesets that put all this in place is needed
to clarify, but looking just at fixing what the compiler is complaining,
do you think the patches are bad?

- Arnaldo
 
> The while thing needs more work :-(
> 
> 	David
> 
> > 
> > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > ---
> >  tools/perf/util/print-events.c | 13 +++++--------
> >  1 file changed, 5 insertions(+), 8 deletions(-)
> > 
> > diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> > index 8f3ed83853a9e468..898cf426509790cd 100644
> > --- a/tools/perf/util/print-events.c
> > +++ b/tools/perf/util/print-events.c
> > @@ -97,14 +97,11 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
> >  		} else {
> >  			next_sdt_name = strlist__next(sdt_name);
> >  			if (next_sdt_name) {
> > -				char *bid2 = strchr(next_sdt_name->s, '@');
> > -
> > -				if (bid2)
> > -					*bid2 = '\0';
> > -				if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
> > -					show_detail = true;
> > -				if (bid2)
> > -					*bid2 = '@';
> > +				const char *bid2 = strchr(next_sdt_name->s, '@');
> > +
> > +				show_detail = bid2 ?
> > +						strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0 :
> > +						strcmp(sdt_name->s, next_sdt_name->s) == 0;
> >  			}
> >  		}
> >  		last_sdt_name = sdt_name->s;
Re: [PATCH 3/4] perf list: Don't write to const memory
Posted by David Laight 2 weeks, 2 days ago
On Wed, 21 Jan 2026 22:10:18 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> On Wed, Jan 21, 2026 at 10:17:13PM +0000, David Laight wrote:
> > On Tue, 20 Jan 2026 19:08:59 -0300
> > Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> >   
> > > From: Arnaldo Carvalho de Melo <acme@redhat.com>
> > > 
> > > Something now detected on fedora 44, where strchr() returns const if it
> > > is passed a const pointer:
> > > 
> > >   util/print-events.c: In function 'print_sdt_events':
> > >   util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
> > >      89 |                 char *bid = strchr(sdt_name->s, '@');
> > >         |                             ^~~~~~
> > > 
> > > Fix it by using strnchr() if strchr finds the separator instead of
> > > temporarily scrubbing it with '\0'.  
> > 
> > I've just looked at the full function to see WTF it is doing.
> > You've fixed the second strchr() not the one the compiler bleated about.  
> 
> It complained about both, no?
> 
> > Line 89 is followed by:
> > 	if (bid)
> > 		*bid++ = 0;
> > but if it is NULL there is a fair chance the code will just explode a bit later on.  
> 
> Why, can you elaborate?

I don't see why it can't end up in:
		if (show_detail) {
			char *path = build_id_cache__origname(bid);
with 'bid == NULL' and the function just dereferences it.

> 
> > I suspect it is an error if the strings aren't "name@bar"  
>  
> > 'show_detail' seems to be set if either the previous or next entries in the
> > list/tree have the same "name" - which seems strange to me.  
> 
> All this is strange, a corner case, it looks as if we may have multiple
> binaries, differentiated by buildids, that would have different SDTs.
> 
> The code seems to be trying to reduce the amount of info (not showing
> the buildid if there are no more at that point multiple versions of a
> DSO with SDTs in place).
> 
> Further analysis of the changesets that put all this in place is needed
> to clarify, but looking just at fixing what the compiler is complaining,
> do you think the patches are bad?

I didn't see a patch to fix the first one.
But can you just change the structure so that 's' is 'char *'?

	David

> 
> - Arnaldo
>  
> > The while thing needs more work :-(
> > 
> > 	David
> >   
> > > 
> > > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > > ---
> > >  tools/perf/util/print-events.c | 13 +++++--------
> > >  1 file changed, 5 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> > > index 8f3ed83853a9e468..898cf426509790cd 100644
> > > --- a/tools/perf/util/print-events.c
> > > +++ b/tools/perf/util/print-events.c
> > > @@ -97,14 +97,11 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
> > >  		} else {
> > >  			next_sdt_name = strlist__next(sdt_name);
> > >  			if (next_sdt_name) {
> > > -				char *bid2 = strchr(next_sdt_name->s, '@');
> > > -
> > > -				if (bid2)
> > > -					*bid2 = '\0';
> > > -				if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
> > > -					show_detail = true;
> > > -				if (bid2)
> > > -					*bid2 = '@';
> > > +				const char *bid2 = strchr(next_sdt_name->s, '@');
> > > +
> > > +				show_detail = bid2 ?
> > > +						strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0 :
> > > +						strcmp(sdt_name->s, next_sdt_name->s) == 0;
> > >  			}
> > >  		}
> > >  		last_sdt_name = sdt_name->s;
Re: [PATCH 3/4] perf list: Don't write to const memory
Posted by David Laight 2 weeks, 3 days ago
On Tue, 20 Jan 2026 19:08:59 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> From: Arnaldo Carvalho de Melo <acme@redhat.com>
> 
> Something now detected on fedora 44, where strchr() returns const if it
> is passed a const pointer:
> 
>   util/print-events.c: In function 'print_sdt_events':
>   util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
>      89 |                 char *bid = strchr(sdt_name->s, '@');
>         |                             ^~~~~~
> 
> Fix it by using strnchr() if strchr finds the separator instead of
> temporarily scrubbing it with '\0'.
> 
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
>  tools/perf/util/print-events.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> index 8f3ed83853a9e468..898cf426509790cd 100644
> --- a/tools/perf/util/print-events.c
> +++ b/tools/perf/util/print-events.c
> @@ -97,14 +97,11 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
>  		} else {
>  			next_sdt_name = strlist__next(sdt_name);
>  			if (next_sdt_name) {
> -				char *bid2 = strchr(next_sdt_name->s, '@');
> -
> -				if (bid2)
> -					*bid2 = '\0';
> -				if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
> -					show_detail = true;
> -				if (bid2)
> -					*bid2 = '@';
> +				const char *bid2 = strchr(next_sdt_name->s, '@');
> +
> +				show_detail = bid2 ?
> +						strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0 :
> +						strcmp(sdt_name->s, next_sdt_name->s) == 0;

You could use:
	show_detail = strncmp(sdt_name->s, next_sdt_name->s, strcspn(sdt_name->s, "@"));
strcspn() will be slower, but it is succinct.
I'm sure there is a function like strchr() that returns a pointer to the '\0'
when the character isn't found - but I can't remember what it is called :-(

	David

>  			}
>  		}
>  		last_sdt_name = sdt_name->s;
Re: [PATCH 3/4] perf list: Don't write to const memory
Posted by Arnaldo Carvalho de Melo 2 weeks, 2 days ago
On Wed, Jan 21, 2026 at 11:25:36AM +0000, David Laight wrote:
> On Tue, 20 Jan 2026 19:08:59 -0300
> Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> 
> > From: Arnaldo Carvalho de Melo <acme@redhat.com>
> > 
> > Something now detected on fedora 44, where strchr() returns const if it
> > is passed a const pointer:
> > 
> >   util/print-events.c: In function 'print_sdt_events':
> >   util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
> >      89 |                 char *bid = strchr(sdt_name->s, '@');
> >         |                             ^~~~~~
> > 
> > Fix it by using strnchr() if strchr finds the separator instead of
> > temporarily scrubbing it with '\0'.
> > 
> > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > ---
> >  tools/perf/util/print-events.c | 13 +++++--------
> >  1 file changed, 5 insertions(+), 8 deletions(-)
> > 
> > diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> > index 8f3ed83853a9e468..898cf426509790cd 100644
> > --- a/tools/perf/util/print-events.c
> > +++ b/tools/perf/util/print-events.c
> > @@ -97,14 +97,11 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
> >  		} else {
> >  			next_sdt_name = strlist__next(sdt_name);
> >  			if (next_sdt_name) {
> > -				char *bid2 = strchr(next_sdt_name->s, '@');
> > -
> > -				if (bid2)
> > -					*bid2 = '\0';
> > -				if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
> > -					show_detail = true;
> > -				if (bid2)
> > -					*bid2 = '@';
> > +				const char *bid2 = strchr(next_sdt_name->s, '@');
> > +
> > +				show_detail = bid2 ?
> > +						strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0 :
> > +						strcmp(sdt_name->s, next_sdt_name->s) == 0;
> 
> You could use:
> 	show_detail = strncmp(sdt_name->s, next_sdt_name->s, strcspn(sdt_name->s, "@"));
> strcspn() will be slower, but it is succinct.

That works.

> I'm sure there is a function like strchr() that returns a pointer to the '\0'
> when the character isn't found - but I can't remember what it is called :-(

strchrnull()

And this also works and I'll use it:

                                const char *bid2 = strchrnul(next_sdt_name->s, '@');

                                show_detail = strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0;

This way the patch ends up as below, thanks for the suggestion!

Ian, I think I can keep your Reviewed-by, ok?

Cheers,

- Arnaldo

From 02b160f200a2224e8ecf490cf2e316b1a994509a Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Date: Tue, 20 Jan 2026 18:16:09 -0300
Subject: [PATCH 1/1] perf list: Don't write to const memory

Something now detected on fedora 44, where strchr() returns const if it
is passed a const pointer:

  util/print-events.c: In function 'print_sdt_events':
  util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
     89 |                 char *bid = strchr(sdt_name->s, '@');
        |                             ^~~~~~

Fix it by using strncnmp() + strchrnul() instead of temporarily
scrubbing it with '\0'.

Reviewed-by: Ian Rogers <irogers@google.com>
Suggested-by: David Laight <david.laight.linux@gmail.com>
Link: https://lore.kernel.org/r/20260121112536.27fd5d11@pumpkin
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/print-events.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
index 4bbcdbf05b843302..cb27e2898aa0558f 100644
--- a/tools/perf/util/print-events.c
+++ b/tools/perf/util/print-events.c
@@ -97,14 +97,9 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
 		} else {
 			next_sdt_name = strlist__next(sdt_name);
 			if (next_sdt_name) {
-				char *bid2 = strchr(next_sdt_name->s, '@');
-
-				if (bid2)
-					*bid2 = '\0';
-				if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
-					show_detail = true;
-				if (bid2)
-					*bid2 = '@';
+				const char *bid2 = strchrnul(next_sdt_name->s, '@');
+
+				show_detail = strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0;
 			}
 		}
 		last_sdt_name = sdt_name->s;
-- 
2.52.0
Re: [PATCH 3/4] perf list: Don't write to const memory
Posted by Ian Rogers 2 weeks, 2 days ago
On Wed, Jan 21, 2026 at 10:40 AM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> On Wed, Jan 21, 2026 at 11:25:36AM +0000, David Laight wrote:
> > On Tue, 20 Jan 2026 19:08:59 -0300
> > Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> >
> > > From: Arnaldo Carvalho de Melo <acme@redhat.com>
> > >
> > > Something now detected on fedora 44, where strchr() returns const if it
> > > is passed a const pointer:
> > >
> > >   util/print-events.c: In function 'print_sdt_events':
> > >   util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
> > >      89 |                 char *bid = strchr(sdt_name->s, '@');
> > >         |                             ^~~~~~
> > >
> > > Fix it by using strnchr() if strchr finds the separator instead of
> > > temporarily scrubbing it with '\0'.
> > >
> > > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > > ---
> > >  tools/perf/util/print-events.c | 13 +++++--------
> > >  1 file changed, 5 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> > > index 8f3ed83853a9e468..898cf426509790cd 100644
> > > --- a/tools/perf/util/print-events.c
> > > +++ b/tools/perf/util/print-events.c
> > > @@ -97,14 +97,11 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
> > >             } else {
> > >                     next_sdt_name = strlist__next(sdt_name);
> > >                     if (next_sdt_name) {
> > > -                           char *bid2 = strchr(next_sdt_name->s, '@');
> > > -
> > > -                           if (bid2)
> > > -                                   *bid2 = '\0';
> > > -                           if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
> > > -                                   show_detail = true;
> > > -                           if (bid2)
> > > -                                   *bid2 = '@';
> > > +                           const char *bid2 = strchr(next_sdt_name->s, '@');
> > > +
> > > +                           show_detail = bid2 ?
> > > +                                           strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0 :
> > > +                                           strcmp(sdt_name->s, next_sdt_name->s) == 0;
> >
> > You could use:
> >       show_detail = strncmp(sdt_name->s, next_sdt_name->s, strcspn(sdt_name->s, "@"));
> > strcspn() will be slower, but it is succinct.
>
> That works.
>
> > I'm sure there is a function like strchr() that returns a pointer to the '\0'
> > when the character isn't found - but I can't remember what it is called :-(
>
> strchrnull()
>
> And this also works and I'll use it:
>
>                                 const char *bid2 = strchrnul(next_sdt_name->s, '@');
>
>                                 show_detail = strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0;
>
> This way the patch ends up as below, thanks for the suggestion!
>
> Ian, I think I can keep your Reviewed-by, ok?

Yup.

Thanks,
Ian

> Cheers,
>
> - Arnaldo
>
> From 02b160f200a2224e8ecf490cf2e316b1a994509a Mon Sep 17 00:00:00 2001
> From: Arnaldo Carvalho de Melo <acme@redhat.com>
> Date: Tue, 20 Jan 2026 18:16:09 -0300
> Subject: [PATCH 1/1] perf list: Don't write to const memory
>
> Something now detected on fedora 44, where strchr() returns const if it
> is passed a const pointer:
>
>   util/print-events.c: In function 'print_sdt_events':
>   util/print-events.c:89:29: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
>      89 |                 char *bid = strchr(sdt_name->s, '@');
>         |                             ^~~~~~
>
> Fix it by using strncnmp() + strchrnul() instead of temporarily
> scrubbing it with '\0'.
>
> Reviewed-by: Ian Rogers <irogers@google.com>
> Suggested-by: David Laight <david.laight.linux@gmail.com>
> Link: https://lore.kernel.org/r/20260121112536.27fd5d11@pumpkin
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
>  tools/perf/util/print-events.c | 11 +++--------
>  1 file changed, 3 insertions(+), 8 deletions(-)
>
> diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c
> index 4bbcdbf05b843302..cb27e2898aa0558f 100644
> --- a/tools/perf/util/print-events.c
> +++ b/tools/perf/util/print-events.c
> @@ -97,14 +97,9 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)
>                 } else {
>                         next_sdt_name = strlist__next(sdt_name);
>                         if (next_sdt_name) {
> -                               char *bid2 = strchr(next_sdt_name->s, '@');
> -
> -                               if (bid2)
> -                                       *bid2 = '\0';
> -                               if (strcmp(sdt_name->s, next_sdt_name->s) == 0)
> -                                       show_detail = true;
> -                               if (bid2)
> -                                       *bid2 = '@';
> +                               const char *bid2 = strchrnul(next_sdt_name->s, '@');
> +
> +                               show_detail = strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0;
>                         }
>                 }
>                 last_sdt_name = sdt_name->s;
> --
> 2.52.0
>