linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [BUG] libtraceevent: perf script -g python segfaults
@ 2019-10-17 15:42 Arnaldo Carvalho de Melo
  2019-10-17 17:45 ` Steven Rostedt
  2019-10-17 18:38 ` Steven Rostedt
  0 siblings, 2 replies; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-10-17 15:42 UTC (permalink / raw)
  To: Tzvetomir Stoyanov
  Cc: Steven Rostedt, Jiri Olsa, Namhyung Kim, Linux Kernel Mailing List

I'll try and continue later, but if you guys can take a look...

The first call in that loop:

  while ((event = trace_find_next_event(pevent, event)))

works and the event is valid, one of the sched: tracepoints, but then
the next call returns this:

struct tep_event *trace_find_next_event(struct tep_handle *pevent,
                                        struct tep_event *event)
{
        static int idx;
        int events_count;
        struct tep_event *all_events;

        all_events = tep_get_first_event(pevent);
        events_count = tep_get_events_count(pevent);
        if (!pevent || !all_events || events_count < 1)
                return NULL;

        if (!event) {
                idx = 0;
                return all_events;
        }

        if (idx < events_count && event == (all_events + idx)) {
                idx++;
                if (idx == events_count)
                        return NULL;
                return (all_events + idx);
        }

        for (idx = 1; idx < events_count; idx++) {
                if (event == (all_events + (idx - 1)))
                        return (all_events + idx);
        }
        return NULL;
}

Oh, static int idx, oops, anyway, the all_events + idx returned for the
second call to trace_find_next_event() fails, in a hurry now, will get
back to this later.

- Arnaldo


[root@quaco ~]# perf record -e sched:* sleep 1
[ perf record: Woken up 33 times to write data ]
[ perf record: Captured and wrote 0.030 MB perf.data (8 samples) ]
[root@quaco ~]# perf script -g python
Segmentation fault (core dumped)
[root@quaco ~]#

Bisected to:

[acme@quaco perf]$ git bisect bad
bb3dd7e7c4d5e024d607c0ec06c2a2fb9408cc99 is the first bad commit
commit bb3dd7e7c4d5e024d607c0ec06c2a2fb9408cc99
Author: Tzvetomir Stoyanov <tstoyanov@vmware.com>
Date:   Fri Oct 5 12:22:25 2018 -0400

    tools lib traceevent, perf tools: Move struct tep_handler definition in a local header file
    
    As traceevent is going to be transferred into a proper library,
    its local data should be protected from the library users.
    This patch encapsulates struct tep_handler into a local header,
    not visible outside of the library. It implements also a bunch
    of new APIs, which library users can use to access tep_handler members.
    
    Signed-off-by: Tzvetomir Stoyanov <tstoyanov@vmware.com>
    Cc: Jiri Olsa <jolsa@redhat.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: linux trace devel <linux-trace-devel@vger.kernel.org>
    Cc: tzvetomir stoyanov <tstoyanov@vmware.com>
    Link: http://lkml.kernel.org/r/20181005122225.522155df@gandalf.local.home
    Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

:040000 040000 7a23aa486fd8ed255b681e6c959d6ab64d16f2f6 d95f601bb03b81bc04070b69635df40b62c70a1a M	tools
[acme@quaco perf]$

[root@quaco ~]# gdb perf
GNU gdb (GDB) Fedora 8.3-6.fc30
Reading symbols from perf...
(gdb) run script -g python
Starting program: /root/bin/perf script -g python
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[Detaching after fork from child process 10352]

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff76f55e5 in __strlen_avx2 () from /lib64/libc.so.6
Missing separate debuginfos, use: dnf debuginfo-install bzip2-libs-1.0.6-29.fc30.x86_64 elfutils-libelf-0.177-1.fc30.x86_64 elfutils-libs-0.177-1.fc30.x86_64 glib2-2.60.7-1.fc30.x86_64 libbabeltrace-1.5.6-2.fc30.x86_64 libcap-2.26-5.fc30.x86_64 libgcc-9.2.1-1.fc30.x86_64 libunwind-1.3.1-2.fc30.x86_64 libuuid-2.33.2-2.fc30.x86_64 libxcrypt-4.4.10-1.fc30.x86_64 libzstd-1.4.2-1.fc30.x86_64 numactl-libs-2.0.12-2.fc30.x86_64 pcre-8.43-2.fc30.x86_64 perl-libs-5.28.2-440.fc30.x86_64 popt-1.16-17.fc30.x86_64 slang-2.3.2-5.fc30.x86_64 xz-libs-5.2.4-5.fc30.x86_64 zlib-1.2.11-18.fc30.x86_64
(gdb) bt
#0  0x00007ffff76f55e5 in __strlen_avx2 () from /lib64/libc.so.6
#1  0x00007ffff7601a1e in __vfprintf_internal () from /lib64/libc.so.6
#2  0x00007ffff75ec2ba in fprintf () from /lib64/libc.so.6
#3  0x00000000005ec8db in python_generate_script (pevent=0xbedb10, outfile=0x71f761 "perf-script") at util/scripting-engines/trace-event-python.c:1739
#4  0x000000000046e94a in cmd_script (argc=0, argv=0x7fffffffd680) at builtin-script.c:3848
#5  0x00000000004e0d86 in run_builtin (p=0xa3d238 <commands+408>, argc=3, argv=0x7fffffffd680) at perf.c:312
#6  0x00000000004e0ff3 in handle_internal_command (argc=3, argv=0x7fffffffd680) at perf.c:364
#7  0x00000000004e113a in run_argv (argcp=0x7fffffffd4dc, argv=0x7fffffffd4d0) at perf.c:408
#8  0x00000000004e1506 in main (argc=3, argv=0x7fffffffd680) at perf.c:538
(gdb) fr 3
#3  0x00000000005ec8db in python_generate_script (pevent=0xbedb10, outfile=0x71f761 "perf-script") at util/scripting-engines/trace-event-python.c:1739
1739			fprintf(ofp, "def %s__%s(", event->system, event->name);
(gdb) p event
$1 = (struct tep_event *) 0xbfa298
(gdb) p *event
$2 = {tep = 0x31, name = 0x61775f6465686373 <error: Cannot access memory at address 0x61775f6465686373>, id = 1767859563, flags = 1600482404, format = {nr_common = 1752459639, nr_fields = 1601467759, common_fields = 0x6e6f6d6d00697069,
    fields = 0x93b7367616c665f}, print_fmt = {format = 0x21 <error: Cannot access memory at address 0x21>, args = 0x64656e6769736e75}, system = 0x74726f687320 <error: Cannot access memory at address 0x74726f687320>,
  handler = 0x656966090a3b303a, context = 0x51}
(gdb) list -20
1714		fprintf(ofp, "# in the format files.  Those fields not available as "
1715			"handler params can\n");
1716
1717		fprintf(ofp, "# be retrieved using Python functions of the form "
1718			"common_*(context).\n");
1719
1720		fprintf(ofp, "# See the perf-script-python Documentation for the list "
1721			"of available functions.\n\n");
1722
1723		fprintf(ofp, "from __future__ import print_function\n\n");
(gdb)
1724		fprintf(ofp, "import os\n");
1725		fprintf(ofp, "import sys\n\n");
1726
1727		fprintf(ofp, "sys.path.append(os.environ['PERF_EXEC_PATH'] + \\\n");
1728		fprintf(ofp, "\t'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')\n");
1729		fprintf(ofp, "\nfrom perf_trace_context import *\n");
1730		fprintf(ofp, "from Core import *\n\n\n");
1731
1732		fprintf(ofp, "def trace_begin():\n");
1733		fprintf(ofp, "\tprint(\"in trace_begin\")\n\n");
(gdb)
1734
1735		fprintf(ofp, "def trace_end():\n");
1736		fprintf(ofp, "\tprint(\"in trace_end\")\n\n");
1737
1738		while ((event = trace_find_next_event(pevent, event))) {
1739			fprintf(ofp, "def %s__%s(", event->system, event->name);
1740			fprintf(ofp, "event_name, ");
1741			fprintf(ofp, "context, ");
1742			fprintf(ofp, "common_cpu,\n");
1743			fprintf(ofp, "\tcommon_secs, ");


- Arnaldo

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] libtraceevent: perf script -g python segfaults
  2019-10-17 15:42 [BUG] libtraceevent: perf script -g python segfaults Arnaldo Carvalho de Melo
@ 2019-10-17 17:45 ` Steven Rostedt
  2019-10-17 18:38 ` Steven Rostedt
  1 sibling, 0 replies; 10+ messages in thread
From: Steven Rostedt @ 2019-10-17 17:45 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Tzvetomir Stoyanov, Jiri Olsa, Namhyung Kim, Linux Kernel Mailing List

On Thu, 17 Oct 2019 12:42:05 -0300
Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> wrote:

> I'll try and continue later, but if you guys can take a look...
> 
> The first call in that loop:
> 
>   while ((event = trace_find_next_event(pevent, event)))
> 
> works and the event is valid, one of the sched: tracepoints, but then
> the next call returns this:
> 
> struct tep_event *trace_find_next_event(struct tep_handle *pevent,
>                                         struct tep_event *event)
> {
>         static int idx;
>         int events_count;
>         struct tep_event *all_events;
> 
>         all_events = tep_get_first_event(pevent);
>         events_count = tep_get_events_count(pevent);
>         if (!pevent || !all_events || events_count < 1)
>                 return NULL;
> 
>         if (!event) {
>                 idx = 0;
>                 return all_events;
>         }
> 
>         if (idx < events_count && event == (all_events + idx)) {
>                 idx++;
>                 if (idx == events_count)
>                         return NULL;
>                 return (all_events + idx);
>         }
> 
>         for (idx = 1; idx < events_count; idx++) {
>                 if (event == (all_events + (idx - 1)))
>                         return (all_events + idx);
>         }
>         return NULL;
> }
> 
> Oh, static int idx, oops, anyway, the all_events + idx returned for the
> second call to trace_find_next_event() fails, in a hurry now, will get
> back to this later.

Yeah, this is obviously broken. :-( 

I'll have a patch later today.

-- Steve

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] libtraceevent: perf script -g python segfaults
  2019-10-17 15:42 [BUG] libtraceevent: perf script -g python segfaults Arnaldo Carvalho de Melo
  2019-10-17 17:45 ` Steven Rostedt
@ 2019-10-17 18:38 ` Steven Rostedt
  2019-10-17 18:41   ` Steven Rostedt
  1 sibling, 1 reply; 10+ messages in thread
From: Steven Rostedt @ 2019-10-17 18:38 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Tzvetomir Stoyanov, Jiri Olsa, Namhyung Kim, Linux Kernel Mailing List

On Thu, 17 Oct 2019 12:42:05 -0300
Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> wrote:

> I'll try and continue later, but if you guys can take a look...

Does this fix it for you?

-- Steve

diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index ad74be1f0e42..227629796e32 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -193,30 +193,32 @@ int parse_event_file(struct tep_handle *pevent,
 struct tep_event *trace_find_next_event(struct tep_handle *pevent,
 					struct tep_event *event)
 {
+	static struct tep_event **all_events;
 	static int idx;
 	int events_count;
-	struct tep_event *all_events;
 
-	all_events = tep_get_first_event(pevent);
 	events_count = tep_get_events_count(pevent);
 	if (!pevent || !all_events || events_count < 1)
 		return NULL;
 
 	if (!event) {
 		idx = 0;
-		return all_events;
+		all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
+		if (all_events)
+			return all_events[0];
+		return NULL;
 	}
 
-	if (idx < events_count && event == (all_events + idx)) {
+	if (idx < events_count && event == all_events[idx]) {
 		idx++;
 		if (idx == events_count)
 			return NULL;
-		return (all_events + idx);
+		return all_events[idx];
 	}
 
 	for (idx = 1; idx < events_count; idx++) {
-		if (event == (all_events + (idx - 1)))
-			return (all_events + idx);
+		if (event == all_events[idx - 1])
+			return all_events[idx];
 	}
 	return NULL;
 }

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [BUG] libtraceevent: perf script -g python segfaults
  2019-10-17 18:38 ` Steven Rostedt
@ 2019-10-17 18:41   ` Steven Rostedt
  2019-10-17 19:28     ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 10+ messages in thread
From: Steven Rostedt @ 2019-10-17 18:41 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Tzvetomir Stoyanov, Jiri Olsa, Namhyung Kim, Linux Kernel Mailing List

On Thu, 17 Oct 2019 14:38:41 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

>  struct tep_event *trace_find_next_event(struct tep_handle *pevent,
>  					struct tep_event *event)
>  {
> +	static struct tep_event **all_events;
>  	static int idx;
>  	int events_count;
> -	struct tep_event *all_events;

If we are going to use static variables, let's make them all static and
optimize it a little more...

-- Steve

diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index ad74be1f0e42..3f23462517a3 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -193,30 +193,35 @@ int parse_event_file(struct tep_handle *pevent,
 struct tep_event *trace_find_next_event(struct tep_handle *pevent,
 					struct tep_event *event)
 {
+	static struct tep_event **all_events;
+	static int events_count;
 	static int idx;
-	int events_count;
-	struct tep_event *all_events;
 
-	all_events = tep_get_first_event(pevent);
-	events_count = tep_get_events_count(pevent);
-	if (!pevent || !all_events || events_count < 1)
+	if (!pevent || !all_events)
 		return NULL;
 
 	if (!event) {
 		idx = 0;
-		return all_events;
+		events_count = tep_get_events_count(pevent);
+		if (events_count < 1)
+			return NULL;
+
+		all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
+		if (all_events)
+			return all_events[0];
+		return NULL;
 	}
 
-	if (idx < events_count && event == (all_events + idx)) {
+	if (idx < events_count && event == all_events[idx]) {
 		idx++;
 		if (idx == events_count)
 			return NULL;
-		return (all_events + idx);
+		return all_events[idx];
 	}
 
 	for (idx = 1; idx < events_count; idx++) {
-		if (event == (all_events + (idx - 1)))
-			return (all_events + idx);
+		if (event == all_events[idx - 1])
+			return all_events[idx];
 	}
 	return NULL;
 }

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [BUG] libtraceevent: perf script -g python segfaults
  2019-10-17 18:41   ` Steven Rostedt
@ 2019-10-17 19:28     ` Arnaldo Carvalho de Melo
  2019-10-17 19:37       ` Steven Rostedt
  0 siblings, 1 reply; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-10-17 19:28 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Arnaldo Carvalho de Melo, Tzvetomir Stoyanov, Jiri Olsa,
	Namhyung Kim, Linux Kernel Mailing List

Em Thu, Oct 17, 2019 at 02:41:14PM -0400, Steven Rostedt escreveu:
> On Thu, 17 Oct 2019 14:38:41 -0400
> Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> >  struct tep_event *trace_find_next_event(struct tep_handle *pevent,
> >  					struct tep_event *event)
> >  {
> > +	static struct tep_event **all_events;
> >  	static int idx;
> >  	int events_count;
> > -	struct tep_event *all_events;
> 
> If we are going to use static variables, let's make them all static and
> optimize it a little more...

I'll test it, but can't you have this somewhere else, i.e. at
tep_handle perhaps?

- Arnaldo
 
> -- Steve
> 
> diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
> index ad74be1f0e42..3f23462517a3 100644
> --- a/tools/perf/util/trace-event-parse.c
> +++ b/tools/perf/util/trace-event-parse.c
> @@ -193,30 +193,35 @@ int parse_event_file(struct tep_handle *pevent,
>  struct tep_event *trace_find_next_event(struct tep_handle *pevent,
>  					struct tep_event *event)
>  {
> +	static struct tep_event **all_events;
> +	static int events_count;
>  	static int idx;
> -	int events_count;
> -	struct tep_event *all_events;
>  
> -	all_events = tep_get_first_event(pevent);
> -	events_count = tep_get_events_count(pevent);
> -	if (!pevent || !all_events || events_count < 1)
> +	if (!pevent || !all_events)
>  		return NULL;
>  
>  	if (!event) {
>  		idx = 0;
> -		return all_events;
> +		events_count = tep_get_events_count(pevent);
> +		if (events_count < 1)
> +			return NULL;
> +
> +		all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
> +		if (all_events)
> +			return all_events[0];
> +		return NULL;
>  	}
>  
> -	if (idx < events_count && event == (all_events + idx)) {
> +	if (idx < events_count && event == all_events[idx]) {
>  		idx++;
>  		if (idx == events_count)
>  			return NULL;
> -		return (all_events + idx);
> +		return all_events[idx];
>  	}
>  
>  	for (idx = 1; idx < events_count; idx++) {
> -		if (event == (all_events + (idx - 1)))
> -			return (all_events + idx);
> +		if (event == all_events[idx - 1])
> +			return all_events[idx];
>  	}
>  	return NULL;
>  }

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] libtraceevent: perf script -g python segfaults
  2019-10-17 19:28     ` Arnaldo Carvalho de Melo
@ 2019-10-17 19:37       ` Steven Rostedt
  2019-10-17 19:49         ` Arnaldo Carvalho de Melo
                           ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Steven Rostedt @ 2019-10-17 19:37 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Tzvetomir Stoyanov, Jiri Olsa, Namhyung Kim, Linux Kernel Mailing List

On Thu, 17 Oct 2019 16:28:32 -0300
Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> wrote:

> Em Thu, Oct 17, 2019 at 02:41:14PM -0400, Steven Rostedt escreveu:
> > On Thu, 17 Oct 2019 14:38:41 -0400
> > Steven Rostedt <rostedt@goodmis.org> wrote:
> >   
> > >  struct tep_event *trace_find_next_event(struct tep_handle *pevent,
> > >  					struct tep_event *event)
> > >  {
> > > +	static struct tep_event **all_events;
> > >  	static int idx;
> > >  	int events_count;
> > > -	struct tep_event *all_events;  
> > 
> > If we are going to use static variables, let's make them all static and
> > optimize it a little more...  
> 
> I'll test it, but can't you have this somewhere else, i.e. at
> tep_handle perhaps?
> 
>

Or we can nuke the function entirely, it's a rather silly helper
anyway. Just do this:

-- Steve


diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index b93f36b887b5..f1d5f564aa46 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -537,10 +537,11 @@ static int perl_stop_script(void)
 
 static int perl_generate_script(struct tep_handle *pevent, const char *outfile)
 {
+	int i, not_first, count, nr_events;
+	struct tep_event **all_events;
 	struct tep_event *event = NULL;
 	struct tep_format_field *f;
 	char fname[PATH_MAX];
-	int not_first, count;
 	FILE *ofp;
 
 	sprintf(fname, "%s.pl", outfile);
@@ -601,8 +602,11 @@ sub print_backtrace\n\
 }\n\n\
 ");
 
+	nr_events = tep_get_events_count(pevent);
+	all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
 
-	while ((event = trace_find_next_event(pevent, event))) {
+	for (i = 0; all_events && i < nr_events; i++) {
+		event = all_events[i];
 		fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
 		fprintf(ofp, "\tmy (");
 
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 87ef16a1b17e..2a148a10d0de 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -1590,10 +1590,11 @@ static int python_stop_script(void)
 
 static int python_generate_script(struct tep_handle *pevent, const char *outfile)
 {
+	int i, not_first, count, nr_events;
+	struct tep_event **all_events;
 	struct tep_event *event = NULL;
 	struct tep_format_field *f;
 	char fname[PATH_MAX];
-	int not_first, count;
 	FILE *ofp;
 
 	sprintf(fname, "%s.py", outfile);
@@ -1638,7 +1639,11 @@ static int python_generate_script(struct tep_handle *pevent, const char *outfile
 	fprintf(ofp, "def trace_end():\n");
 	fprintf(ofp, "\tprint(\"in trace_end\")\n\n");
 
-	while ((event = trace_find_next_event(pevent, event))) {
+	nr_events = tep_get_events_count(pevent);
+	all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
+
+	for (i = 0; all_events && i < nr_events; i++) {
+		event = all_events[i];
 		fprintf(ofp, "def %s__%s(", event->system, event->name);
 		fprintf(ofp, "event_name, ");
 		fprintf(ofp, "context, ");



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [BUG] libtraceevent: perf script -g python segfaults
  2019-10-17 19:37       ` Steven Rostedt
@ 2019-10-17 19:49         ` Arnaldo Carvalho de Melo
  2019-10-17 19:51           ` Arnaldo Carvalho de Melo
  2019-10-21 23:19         ` [tip: perf/core] perf scripting engines: Iterate on tep event arrays directly tip-bot2 for Steven Rostedt (VMware)
  2019-11-06 18:14         ` [tip: perf/urgent] " tip-bot2 for Steven Rostedt (VMware)
  2 siblings, 1 reply; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-10-17 19:49 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Arnaldo Carvalho de Melo, Tzvetomir Stoyanov, Jiri Olsa,
	Namhyung Kim, Linux Kernel Mailing List

Em Thu, Oct 17, 2019 at 03:37:33PM -0400, Steven Rostedt escreveu:
> On Thu, 17 Oct 2019 16:28:32 -0300
> Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> wrote:
> 
> > Em Thu, Oct 17, 2019 at 02:41:14PM -0400, Steven Rostedt escreveu:
> > > On Thu, 17 Oct 2019 14:38:41 -0400
> > > Steven Rostedt <rostedt@goodmis.org> wrote:
> > >   
> > > >  struct tep_event *trace_find_next_event(struct tep_handle *pevent,
> > > >  					struct tep_event *event)
> > > >  {
> > > > +	static struct tep_event **all_events;
> > > >  	static int idx;
> > > >  	int events_count;
> > > > -	struct tep_event *all_events;  
> > > 
> > > If we are going to use static variables, let's make them all static and
> > > optimize it a little more...  
> > 
> > I'll test it, but can't you have this somewhere else, i.e. at
> > tep_handle perhaps?
> > 
> >
> 
> Or we can nuke the function entirely, it's a rather silly helper
> anyway. Just do this:

I like it, that is a good nuke use, nice button to press! :-)

Testing it now...

- Arnaldo
 
> -- Steve
> 
> 
> diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
> index b93f36b887b5..f1d5f564aa46 100644
> --- a/tools/perf/util/scripting-engines/trace-event-perl.c
> +++ b/tools/perf/util/scripting-engines/trace-event-perl.c
> @@ -537,10 +537,11 @@ static int perl_stop_script(void)
>  
>  static int perl_generate_script(struct tep_handle *pevent, const char *outfile)
>  {
> +	int i, not_first, count, nr_events;
> +	struct tep_event **all_events;
>  	struct tep_event *event = NULL;
>  	struct tep_format_field *f;
>  	char fname[PATH_MAX];
> -	int not_first, count;
>  	FILE *ofp;
>  
>  	sprintf(fname, "%s.pl", outfile);
> @@ -601,8 +602,11 @@ sub print_backtrace\n\
>  }\n\n\
>  ");
>  
> +	nr_events = tep_get_events_count(pevent);
> +	all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
>  
> -	while ((event = trace_find_next_event(pevent, event))) {
> +	for (i = 0; all_events && i < nr_events; i++) {
> +		event = all_events[i];
>  		fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
>  		fprintf(ofp, "\tmy (");
>  
> diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
> index 87ef16a1b17e..2a148a10d0de 100644
> --- a/tools/perf/util/scripting-engines/trace-event-python.c
> +++ b/tools/perf/util/scripting-engines/trace-event-python.c
> @@ -1590,10 +1590,11 @@ static int python_stop_script(void)
>  
>  static int python_generate_script(struct tep_handle *pevent, const char *outfile)
>  {
> +	int i, not_first, count, nr_events;
> +	struct tep_event **all_events;
>  	struct tep_event *event = NULL;
>  	struct tep_format_field *f;
>  	char fname[PATH_MAX];
> -	int not_first, count;
>  	FILE *ofp;
>  
>  	sprintf(fname, "%s.py", outfile);
> @@ -1638,7 +1639,11 @@ static int python_generate_script(struct tep_handle *pevent, const char *outfile
>  	fprintf(ofp, "def trace_end():\n");
>  	fprintf(ofp, "\tprint(\"in trace_end\")\n\n");
>  
> -	while ((event = trace_find_next_event(pevent, event))) {
> +	nr_events = tep_get_events_count(pevent);
> +	all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
> +
> +	for (i = 0; all_events && i < nr_events; i++) {
> +		event = all_events[i];
>  		fprintf(ofp, "def %s__%s(", event->system, event->name);
>  		fprintf(ofp, "event_name, ");
>  		fprintf(ofp, "context, ");
> 

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [BUG] libtraceevent: perf script -g python segfaults
  2019-10-17 19:49         ` Arnaldo Carvalho de Melo
@ 2019-10-17 19:51           ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2019-10-17 19:51 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Arnaldo Carvalho de Melo, Tzvetomir Stoyanov, Jiri Olsa,
	Namhyung Kim, Linux Kernel Mailing List

Em Thu, Oct 17, 2019 at 04:49:08PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Oct 17, 2019 at 03:37:33PM -0400, Steven Rostedt escreveu:
> > On Thu, 17 Oct 2019 16:28:32 -0300
> > Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> wrote:
> > 
> > > Em Thu, Oct 17, 2019 at 02:41:14PM -0400, Steven Rostedt escreveu:
> > > > On Thu, 17 Oct 2019 14:38:41 -0400
> > > > Steven Rostedt <rostedt@goodmis.org> wrote:
> > > >   
> > > > >  struct tep_event *trace_find_next_event(struct tep_handle *pevent,
> > > > >  					struct tep_event *event)
> > > > >  {
> > > > > +	static struct tep_event **all_events;
> > > > >  	static int idx;
> > > > >  	int events_count;
> > > > > -	struct tep_event *all_events;  
> > > > 
> > > > If we are going to use static variables, let's make them all static and
> > > > optimize it a little more...  
> > > 
> > > I'll test it, but can't you have this somewhere else, i.e. at
> > > tep_handle perhaps?
> > > 
> > >
> > 
> > Or we can nuke the function entirely, it's a rather silly helper
> > anyway. Just do this:
> 
> I like it, that is a good nuke use, nice button to press! :-)
> 
> Testing it now...

Reported-by: Daniel Bristot de Oliveira <bristot@redhat.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>

Works like a charm, thanks!

- Arnaldo

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [tip: perf/core] perf scripting engines: Iterate on tep event arrays directly
  2019-10-17 19:37       ` Steven Rostedt
  2019-10-17 19:49         ` Arnaldo Carvalho de Melo
@ 2019-10-21 23:19         ` tip-bot2 for Steven Rostedt (VMware)
  2019-11-06 18:14         ` [tip: perf/urgent] " tip-bot2 for Steven Rostedt (VMware)
  2 siblings, 0 replies; 10+ messages in thread
From: tip-bot2 for Steven Rostedt (VMware) @ 2019-10-21 23:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Daniel Bristot de Oliveira, Steven Rostedt (VMware),
	Arnaldo Carvalho de Melo, Andrew Morton, Jiri Olsa, Namhyung Kim,
	Tzvetomir Stoyanov, linux-trace-devel, Ingo Molnar,
	Borislav Petkov, linux-kernel

The following commit has been merged into the perf/core branch of tip:

Commit-ID:     a5e05abc6b8d81148b35cd8632a4a6252383d968
Gitweb:        https://git.kernel.org/tip/a5e05abc6b8d81148b35cd8632a4a6252383d968
Author:        Steven Rostedt (VMware) <rostedt@goodmis.org>
AuthorDate:    Thu, 17 Oct 2019 17:05:22 -04:00
Committer:     Arnaldo Carvalho de Melo <acme@redhat.com>
CommitterDate: Fri, 18 Oct 2019 12:07:46 -03:00

perf scripting engines: Iterate on tep event arrays directly

Instead of calling a useless (and broken) helper function to get the
next event of a tep event array, just get the array directly and iterate
over it.

Note, the broken part was from trace_find_next_event() which after this
will no longer be used, and can be removed.

Committer notes:

This fixes a segfault when generating python scripts from perf.data
files with multiple tracepoint events, i.e. the following use case is
fixed by this patch:

  # perf record -e sched:* sleep 1
  [ perf record: Woken up 31 times to write data ]
  [ perf record: Captured and wrote 0.031 MB perf.data (9 samples) ]
  # perf script -g python
  Segmentation fault (core dumped)
  #

Reported-by: Daniel Bristot de Oliveira <bristot@redhat.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Tzvetomir Stoyanov <tstoyanov@vmware.com>
Cc: linux-trace-devel@vger.kernel.org
Link: http://lkml.kernel.org/r/20191017153733.630cd5eb@gandalf.local.home
Link: http://lore.kernel.org/lkml/20191017210636.061448713@goodmis.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/scripting-engines/trace-event-perl.c   |  8 ++++++--
 tools/perf/util/scripting-engines/trace-event-python.c |  9 +++++++--
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 1596185..741f040 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -539,10 +539,11 @@ static int perl_stop_script(void)
 
 static int perl_generate_script(struct tep_handle *pevent, const char *outfile)
 {
+	int i, not_first, count, nr_events;
+	struct tep_event **all_events;
 	struct tep_event *event = NULL;
 	struct tep_format_field *f;
 	char fname[PATH_MAX];
-	int not_first, count;
 	FILE *ofp;
 
 	sprintf(fname, "%s.pl", outfile);
@@ -603,8 +604,11 @@ sub print_backtrace\n\
 }\n\n\
 ");
 
+	nr_events = tep_get_events_count(pevent);
+	all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
 
-	while ((event = trace_find_next_event(pevent, event))) {
+	for (i = 0; all_events && i < nr_events; i++) {
+		event = all_events[i];
 		fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
 		fprintf(ofp, "\tmy (");
 
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 5d341ef..93c03b3 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -1687,10 +1687,11 @@ static int python_stop_script(void)
 
 static int python_generate_script(struct tep_handle *pevent, const char *outfile)
 {
+	int i, not_first, count, nr_events;
+	struct tep_event **all_events;
 	struct tep_event *event = NULL;
 	struct tep_format_field *f;
 	char fname[PATH_MAX];
-	int not_first, count;
 	FILE *ofp;
 
 	sprintf(fname, "%s.py", outfile);
@@ -1735,7 +1736,11 @@ static int python_generate_script(struct tep_handle *pevent, const char *outfile
 	fprintf(ofp, "def trace_end():\n");
 	fprintf(ofp, "\tprint(\"in trace_end\")\n\n");
 
-	while ((event = trace_find_next_event(pevent, event))) {
+	nr_events = tep_get_events_count(pevent);
+	all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
+
+	for (i = 0; all_events && i < nr_events; i++) {
+		event = all_events[i];
 		fprintf(ofp, "def %s__%s(", event->system, event->name);
 		fprintf(ofp, "event_name, ");
 		fprintf(ofp, "context, ");

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [tip: perf/urgent] perf scripting engines: Iterate on tep event arrays directly
  2019-10-17 19:37       ` Steven Rostedt
  2019-10-17 19:49         ` Arnaldo Carvalho de Melo
  2019-10-21 23:19         ` [tip: perf/core] perf scripting engines: Iterate on tep event arrays directly tip-bot2 for Steven Rostedt (VMware)
@ 2019-11-06 18:14         ` tip-bot2 for Steven Rostedt (VMware)
  2 siblings, 0 replies; 10+ messages in thread
From: tip-bot2 for Steven Rostedt (VMware) @ 2019-11-06 18:14 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Daniel Bristot de Oliveira, Steven Rostedt (VMware),
	Arnaldo Carvalho de Melo, Andrew Morton, Jiri Olsa, Namhyung Kim,
	Tzvetomir Stoyanov, linux-trace-devel, Ingo Molnar,
	Borislav Petkov, linux-kernel

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID:     443b0636ea7386d01dc460b4a4264e125f710b53
Gitweb:        https://git.kernel.org/tip/443b0636ea7386d01dc460b4a4264e125f710b53
Author:        Steven Rostedt (VMware) <rostedt@goodmis.org>
AuthorDate:    Thu, 17 Oct 2019 17:05:22 -04:00
Committer:     Arnaldo Carvalho de Melo <acme@redhat.com>
CommitterDate: Tue, 05 Nov 2019 08:39:26 -03:00

perf scripting engines: Iterate on tep event arrays directly

Instead of calling a useless (and broken) helper function to get the
next event of a tep event array, just get the array directly and iterate
over it.

Note, the broken part was from trace_find_next_event() which after this
will no longer be used, and can be removed.

Committer notes:

This fixes a segfault when generating python scripts from perf.data
files with multiple tracepoint events, i.e. the following use case is
fixed by this patch:

  # perf record -e sched:* sleep 1
  [ perf record: Woken up 31 times to write data ]
  [ perf record: Captured and wrote 0.031 MB perf.data (9 samples) ]
  # perf script -g python
  Segmentation fault (core dumped)
  #

Reported-by: Daniel Bristot de Oliveira <bristot@redhat.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Tzvetomir Stoyanov <tstoyanov@vmware.com>
Cc: linux-trace-devel@vger.kernel.org
Link: http://lkml.kernel.org/r/20191017153733.630cd5eb@gandalf.local.home
Link: http://lore.kernel.org/lkml/20191017210636.061448713@goodmis.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/scripting-engines/trace-event-perl.c   |  8 ++++++--
 tools/perf/util/scripting-engines/trace-event-python.c |  9 +++++++--
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 1596185..741f040 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -539,10 +539,11 @@ static int perl_stop_script(void)
 
 static int perl_generate_script(struct tep_handle *pevent, const char *outfile)
 {
+	int i, not_first, count, nr_events;
+	struct tep_event **all_events;
 	struct tep_event *event = NULL;
 	struct tep_format_field *f;
 	char fname[PATH_MAX];
-	int not_first, count;
 	FILE *ofp;
 
 	sprintf(fname, "%s.pl", outfile);
@@ -603,8 +604,11 @@ sub print_backtrace\n\
 }\n\n\
 ");
 
+	nr_events = tep_get_events_count(pevent);
+	all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
 
-	while ((event = trace_find_next_event(pevent, event))) {
+	for (i = 0; all_events && i < nr_events; i++) {
+		event = all_events[i];
 		fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name);
 		fprintf(ofp, "\tmy (");
 
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 5d341ef..93c03b3 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -1687,10 +1687,11 @@ static int python_stop_script(void)
 
 static int python_generate_script(struct tep_handle *pevent, const char *outfile)
 {
+	int i, not_first, count, nr_events;
+	struct tep_event **all_events;
 	struct tep_event *event = NULL;
 	struct tep_format_field *f;
 	char fname[PATH_MAX];
-	int not_first, count;
 	FILE *ofp;
 
 	sprintf(fname, "%s.py", outfile);
@@ -1735,7 +1736,11 @@ static int python_generate_script(struct tep_handle *pevent, const char *outfile
 	fprintf(ofp, "def trace_end():\n");
 	fprintf(ofp, "\tprint(\"in trace_end\")\n\n");
 
-	while ((event = trace_find_next_event(pevent, event))) {
+	nr_events = tep_get_events_count(pevent);
+	all_events = tep_list_events(pevent, TEP_EVENT_SORT_ID);
+
+	for (i = 0; all_events && i < nr_events; i++) {
+		event = all_events[i];
 		fprintf(ofp, "def %s__%s(", event->system, event->name);
 		fprintf(ofp, "event_name, ");
 		fprintf(ofp, "context, ");

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-11-06 18:15 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-17 15:42 [BUG] libtraceevent: perf script -g python segfaults Arnaldo Carvalho de Melo
2019-10-17 17:45 ` Steven Rostedt
2019-10-17 18:38 ` Steven Rostedt
2019-10-17 18:41   ` Steven Rostedt
2019-10-17 19:28     ` Arnaldo Carvalho de Melo
2019-10-17 19:37       ` Steven Rostedt
2019-10-17 19:49         ` Arnaldo Carvalho de Melo
2019-10-17 19:51           ` Arnaldo Carvalho de Melo
2019-10-21 23:19         ` [tip: perf/core] perf scripting engines: Iterate on tep event arrays directly tip-bot2 for Steven Rostedt (VMware)
2019-11-06 18:14         ` [tip: perf/urgent] " tip-bot2 for Steven Rostedt (VMware)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).