Bug #1052
closedPython 3 exit code 139 with repeated requests of EventDeclaration
0%
Description
Using Python 3.2.3 on Ubuntu 14.04.4 through PyCharm Community Edition 2016.1.3, build #PC-145.971, JRE: 1.8.0_76-release-b32 amd64, JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
#!/usr/bin/python3 import babeltrace def some_events(trace_collection, number): n_names = 0 for event in trace_collection.events: n_names += 1 print("{0:s}:".format(event.name)) n_decl = 0 for decl in event.handle.events: n_decl += 1 print(" {0:d} declarations".format(n_decl)) if (number is not None) and (n_names >= number): break trace_path = "/home/daniel/lttng-traces/ffx-session-20160706-141412.0/kernel" trace_collection = babeltrace.TraceCollection() trace_handle = trace_collection.add_trace(trace_path, 'ctf') print("first three events:") some_events(trace_collection, 3) print("some_events done.") print("All done.")
Results in:
/usr/bin/python3.2mu /home/daniel/pycharm-community-2016.1.3/helpers/pydev/pydevd.py --multiproc --qt-support --client 127.0.0.1 --port 58138 --file /home/daniel/PycharmProjects/untitled/ltrace_examples.py pydev debugger: process 8756 is connecting Connected to pydev debugger (build 145.971) first three events: syscall_exit_epoll_wait: 12826 declarations syscall_entry_ioctl: 12826 declarations Process finished with exit code 139
The exit occurs on the for event in trace_collection.events:
line when the third event (which is quite valid) should be generated. Exit code 139 is SIGSEGV, "attempt to access a virtual address which is not in your address space", and is probably an out-of-memory error. Maybe a major memory leak? I tried importing gc and calling gc.collect() right after each inner loop: it collects no objects.
(The set of @EventDeclaration@s is unchanging for a given trace; but there could be cases where one wants to interrogate the @EventDeclaration@s of a collection of several traces)
Updated by Daniel U. Thibault almost 9 years ago
If I use the trace_handle
from the TraceCollection.add_trace
or if I recover it from a piece of code like:
for event in trace_collection.events: trace1 = event.handle break
Then I can loop over the set of
EventDeclaration
as many times as I like without triggering exit code 139:while True: n_decl = 0 for decl in trace_handle.events: n_decl += 1 print(" {0:d} declarations".format(n_decl))
So it looks like it's not a memory leak but rather more about a handle-like value that goes out of context. You can get an exit code 139 if you grab the first event from the
for event in trace_collection.events:
loop, break out of the loop, then try to use that value. This is a stronger constraint than the one appearing in the documentation, http://diamon.org/babeltrace/docs/python/reader/ :Due to limitations of the native Babeltrace API, only one event may be "alive" at a given time, i.e. a user should never store a copy of the events returned by this function for ulterior use. Users shall make sure to copy the information they need from an event before accessing the next one.
That warning boils down to "you can't use an event reference once the iterator has moved on to the next one". It needs to be broadened to "you can't use an event reference once the iterator has moved on to the next one or gone out of scope".
Updated by Daniel U. Thibault almost 9 years ago
Here's an even simpler case:
def some_events(trace_collection, number): n_events = 0 path = None for event in trace_collection.events: th = event.handle n_events += 1 print("Trace handles obtained: {0:d}".format(n_events))
This loop will crash (at the
for event in trace_collection.events:
line) with exit code 139 when it tries to read the fourth event.Updated by Daniel U. Thibault almost 9 years ago
This is a very annoying bug that is getting in the way of our trace analyses (and should be treated as high priority). For instance, reading a bunch of sequential (non-overlapping in time) traces and then trying to treat them one at a time with:
traces = babeltrace.TraceCollection() trace_handles = traces.add_traces_recursive(traces_path, 'ctf') handle = None for event in traces.events: if (handle is None) or (handle.id != event.handle.id): # New trace (they don't overlap) handle = event.handle print("Trace {0}".format(handle.path)) ...
will fail miserably with an exit code 139 on the third event.
Updated by Jérémie Galarneau almost 9 years ago
I agree that the warning should be clarified.
Do you have a trace that reproduces the problem?
Updated by Daniel U. Thibault almost 9 years ago
Here's a self-contained script and a small (kernel system call) trace that chokes on the third pass through the EventDeclarations. You'll have to adapt the trace_path
#!/usr/bin/python3 import sys, babeltrace def some_events(trace_collection, number): n_names = 0 for event in trace_collection.events: n_names += 1 print("{0:s}:".format(event.name)) n_decl = 0 for decl in event.handle.events: n_decl += 1 print(" {0:d} declarations".format(n_decl)) if (number is not None) and (n_names >= number): break def main(argv): """ The main function. :param argv: the list of command-line arguments, excluding the executable name :return: Nothing """ trace_path = "/home/daniel/lttng-traces/smallsession-20160803-143625/kernel" trace_collection = babeltrace.TraceCollection() trace_handle = trace_collection.add_trace(trace_path, 'ctf') print("first three events:") some_events(trace_collection, 3) print("some_events done.") print("All done.") if __name__ == "__main__": main(sys.argv[1:])
Updated by Daniel U. Thibault almost 9 years ago
Umm...Trouble uploading. It's a 1.1 MB zip...The button reads "ExecutableDownloadsNew" (truncated) after I've uploaded.
Updated by Jonathan Rajotte Julien about 5 years ago
- Status changed from New to Invalid
State of babeltrace moved a lot since.
Closing this ticket as invalid. Reopen it if it stills apply to Babeltrace 2.