macOS injector matches QtCore5Compat instead of QtCore and fails to load QtNetwork/QtGui

Description of Issue

On macOS, the Qat injector discovers Qt by taking the first loaded image whose filename contains the substring "QtCore". Applications that also ship QtCore5Compat (Qt 6 Core5Compat module) can therefore resolve the wrong library. From that path the injector derives non-existent QtNetwork / QtGui sibling names, injection fails, and the Qat server never starts.

Linux already avoids this by matching specific sonames (libQt6Core.so / libQt5Core.so). macOS does not.

Affected version(s)

1.8.0 (and earlier macOS injector revisions that use libName.find("QtCore"))

System information

  • OS: macOS
  • OS version: darwin 25.6.0
  • Qt version: 6.7.3 (framework build, app also links QtCore5Compat)
  • Python version: 3.14.7
  • Qat: 1.8.0 (PyPI / installed package)

Steps to reproduce

  1. Build or install a Qt 6 application that links Qt6::Core5Compat (so the bundle contains both QtCore.framework and QtCore5Compat.framework), with QtCore5Compat appearing before QtCore in the Mach-O load commands / dyld image list.
  2. Register that app in applications.json and start it with Qat (qat.start_application(...) or qat-gui) on macOS without preloading real QtCore via DYLD_INSERT_LIBRARIES.
  3. Observe injector output and the failure to attach.

What is the current issue behavior?

Injector picks QtCore5Compat, fails to load Network/Gui derived from that name, retries after waiting for libraries, fails again, and Qat cannot connect:

ProcessLookupError: Could not retrieve server port number. Cannot establish communication with application.

What is the expected behavior?

FindQtCorePath() should resolve the real Qt Core library (QtCore framework binary, or libQt5Core.* / libQt6Core.* dylibs), never QtCore5Compat, so injection and TCP attach succeed on apps that use Core5Compat.

Relevant logs and/or screenshots

Loading injector
Detected Qt version 6.7.3
QtCore library found at "/Applications/myApp.app/Contents/Frameworks/QtCore5Compat.framework/Versions/A/QtCore5Compat"
Could not load QtNetwork library
Could not load Qt libraries
Waiting for Qt libraries to be loaded before injecting server
...
Libraries loaded in 1850 ms
Loading injector
Detected Qt version 6.7.3
QtCore library found at "/Applications/myApp.app/Contents/Frameworks/QtCore5Compat.framework/Versions/A/QtCore5Compat"
Could not load QtNetwork library
Could not load Qt libraries

Possible fixes

Root cause in injector/macos.cpp — substring match:

if (libName.find("QtCore") != std::string::npos)

QtCore5Compat matches that. LoadQtLibraries() then does std::regex_replace(..., "Core.", "Network.") on the filename, producing something like QtNetwork5Compat under the Compat framework path, which does not exist.

Suggested fix: match the exact framework binary name and/or Qt Core dylib prefixes (aligned with Linux), e.g.:

const bool isFrameworkCore = (libName == "QtCore");
const bool isDylibCore =
   libName.find("libQt6Core.") == 0 || libName.find("libQt5Core.") == 0;

if (isFrameworkCore || isDylibCore)
{
   // ...
}

Compare with the stricter Linux matcher in injector/linux.cpp (libQt6Core.so / libQt5Core.so).

Edited by Alexander