8000 Fix crash when restarting OSX single shot timer by dopplershift · Pull Request #9662 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Fix crash when restarting OSX single shot timer #9662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 7, 2017

Conversation

dopplershift
Copy link
Contributor

Fixes #9655.

Previously, if we had a pointer to an old timer when calling start(), we would manually get the context for the old timer and from there get a pointer to the attribute. The problem is that for a single-timer, the timer is automatically invalidated (and context cleared) at the end. This resulted in trying to Py_DECREF(0x0).

To fix this, use the built-in support for a callback to run when the context is released. By doing so, we can also clean up a lot of code to release the reference in stop() as well.

While I was here I also moved a lot of code to use Py_RETURN_NONE (instead of manually returning Py_None), as well as fixed up some incorrect reference counting.

…b#9655)

Previously, if we had a pointer to an old timer when calling start(), we
would manually get the context for the old timer and from there get a
pointer to the attribute. The problem is that for a single-timer, the
timer is automatically invalidated (and context cleared) at the end.
This resulted in trying to Py_DECREF(0x0).

To fix this, use the built-in support for a callback to run when the
context is released. By doing so, we can also clean up a lot of code to
release the reference in stop() as well.
Simplifies things just a bit.
Group setting all attributes together. Use NULL (rather than 0) where
appropriate for clarity.
@dopplershift
Copy link
Contributor Author

Anyone wanting to understand some of the changes to the macOS API calls should examine: https://developer.apple.com/documentation/corefoundation/1543570-cfrunlooptimercreate

@dopplershift
Copy link
Contributor Author

Here's the script I used for testing:

import matplotlib.pyplot as plt
import sys

fig = plt.figure()
timer = fig.canvas.new_timer(interval=100)
timer.single_shot = True

def test():
    print(sys.getrefcount(timer._on_timer))
    print(sys.getrefcount(timer))
    print("TEST")

timer.add_callback(test)

timer.start()
plt.pause(1.0)
timer.start()
plt.pause(1.0)
timer.start()
plt.pause(1.0)
timer.start()
plt.pause(1.0)
timer.stop()

Without this PR, the script will crash at the second call to start() (adapted from #9655).

@jklymak
Copy link
Member
jklymak commented Nov 2, 2017

Hmmm, I get a seg fault and it doesn't appear to hit all the timers?

$ pythonw testtimer.py
1
4
TEST
/Users/jklymak/anaconda3/envs/matplotlibdev/bin/pythonw: line 3: 17048 Segmentation fault: 11  /Users/jklymak/anaconda3/envs/matplotlibdev/python.app/Contents/MacOS/python "$@"

@dstansby
Copy link
Member
dstansby commented Nov 2, 2017

Works for me - you might need to re-install from source @jklymak to make it work?

Copy link
Member
@dstansby dstansby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I know enough to understand the code changes, but the fix works for my on OSX...

@jklymak
Copy link
Member
jklymak commented Nov 2, 2017

Oh I see, a C file changed. Yes this works if I do a pip install -e .

@tacaswell
Copy link
Member

attn @mdehoon ?

@jklymak
Copy link
Member
jklymak commented Nov 2, 2017

Yeah, I'm only barely qualified to tell if this crashes or not - I can't really review it properly.

Copy link
Member
@jklymak jklymak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works w/ test for me

@jklymak
Copy link
Member
jklymak commented Nov 7, 2017

Merging because it works. If it breaks something else, I suppose the best way to tell is if its in Master...

@jklymak jklymak closed this Nov 7, 2017
@jklymak jklymak reopened this Nov 7, 2017
@jklymak jklymak merged commit 5cbe37f into matplotlib:master Nov 7, 2017
@dopplershift dopplershift deleted the osx-timer-crash branch November 7, 2017 21:22
@dopplershift
Copy link
Contributor Author

If something breaks, I promise to pay attention. I'm at least capable of building and running on my osx box.

@dstansby
Copy link
Member
dstansby commented Nov 7, 2017

I use the master branch pretty much exclusively day to day on OSX, so if something breaks it probably won't be long before I notice!

jklymak added a commit that referenced this pull request Nov 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Segmentation fault when starting a timer a second time (MacOS X backend)
4 participants
0