f31522130f
Build system (5 gaps hardened): - COOKBOOK_OFFLINE defaults to true (fork-mode) - normalize_patch handles diff -ruN format - New 'repo validate-patches' command (25/25 relibc patches) - 14 patched Qt/Wayland/display recipes added to protected list - relibc archive regenerated with current patch chain Boot fixes (fixable): - Full ISO EFI partition: 16 MiB → 1 MiB (matches mini, BIOS hardcoded 2 MiB offset) - D-Bus system bus: absolute /usr/bin/dbus-daemon path (was skipped) - redbear-sessiond: absolute /usr/bin/redbear-sessiond path (was skipped) - daemon framework: silenced spurious INIT_NOTIFY warnings for oneshot_async services (P0-daemon-silence-init-notify.patch) - udev-shim: demoted INIT_NOTIFY warning to INFO (expected for oneshot_async) - relibc: comprehensive named semaphores (sem_open/close/unlink) replacing upstream todo!() stubs - greeterd: Wayland socket timeout 15s → 30s (compositor DRM wait) - greeter-ui: built and linked (header guard unification, sem_compat stubs removed) - mc: un-ignored in both configs, fixed glib/libiconv/pcre2 transitive deps - greeter config: removed stale keymapd dependency from display/greeter services - prefix toolchain: relibc headers synced, _RELIBC_STDLIB_H guard unified Unfixable (diagnosed, upstream): - i2c-hidd: abort on no-I2C-hardware (QEMU) — process::exit → relibc abort - kded6/greeter-ui: page fault 0x8 — Qt library null deref - Thread panics fd != -1 — Rust std library on Redox - DHCP timeout / eth0 MAC — QEMU user-mode networking - hwrngd/thermald — no hardware RNG/thermal in VM - live preload allocation — BIOS memory fragmentation, continues on demand
224 lines
8.8 KiB
C++
224 lines
8.8 KiB
C++
// Copyright (C) 2016 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
|
// Qt-Security score:critical reason:enables-debug-framework
|
|
|
|
#include "qqmldebug.h"
|
|
#include "qqmldebugconnector_p.h"
|
|
#include "qqmldebugserviceinterfaces_p.h"
|
|
|
|
#include <private/qqmlengine_p.h>
|
|
#include <private/qv4compileddata_p.h>
|
|
|
|
#include <atomic>
|
|
#include <cstdio>
|
|
|
|
QT_REQUIRE_CONFIG(qml_debug);
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
#if __cplusplus >= 202002L
|
|
# define Q_ATOMIC_FLAG_INIT {}
|
|
#else
|
|
# define Q_ATOMIC_FLAG_INIT ATOMIC_FLAG_INIT // deprecated in C++20
|
|
#endif
|
|
|
|
/*!
|
|
\class QQmlDebuggingEnabler
|
|
\inmodule QtQml
|
|
\brief The QQmlDebuggingEnabler class provides methods to enable debugging or profiling.
|
|
|
|
Usually QML debugging and profiling is enabled by passing
|
|
\c{QT_ENABLE_QML_DEBUG} via CMake or \c{CONFIG+=qml_debug} via qmake when
|
|
building your application. At run time, the application generally parses
|
|
any \c{-qmljsdebugger} command line arguments to actually start debugging
|
|
or profiling.
|
|
|
|
You can instead handle these tasks manually by using the methods in this
|
|
class.
|
|
*/
|
|
|
|
Q_CONSTINIT static std::atomic_flag s_printedWarning = Q_ATOMIC_FLAG_INIT;
|
|
|
|
/*!
|
|
Enable debugging or profiling. If \a printWarning is \c{true}, print the
|
|
following warning to stderr:
|
|
|
|
\badcode
|
|
QML debugging is enabled. Only use this in a safe environment.
|
|
\endcode
|
|
|
|
This method is automatically called at startup if \c{QT_ENABLE_QML_DEBUG}
|
|
or \c{CONFIG+=qml_debug} is passed at build time.
|
|
|
|
This method needs to be called one way or another before starting a debug
|
|
connector of any kind. Otherwise the connector will refuse to start.
|
|
|
|
\sa startTcpDebugServer(), connectToLocalDebugger(), startDebugConnector()
|
|
*/
|
|
void QQmlDebuggingEnabler::enableDebugging(bool printWarning)
|
|
{
|
|
if (printWarning && !s_printedWarning.test_and_set(std::memory_order_relaxed)) {
|
|
fprintf(stderr, "QML debugging is enabled. Only use this in a safe environment.\n");
|
|
fflush(stderr); // We really want to print this warning, even if stderr is buffered
|
|
}
|
|
QQmlEnginePrivate::qml_debugging_enabled.store(true, std::memory_order_relaxed);
|
|
}
|
|
|
|
#if QT_DEPRECATED_SINCE(6, 4)
|
|
/*!
|
|
\internal
|
|
*/
|
|
QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
|
|
{
|
|
enableDebugging(printWarning);
|
|
};
|
|
#endif // QT_DEPRECATED_SINCE(6, 4)
|
|
|
|
/*!
|
|
* Retrieves the plugin keys of the debugger services provided by default. The debugger services
|
|
* enable a debug client to use a Qml/JavaScript debugger, in order to set breakpoints, pause
|
|
* execution, evaluate expressions and similar debugging tasks.
|
|
* \return List of plugin keys of default debugger services.
|
|
*/
|
|
QStringList QQmlDebuggingEnabler::debuggerServices()
|
|
{
|
|
return {QV4DebugService::s_key, QQmlEngineDebugService::s_key, QDebugMessageService::s_key};
|
|
}
|
|
|
|
/*!
|
|
* Retrieves the plugin keys of the inspector services provided by default. The inspector services
|
|
* enable a debug client to use a visual inspector tool for Qt Quick.
|
|
* \return List of plugin keys of default inspector services.
|
|
*/
|
|
QStringList QQmlDebuggingEnabler::inspectorServices()
|
|
{
|
|
return {QQmlInspectorService::s_key};
|
|
}
|
|
|
|
/*!
|
|
* Retrieves the names of the profiler services provided by default. The profiler services enable a
|
|
* debug client to use a profiler and track the time taken by various QML and JavaScript constructs,
|
|
* as well as the QtQuick SceneGraph.
|
|
* \return List of plugin keys of default profiler services.
|
|
*/
|
|
QStringList QQmlDebuggingEnabler::profilerServices()
|
|
{
|
|
return {QQmlProfilerService::s_key, QQmlEngineControlService::s_key, QDebugMessageService::s_key};
|
|
}
|
|
|
|
/*!
|
|
* Retrieves the plugin keys of the debug services designed to be used with a native debugger. The
|
|
* native debugger will communicate with these services by directly reading and writing the
|
|
* application's memory.
|
|
* \return List of plugin keys of debug services designed to be used with a native debugger.
|
|
*/
|
|
QStringList QQmlDebuggingEnabler::nativeDebuggerServices()
|
|
{
|
|
return {QQmlNativeDebugService::s_key};
|
|
}
|
|
|
|
/*!
|
|
* Restricts the services available from the debug connector. The connector will scan plugins in the
|
|
* "qmltooling" subdirectory of the default plugin path. If this function is not called before the
|
|
* debug connector is enabled, all services found that way will be available to any client. If this
|
|
* function is called, only the services with plugin keys given in \a services will be available.
|
|
*
|
|
* Use this method to disable debugger and inspector services when profiling to get better
|
|
* performance and more realistic profiles. The debugger service will put any JavaScript engine it
|
|
* connects to into interpreted mode, disabling the JIT compiler.
|
|
*
|
|
* \sa debuggerServices(), profilerServices(), inspectorServices()
|
|
*/
|
|
void QQmlDebuggingEnabler::setServices(const QStringList &services)
|
|
{
|
|
QQmlDebugConnector::setServices(services);
|
|
}
|
|
|
|
/*!
|
|
* \enum QQmlDebuggingEnabler::StartMode
|
|
*
|
|
* Defines the debug connector's start behavior. You can interrupt QML engines starting while a
|
|
* debug client is connecting, in order to set breakpoints in or profile startup code.
|
|
*
|
|
* \value DoNotWaitForClient Run any QML engines as usual while the debug services are connecting.
|
|
* \value WaitForClient If a QML engine starts while the debug services are connecting,
|
|
* interrupt it until they are done.
|
|
*/
|
|
|
|
/*!
|
|
* Enables debugging for QML engines created after calling this function. The debug connector will
|
|
* listen on \a port at \a hostName and block the QML engine until it receives a connection if
|
|
* \a mode is \c WaitForClient. If \a mode is not specified it won't block and if \a hostName is not
|
|
* specified it will listen on all available interfaces. You can only start one debug connector at a
|
|
* time. A debug connector may have already been started if the -qmljsdebugger= command line
|
|
* argument was given. This method returns \c true if a new debug connector was successfully
|
|
* started, or \c false otherwise.
|
|
*/
|
|
bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const QString &hostName)
|
|
{
|
|
QVariantHash configuration;
|
|
configuration[QLatin1String("portFrom")] = configuration[QLatin1String("portTo")] = port;
|
|
configuration[QLatin1String("block")] = (mode == WaitForClient);
|
|
configuration[QLatin1String("hostAddress")] = hostName;
|
|
return startDebugConnector(QLatin1String("QQmlDebugServer"), configuration);
|
|
}
|
|
|
|
/*!
|
|
* \since 5.6
|
|
*
|
|
* Enables debugging for QML engines created after calling this function. The debug connector will
|
|
* connect to a debugger waiting on a local socket at the given \a socketFileName and block the QML
|
|
* engine until the connection is established if \a mode is \c WaitForClient. If \a mode is not
|
|
* specified it will not block. You can only start one debug connector at a time. A debug connector
|
|
* may have already been started if the -qmljsdebugger= command line argument was given. This method
|
|
* returns \c true if a new debug connector was successfully started, or \c false otherwise.
|
|
*/
|
|
bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, StartMode mode)
|
|
{
|
|
QVariantHash configuration;
|
|
configuration[QLatin1String("fileName")] = socketFileName;
|
|
configuration[QLatin1String("block")] = (mode == WaitForClient);
|
|
return startDebugConnector(QLatin1String("QQmlDebugServer"), configuration);
|
|
}
|
|
|
|
/*!
|
|
* \since 5.7
|
|
*
|
|
* Enables debugging for QML engines created after calling this function. A debug connector plugin
|
|
* specified by \a pluginName will be loaded and started using the given \a configuration. Supported
|
|
* configuration entries and their semantics depend on the plugin being loaded. You can only start
|
|
* one debug connector at a time. A debug connector may have already been started if the
|
|
* -qmljsdebugger= command line argument was given. This method returns \c true if a new debug
|
|
* connector was successfully started, or \c false otherwise.
|
|
*/
|
|
bool QQmlDebuggingEnabler::startDebugConnector(const QString &pluginName,
|
|
const QVariantHash &configuration)
|
|
{
|
|
QQmlDebugConnector::setPluginKey(pluginName);
|
|
QQmlDebugConnector *connector = QQmlDebugConnector::instance();
|
|
return connector ? connector->open(configuration) : false;
|
|
}
|
|
|
|
enum { HookCount = 4 };
|
|
|
|
// Only add to the end, and bump version if you do.
|
|
quintptr Q_QML_EXPORT qtDeclarativeHookData[] = {
|
|
// Version of this Array. Bump if you add to end.
|
|
2,
|
|
|
|
// Number of entries in this array.
|
|
HookCount,
|
|
|
|
// TypeInformationVersion, an integral value, bumped whenever private
|
|
// object sizes or member offsets that are used in Qt Creator's
|
|
// data structure "pretty printing" change.
|
|
4,
|
|
|
|
// Version of the cache data.
|
|
QV4_DATA_STRUCTURE_VERSION
|
|
};
|
|
|
|
Q_STATIC_ASSERT(HookCount == sizeof(qtDeclarativeHookData) / sizeof(qtDeclarativeHookData[0]));
|
|
|
|
QT_END_NAMESPACE
|