qtconsole segfaults at startup #947

Closed
thisch opened this Issue Oct 30, 2011 · 21 comments

Projects

None yet

5 participants

@thisch
Contributor
thisch commented Oct 30, 2011

on my fedora 15 x86-64 box ipython (latest git version) segfaults

frontend segfaults

» ipython qtconsole --log-level='DEBUG'
[IPythonQtConsoleApp] Config changed:
[IPythonQtConsoleApp] {'Application': {'log_level': u'DEBUG'}}
[IPythonQtConsoleApp] Using existing profile dir: u'/home/thomas/.config/ipython/profile_default'
[IPythonQtConsoleApp] Searching path [u'/home/thomas', u'/home/thomas/.config/ipython/profile_default'] for config files
[IPythonQtConsoleApp] Attempting to load config file: ipython_config.py
[IPythonQtConsoleApp] Config file ipython_config.py not found
[IPythonQtConsoleApp] Attempting to load config file: ipython_qtconsole_config.py
[IPythonQtConsoleApp] Config file not found, skipping: ipython_qtconsole_config.py
[IPythonQtConsoleApp] Connection File not found: kernel-2639.json
zsh: segmentation fault ipython qtconsole --log-level='DEBUG'
[pts/1] thomas@mustang | ~
» [IPKernelApp] Config changed:
[IPKernelApp] {'KernelApp': {'parent_appname': 'ipython-qtconsole'}, 'IPKernelApp': {'log_level': u'DEBUG', 'parent': 1, 'connection_file': u'/home/thomas/.config/ipython/profile_default/security/kernel-2639.json'}}
[IPKernelApp] Using existing profile dir: u'/home/thomas/.config/ipython/profile_default'
[IPKernelApp] Searching path [u'/home/thomas', u'/home/thomas/.config/ipython/profile_default'] for config files
[IPKernelApp] Attempting to load config file: ipython_config.py
[IPKernelApp] Config file ipython_config.py not found
[IPKernelApp] Attempting to load config file: ipython_qtconsole_config.py
[IPKernelApp] Config file not found, skipping: ipython_qtconsole_config.py
[IPKernelApp] Loading connection file /home/thomas/.config/ipython/profile_default/security/kernel-2639.json
[IPKernelApp] Starting the kernel at pid: 2644
[IPKernelApp] shell ROUTER Channel on port: 59635
[IPKernelApp] iopub PUB Channel on port: 51803
[IPKernelApp] stdin ROUTER Channel on port: 43148
[IPKernelApp] Heartbeat REP Channel on port: 50659
[IPKernelApp] To connect another client to this kernel, use:
[IPKernelApp] --existing kernel-2639.json

starting qtconsole with --existing flag

» ipython qtconsole --log-level='DEBUG' --existing kernel-2639.json
[IPythonQtConsoleApp] Config changed:
[IPythonQtConsoleApp] {'Application': {'log_level': u'DEBUG'}, 'IPythonQtConsoleApp': {'existing': u'kernel-2639.json'}}
[IPythonQtConsoleApp] Using existing profile dir: u'/home/thomas/.config/ipython/profile_default'
[IPythonQtConsoleApp] Searching path [u'/home/thomas', u'/home/thomas/.config/ipython/profile_default'] for config files
[IPythonQtConsoleApp] Attempting to load config file: ipython_config.py
[IPythonQtConsoleApp] Config file ipython_config.py not found
[IPythonQtConsoleApp] Attempting to load config file: ipython_qtconsole_config.py
[IPythonQtConsoleApp] Config file not found, skipping: ipython_qtconsole_config.py
[IPythonQtConsoleApp] Connecting to existing kernel: /home/thomas/.config/ipython/profile_default/security/kernel-2639.json
[IPythonQtConsoleApp] Loading connection file /home/thomas/.config/ipython/profile_default/security/kernel-2639.json
zsh: segmentation fault ipython qtconsole --log-level='DEBUG' --existing kernel-2639.json

strace reports (last lines):

read(44, "gn # COLON SIGN\n<dead_"..., 4096) = 4096
read(44, "SIS AND CARON\n<dead_diaeresis> <"..., 4096) = 4096
read(44, " U0309 # COMBIN"..., 4096) = 4096
read(44, "MALL LETTER A WITH RING ABOVE AN"..., 4096) = 4096
read(44, " # LATIN CAPITAL LETTER S WIT"..., 4096) = 4096
read(44, "dead_tilde> <dead_acute> \t "..., 4096) = 4096
read(44, "circumflexgrave # LATIN CAPIT"..., 4096) = 4096
read(44, "ok # LATIN SMALL LETTE"..., 4096) = 4096
read(44, "NG ACUTE ACCENT\n<Multi_key> <apo"..., 4096) = 4096
read(44, "MALL LETTER O WITH COMBINING ACU"..., 4096) = 4096
read(44, " DOUBLE GRAVE ACCENT\n<Multi_key>"..., 4096) = 2671
read(44, "", 4096) = 0
close(44) = 0
munmap(0x7fa350804000, 4096) = 0
poll([{fd=32, events=POLLIN|POLLOUT}], 1, -1) = 1 ([{fd=32, revents=POLLOUT}])
writev(32, [{"\2\21\4\0\1\0\0\0\10\0\0000@@\0\24\0\6\0\1\0\0\22\1\0\0\37\0\0\0"..., 40}, {NULL, 0}, {"", 0}], 3) = 40
poll([{fd=32, events=POLLIN}], 1, -1) = 1 ([{fd=32, revents=POLLIN}])
read(32, "\1\10\236\0\n\0\0\0\37\0\0\0\0\0\0\0%\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 72
read(32, 0x387e8e4, 4096) = -1 EAGAIN (Resource temporarily unavailable)
read(32, 0x387e8e4, 4096) = -1 EAGAIN (Resource temporarily unavailable)
read(32, 0x387e8e4, 4096) = -1 EAGAIN (Resource temporarily unavailable)
stat("/usr/share/fonts/dejavu/DejaVuSansMono.ttf", {st_mode=S_IFREG|0644, st_size=333632, ...}) = 0
open("/usr/share/fonts/dejavu/DejaVuSansMono.ttf", O_RDONLY) = 44
fcntl(44, F_SETFD, FD_CLOEXEC) = 0
fstat(44, {st_mode=S_IFREG|0644, st_size=333632, ...}) = 0
mmap(NULL, 333632, PROT_READ, MAP_PRIVATE, 44, 0) = 0x7fa34ef54000
close(44) = 0
--- {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x10900002d1f} (Segmentation fault) ---
+++ killed by SIGSEGV +++
zsh: segmentation fault strace ipython qtconsole --log-level='DEBUG' --existing kernel-2639.json

@takluyver
Member

Are you using PySide or PyQt? We know there are some bugs in PySide which cause segfaults. But a bug in IPython can't by itself cause a segfault, because all the code is in Python.

@thisch
Contributor
thisch commented Oct 30, 2011

Yes it was in fact Pyside which caused the segfaults. Now everything works fine. Thx

@thisch thisch closed this Oct 30, 2011
@takluyver
Member

@fperez: We seem to be seeing this a lot. Is it worth giving some warning if we detect PySide being used for the frontend? I guess it would only be seen by people starting it from the terminal, but that's probably OK - savvy users will probably try it from a terminal if it seems to be crashing.

Also, any idea if PySide knows what causes this yet?

@fperez
Member
fperez commented Oct 30, 2011

I'm happy to add a warning, yes, but would like to hear from @epatters and @rkern their take on it: I suspect given EPD's distribution of PySide, they know a lot more about the state of this issue than we do.

@epatters
Contributor
epatters commented Nov 1, 2011

Actually, as far as I know, PySide versions 1.0.3+ work with the Qt console. Since we are performing that version check now and the user is running on master, I'm not sure what the issue is. Without more data points, my inclination would be to not issue a warning. Or are we getting a lot of these reports from users running on master?

@thisch
Contributor
thisch commented Nov 1, 2011

I reinstalled pyside and tried to debug the problem.

The qtconsole starts correctly if I start it with "QT_API='pyqt' ipython qtconsole"
and it prints a stacktrace if I start it with "QT_API='pyside' ipython qtconsole" because my PySide version is 1.0.2 -> ImportError.

If I omit the QT_API in front of ipython, QT_API gets set correctly to pyqt in IPython/external/qt.py and then segfaults somewhere else. I think that first importing pyside and then pyqt4 causes the problem. I tested it with commenting out the "import Pyside and Pyside version check" stuff in external/qt.py. If I do so "ipython qtconsole" doesn't segfault.

@minrk
Member
minrk commented Nov 1, 2011

I think you are right that it is the fact that both have been imported. I guess that means the version check is not acceptable, as the fact that old PySide has been imported seems to mean that PyQt will not be functional.

This means that we should not warn, but actually raise an ImportError if we get to PySide that is too old, informing the user about QT_API, if they want to use PyQt.

Which, in turn, would mean that users who have PyQt and out-of-date PySide cannot use the qtconsole with an unconfigured environment. I'm not sure if this is a general issue that affects any users with old PySide and good PyQt, or if it is particular to this environment. If it is a general issue, we should raise an error. If it is not general, then I don't know what would be best. Adding a warning on every startup of a perfectly functional setup would certainly be annoying.

@takluyver
Member

I may be missing something, but if it's unconfigured and PyQt is present, can we not simply skip the version check, and not import PySide at all?

@minrk
Member
minrk commented Nov 1, 2011

We use PySide by default, so the version check only happens if the default package is present, but is too old to use.

@takluyver
Member

Given the number of segfaults we've had with PySide, would it not be sensible to keep PyQt as the default for now?

I've just been helping someone using Python from EPD, and we abandoned the Qt console after the second hard crash in half an hour. Obviously that's down to Enthought's choices, but it seems sensible to default to the one that works reliably.

@minrk
Member
minrk commented Nov 1, 2011

Well, it's Enthought's choice in that if they don't want EPD as a whole to be GPL, they can never bundle PyQt.

It seems to be that approximately 100% of the PySide crashes are related to the calltips, which is why we added the IPythonWidget.enable_calltips configurable, so they can be disabled while PySide figures out their bug.

@takluyver
Member

But IPython itself needn't default to PySide if PyQt is installed, surely?

@minrk
Member
minrk commented Nov 1, 2011

I'm not necessariy opposed to making PySide not the default for now

Also, I've done some digging, and I've actually isolated the crash down to a very short test case that I will submit to PySide (It's in topLevelAt - PySide segfaults whereas PyQt returns None when there is nothing at the cursor position.

@takluyver
Member

Nice one. Hopefully that will get resolved soon.

@minrk
Member
minrk commented Nov 1, 2011

I actually found the PySide calltip crash, isolated it into a tiny test case, and updated my PySide to 1.0.7 and found that it is in fact fixed. I can easily disable the calltips if PySide < 1.0.7 is in use, or we can bump our PySide dependency to 1.0.7.

@takluyver
Member

My vote is to disable the calltips if PySide is less than 1.0.7. Then
again, the next version of EPD should have Pyside 1.0.8 or above, so
perhaps it's not an issue.

@minrk
Member
minrk commented Nov 1, 2011

You are right, that we need not prefer PySide, and I'm not sure that there's a reason that we do other than it matches the ETS defaults. Though there is a general sense that PySide will displace PyQt, being both 'official' and LGPL instead of GPL licensed.

@takluyver
Member

Reasonable enough, but my feeling is that the future can wait until it
looks better than the present. I've also heard some uncertainty about the
future of PySide now that Nokia is no longer going to be funding it, but so
far it looks like it's doing alright.

@minrk
Member
minrk commented Nov 1, 2011

That makes sense. I won't object to switching the default, but some might. I don't imagine it comes up that often yet, as I bet there aren't too many users outside EPD with PySide.

@takluyver
Member

It looks like the big problems with PySide are getting sorted out now -
both by PySide and by your disabling calltips, so I'm more ambivalent about
the default. I think my inclination is still to stick with PyQt for now -
there's no big advantage to PySide besides the license, and PyQt is better
tested. But it's not a pressing issue any more.

@fperez
Member
fperez commented Nov 2, 2011

I don't see a problem making pyqt our default for a while: since absent pyqt we still try to fall back onto pyside, things will continue to work normally for EPD users, who will simply see pyside. But it will also mean that those who happen to have both pyside and pyqt on their systems (common in linux distros) can get the still-more-robust pyqt.

While I certainly hope pyside does very well in the future (I was super sad with the whole nokia saga of going to windows and abandoning their linux/qt work), we should be pragmatic for our users for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment