mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2026-03-02 22:57:32 -05:00
Bug: QtSingleApplication's UNIX socket sometimes disappears #4018
Labels
No labels
Accessibility
AppImage
Bounty
Build system
CI
Can't reproduce
Code cleanup
Confirmed bug
Confirmed bug
Core
Crash
Data loss
Discussion
Docker
Documentation
Duplicate
Feature
Feature request
Feature request
Feature request
Filters
Flatpak
GUI
Has workaround
I2P
Invalid
Libtorrent
Look and feel
Meta
NSIS
Network
Not an issue
OS: *BSD
OS: Linux
OS: Windows
OS: macOS
PPA
Performance
Project management
Proxy/VPN
Qt bugs
Qt6 compat
RSS
Search engine
Security
Temp folder
Themes
Translations
Triggers
Waiting diagnosis
Waiting info
Waiting upstream
Waiting web implementation
Watched folders
WebAPI
WebUI
autoCloseOldIssue
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/qBittorrent#4018
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @vphantom on GitHub (Mar 5, 2016).
If I run qBittorrent, and then invoke it a second time (say, to add a torrent from another application or the command line for example) the full application is launched a second time in parallel (which I race to close to avoid conflicts!) instead of the already-running instance being told to add the specified magnet link or torrent file.
I can only imagine that QtSingleApplication::isRunning() is itself not detecting what it should? Maybe this is Qt4 behavior that is broken/absent from Qt5? I never touched Qt stuff before so I'm a bit lost. :(
qBittorrent: 3.3.3
Qt: 5.3.2
libtorrent: 1.0.8.0
boost: 1.55.0
OS version: Version? Mostly Debian Jessie, uname: 4.2.0-0.bpo.1-amd64 #1 SMP Debian 4.2.6-3~bpo8+2 (2015-12-14) x86_64 GNU/Linux
@vphantom commented on GitHub (Mar 6, 2016):
Interesting information: it seems that the QtSingleApplication UNIX socket has vanished but the lock file still exists:
Even weirder, I stopped and started qBittorrent numerous times since January 25th, yet that's the lockfile's timestamp. I'm starting to suspect that this is an issue with Qt5, but I couldn't find documentation to support this (I only found one cryptic Qt 4.4 document which would even mention the existence of QtSingleApplication::isRunning() at all.)
I finally decided to stop qBittorrent, delete the stale lockfile, and restart it. This time, a brand new socket and lockfile were created, and attempts to launch qBittorrent multiple times correctly spoke to the running instance instead of starting new ones.
Therefore, the core issue here is that the UNIX socket sometimes disappears, and when it does, the stale lockfile prevents qBittorrent from properly creating said socket next time it is run, making it vulnerable to being launched multiple times.
@sledgehammer999 commented on GitHub (May 13, 2018):
One would have thought that qtsingleapplication would test if the lockfile is still valid. And if not, remove it and create a new lockfile and UNIX socket pair.
I assume it already has this logic, but it is broken.
@sledgehammer999 commented on GitHub (May 13, 2018):
Btw, does your distro ship a qtsingleapplication package or does qbittorrent use its own copy?
@vedgy commented on GitHub (May 13, 2018):
Neither Debian nor Arch have its own qtsingleapplication package, so I suppose both @vphantom and @dreamhunt used the qbittorrent's copy. Not many distributions ship this library: https://repology.org/metapackage/qtsingleapplication/versions
I have the same issue with goldendict, and I believe that the lock file is not at fault for the second application instance. Quitting the application instance, which got its qtsingleapplication local server stopped (for unknown reason), helps. It doesn't matter whether I keep or delete the lock file. This explanation is compatible with @vphantom's comments above - his issue disappeared after quitting all application instances (including the longest-running one, whose local server had apparently stopped).
qtsingleapplication not removing the lock file has been reported for Windows years ago in QTSOLBUG-179. The leftover lock file seems to not have caused other issues to the reporter.
Goldendict uses a slightly newer version of qtsingleapplication and has the same issue. I also tried updating qtsingleapplication to the latest official version, but it didn't help either. There are very few changes to qtsingleapplication in the recent years. qtsingleapplication bug reports look like Qt developers don't care much about this old solution.
I've found two qtsingleapplication alternatives with comparable functionality:
I tried integrating these 2 alternatives into goldendict. Unfortunately they are not completely API-compatible and passing messages to the already running application instance doesn't work right away.
Perhaps a new D-Bus qtsingleapplication backend is called for (see a related discussion here: https://forum.qt.io/topic/71778/what-happened-to-qtsingleapplication/7).
@sledgehammer999 commented on GitHub (May 13, 2018):
By looking at the qtsingleapplication source I can see one possible place where it fails. And it should log a warning in the console.
In file
qtlocalpeer.cpp:@vedgy @dreamhunt can you run your 1st/primary instance from the console? Does any message/warning appear there in the form of:
If so, it should be accompanied by a reason/error string. Can you paste it here?
@vedgy commented on GitHub (May 13, 2018):
@sledgehammer999, I started goldendict from terminal to monitor its output once the second instance gets launched. But I don't think that your suggestion is going to work. If I understand correctly, the primary application instance runs
isClient()only while starting. So this function's failure should manifest itself immediately. This is not what I observe. When other instances are started, they detect this primary running instance correctly for a while. But after this same primary instance runs for some time (for a few days perhaps), its server stops and other instances no longer detect it.@sledgehammer999 commented on GitHub (May 13, 2018):
If you have verified that the issue is that the server has stopped, then I don't think the bug can be fixed. Why? Because the QLocalServer class doesn't have a signal for that. It has only the
newConnectionsignal. The only possible way to detect that something's wrong, is for the primary instance to checkQLocalServer::serverError()in a continuous timeout loop. And that won't be pretty.PS: Since you are able to reproduce, there is a way to discover if the server is the problem:
QtLocalPeer::QtLocalPeer()and calculate yourself the value ofsocketName(or put a print to see what it truly is)QLocalSocket::connectToServer(socketName). Then inspect the state of the socket and the possible error string. Don't forget to let the mainloop run for a while too.@vedgy commented on GitHub (May 21, 2018):
I have tested what happens to the failing local server with a simple client reusing some of the qtsingleapplication code as @sledgehammer999 suggested. The test project: QLocalSocketTest.zip. The output after the goldendict's qtsingleapplication files are deleted from /tmp:
There is no suspicious stdout/stderr output from the failed goldendict instance.
Finally I found the culprit of this bug! Quitting yet another application that uses qtsingleapplication - octopi - deletes ALL qtsingleapplication files, including lock files, from /tmp. So quitting octopi allows launching a second instance of goldendict, qbittorrent and qtcreator -client. Quitting any of these other 3 qtsingleapplication-using applications does not impact files from independent applications. So this is clearly a bug in octopi.
@dreamhunt, do you use octopi? If yes, please confirm that the second qbittorrent instance can be launched after quitting octopi.
I'm looking for the bug in the octopi code right now.
EDIT: found the actual bug: UnixCommand::removeTemporaryFiles() deletes "unneeded" files far too aggressively. I'll report this bug shortly.
@mozo78 commented on GitHub (May 21, 2018):
Yes, I use Octopi on a daily basis. Great you find this annoyance!!!
@sledgehammer999 commented on GitHub (May 27, 2018):
@vedgy thank you for tracking this down. It seems that itsn't our fault and probably nothing we can do about it.
@dreamhunt I hope your problem has the same root cause.
@dreamhunt commented on GitHub (Jun 10, 2018):
The bug has finally fixed:
github.com/aarnt/octopi@be5fa78234