xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.

Opened 9 months ago

Last modified 3 months ago

#2851 closed defect

segfault in motion.pyx:match_distance() — at Initial Version

Reported by: Ian Collier Owned by: Antoine Martin
Priority: critical Milestone: 4.1
Component: server Version: 4.0.x
Keywords: Cc:


I use xpra for several hours a day, and the server crashes maybe every 1-2 weeks. So this one is tricky to reproduce, and I think if I turn debugging on the log will fill up way before the crash happens. But still, when it does happen it's annoying. There also isn't anything particular I can do to trigger the crash, although my window manager (fvwm1) does weird stuff sometimes, and the crashes have tended to happen during WM operations (although one happened when I dismissed xscreensaver by pressing a key just as it was starting to engage).

The xpra version is 4.0.2 using the distro package from Fedora 32 (both client and server). The previous 3.x version of xpra seemed stable.

The crash is happening in the match_distance function of motion.pyx, here:

for i1 in range(rstart, rend):

i2 = i1+distance
v = a1[i1] <----CRASH

By analysing a core file I've managed to ascertain that 'distance' is zero, line_state is a list of 970 zero-bytes, and 'self' has the following value:

{ob_base = {ob_refcnt = 4,

ob_type = 0x7f0f86a329e0 <pyx_type_4xpra_6server_6window_6motion_ScrollData>}, pyx_vtab =
0x7f0f86a33040 <pyx_vtable_4xpra_6server_6window_6motion_ScrollData>,

weakref = 0x0, distances = 0x0, a1 = 0x0, a2 = 0x0, matched = 0 '\000',
x = 211, y = 44, width = 1542, height = 970}

So the crash is happening because self.a1 is null.

This is called from get_scroll_values() here:

for i in reversed(sorted(scroll_hits.keys())):

v = scroll_hits[i]
for scroll in v:

#find matching lines:
line_defs = self.match_distance(line_state, scroll, MIN_LINE_COUNT)

It looks like 'i' is pointing to the 9th element of the sorted list when this happens, although this is difficult to say because of the various layers of translation and optimisation. The puzzle is that this function starts with

if self.a1==NULL or self.a2==NULL:

return None

and so self.a1 and self.a2 should be guaranteed non-null, right? So something must be nullifying them after the function has started. I have no clue as to what, because I don't actually understand the code. I am imagining that distance shouldn't really be zero here, but don't know whether that's anything to do with it. I guess the hack fix would be to return early from match_distance if a1 or a2 are null, but this wouldn't get to the root cause.

Change History (0)

Note: See TracTickets for help on using tickets.