Work wishes us to be familiar with the capabilities of AI, so I figured I'd let Opus 4.6 have a go at it.
It did fix the immediate issue and here is the result: https://haagch.frickel.club/files/ubtouch_gps_fix/
gps-fix.tar.xz contains a build of the fixed library for current 24.04.1-2 and the scripts to install it, and restore the original version. For installing this system wide fix the root partition needs to be made writeable, then the library replaced, then it can be made readonly again. This worked here, but will need to be applied after every OS update until it is fixed upstream.
Note that it's much better to reproduce a patched library yourself rather than installing a prebuilt one from a random stranger like me.
The patch fix-gps-singleton-instance.patch it came up with is this:
diff --git a/qt/position/core_geo_position_info_source.cpp b/qt/position/core_geo_position_info_source.cpp
index 62e5cfd..a4eeb53 100644
--- a/qt/position/core_geo_position_info_source.cpp
+++ b/qt/position/core_geo_position_info_source.cpp
@@ -389,7 +389,25 @@ void core::GeoPositionInfoSource::Private::handleVelocityUpdate(const cll::Updat
void core::GeoPositionInfoSource::Private::createLocationServiceSession()
{
- instance = std::make_shared<Instance>();
+ // Keep the Instance alive as a process-wide singleton. The dbus-cpp
+ // asio executor uses a global static boost::asio::io_context
+ // (see dbus-cpp executor.cpp make_executor()). When an Instance is
+ // destroyed, its Executor::stop() calls io_context::stop() on that
+ // global object. Because the io_context is shared, this permanently
+ // poisons it: any subsequent io_context::run() returns immediately,
+ // so a new Instance's worker thread exits at once and all blocking
+ // D-Bus calls (transact_method / invoke_method_synchronously) hang
+ // forever waiting for a reply that will never be dispatched.
+ //
+ // QtWebEngine's LocationProviderQt destroys and recreates its
+ // QGeoPositionInfoSource on every geolocation request cycle, which
+ // triggers Instance destruction → io_context::stop(). On the next
+ // cycle a new Instance is created but its worker is dead-on-arrival.
+ //
+ // Fix: use a persistent static shared_ptr so the Instance (and its
+ // worker thread / D-Bus connection) lives for the entire process.
+ static std::shared_ptr<Instance> s_instance = std::make_shared<Instance>();
+ instance = s_instance;
try {
session = instance->getService()->create_session_for_criteria(cll::Criteria{});
and the AGENTS.md and final_report.md files should contain enough info to reproduce this build via qemu and proot.
As usual with AI generated fixes, I don't claim that this is the correct way to fix this, nor that there are no issues with this like leaks. So don't go around and demand someone merge this immediately. I just figured I'd post this because it'll make my own smartphone slightly more useful for navigation right now.