1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qqmldebug.h"
41#include "qqmldebugconnector_p.h"
42#include "qqmldebugserviceinterfaces_p.h"
43
44#include <private/qqmlengine_p.h>
45#include <private/qv4compileddata_p.h>
46
47#include <cstdio>
48
49QT_REQUIRE_CONFIG(qml_debug);
50
51QT_BEGIN_NAMESPACE
52
53QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
54{
55 if (!QQmlEnginePrivate::qml_debugging_enabled && printWarning)
56 fprintf(stderr, format: "QML debugging is enabled. Only use this in a safe environment.\n");
57 QQmlEnginePrivate::qml_debugging_enabled = true;
58}
59
60/*!
61 * Retrieves the plugin keys of the debugger services provided by default. The debugger services
62 * enable a debug client to use a Qml/JavaScript debugger, in order to set breakpoints, pause
63 * execution, evaluate expressions and similar debugging tasks.
64 * \return List of plugin keys of default debugger services.
65 */
66QStringList QQmlDebuggingEnabler::debuggerServices()
67{
68 return {QV4DebugService::s_key, QQmlEngineDebugService::s_key, QDebugMessageService::s_key};
69}
70
71/*!
72 * Retrieves the plugin keys of the inspector services provided by default. The inspector services
73 * enable a debug client to use a visual inspector tool for Qt Quick.
74 * \return List of plugin keys of default inspector services.
75 */
76QStringList QQmlDebuggingEnabler::inspectorServices()
77{
78 return {QQmlInspectorService::s_key};
79}
80
81/*!
82 * Retrieves the names of the profiler services provided by default. The profiler services enable a
83 * debug client to use a profiler and track the time taken by various QML and JavaScript constructs,
84 * as well as the QtQuick SceneGraph.
85 * \return List of plugin keys of default profiler services.
86 */
87QStringList QQmlDebuggingEnabler::profilerServices()
88{
89 return {QQmlProfilerService::s_key, QQmlEngineControlService::s_key, QDebugMessageService::s_key};
90}
91
92/*!
93 * Retrieves the plugin keys of the debug services designed to be used with a native debugger. The
94 * native debugger will communicate with these services by directly reading and writing the
95 * application's memory.
96 * \return List of plugin keys of debug services designed to be used with a native debugger.
97 */
98QStringList QQmlDebuggingEnabler::nativeDebuggerServices()
99{
100 return {QQmlNativeDebugService::s_key};
101}
102
103/*!
104 * Restricts the services available from the debug connector. The connector will scan plugins in the
105 * "qmltooling" subdirectory of the default plugin path. If this function is not called before the
106 * debug connector is enabled, all services found that way will be available to any client. If this
107 * function is called, only the services with plugin keys given in \a services will be available.
108 *
109 * Use this method to disable debugger and inspector services when profiling to get better
110 * performance and more realistic profiles. The debugger service will put any JavaScript engine it
111 * connects to into interpreted mode, disabling the JIT compiler.
112 *
113 * \sa debuggerServices(), profilerServices(), inspectorServices()
114 */
115void QQmlDebuggingEnabler::setServices(const QStringList &services)
116{
117 QQmlDebugConnector::setServices(services);
118}
119
120/*!
121 * \enum QQmlDebuggingEnabler::StartMode
122 *
123 * Defines the debug connector's start behavior. You can interrupt QML engines starting while a
124 * debug client is connecting, in order to set breakpoints in or profile startup code.
125 *
126 * \value DoNotWaitForClient Run any QML engines as usual while the debug services are connecting.
127 * \value WaitForClient If a QML engine starts while the debug services are connecting,
128 * interrupt it until they are done.
129 */
130
131/*!
132 * Enables debugging for QML engines created after calling this function. The debug connector will
133 * listen on \a port at \a hostName and block the QML engine until it receives a connection if
134 * \a mode is \c WaitForClient. If \a mode is not specified it won't block and if \a hostName is not
135 * specified it will listen on all available interfaces. You can only start one debug connector at a
136 * time. A debug connector may have already been started if the -qmljsdebugger= command line
137 * argument was given. This method returns \c true if a new debug connector was successfully
138 * started, or \c false otherwise.
139 */
140bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const QString &hostName)
141{
142 QVariantHash configuration;
143 configuration[QLatin1String("portFrom")] = configuration[QLatin1String("portTo")] = port;
144 configuration[QLatin1String("block")] = (mode == WaitForClient);
145 configuration[QLatin1String("hostAddress")] = hostName;
146 return startDebugConnector(pluginName: QLatin1String("QQmlDebugServer"), configuration);
147}
148
149/*!
150 * \since 5.6
151 *
152 * Enables debugging for QML engines created after calling this function. The debug connector will
153 * connect to a debugger waiting on a local socket at the given \a socketFileName and block the QML
154 * engine until the connection is established if \a mode is \c WaitForClient. If \a mode is not
155 * specified it will not block. You can only start one debug connector at a time. A debug connector
156 * may have already been started if the -qmljsdebugger= command line argument was given. This method
157 * returns \c true if a new debug connector was successfully started, or \c false otherwise.
158 */
159bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, StartMode mode)
160{
161 QVariantHash configuration;
162 configuration[QLatin1String("fileName")] = socketFileName;
163 configuration[QLatin1String("block")] = (mode == WaitForClient);
164 return startDebugConnector(pluginName: QLatin1String("QQmlDebugServer"), configuration);
165}
166
167/*!
168 * \since 5.7
169 *
170 * Enables debugging for QML engines created after calling this function. A debug connector plugin
171 * specified by \a pluginName will be loaded and started using the given \a configuration. Supported
172 * configuration entries and their semantics depend on the plugin being loaded. You can only start
173 * one debug connector at a time. A debug connector may have already been started if the
174 * -qmljsdebugger= command line argument was given. This method returns \c true if a new debug
175 * connector was successfully started, or \c false otherwise.
176 */
177bool QQmlDebuggingEnabler::startDebugConnector(const QString &pluginName,
178 const QVariantHash &configuration)
179{
180 QQmlDebugConnector::setPluginKey(pluginName);
181 QQmlDebugConnector *connector = QQmlDebugConnector::instance();
182 return connector ? connector->open(configuration) : false;
183}
184
185enum { HookCount = 4 };
186
187// Only add to the end, and bump version if you do.
188quintptr Q_QML_EXPORT qtDeclarativeHookData[] = {
189 // Version of this Array. Bump if you add to end.
190 2,
191
192 // Number of entries in this array.
193 HookCount,
194
195 // TypeInformationVersion, an integral value, bumped whenever private
196 // object sizes or member offsets that are used in Qt Creator's
197 // data structure "pretty printing" change.
198 3,
199
200 // Version of the cache data.
201 QV4_DATA_STRUCTURE_VERSION
202};
203
204Q_STATIC_ASSERT(HookCount == sizeof(qtDeclarativeHookData) / sizeof(qtDeclarativeHookData[0]));
205
206QT_END_NAMESPACE
207

source code of qtdeclarative/src/qml/debugger/qqmldebug.cpp