Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Marco Bubke
flatpak-qt-creator
Commits
17a2f671
Commit
17a2f671
authored
Jun 09, 2010
by
hjk
Browse files
debugger: start second shot at Qml debugging
parent
035cfd55
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/plugins/debugger/debugger.pro
View file @
17a2f671
...
...
@@ -109,6 +109,7 @@ include(cdb/cdb.pri)
include
(
gdb
/
gdb
.
pri
)
include
(
script
/
script
.
pri
)
include
(
pdb
/
pdb
.
pri
)
include
(
qml
/
qml
.
pri
)
include
(
tcf
/
tcf
.
pri
)
include
(
shared
/
shared
.
pri
)
...
...
src/plugins/debugger/debuggermanager.cpp
View file @
17a2f671
...
...
@@ -160,6 +160,7 @@ IDebuggerEngine *createGdbEngine(DebuggerManager *parent);
IDebuggerEngine
*
createScriptEngine
(
DebuggerManager
*
parent
);
IDebuggerEngine
*
createPdbEngine
(
DebuggerManager
*
parent
);
IDebuggerEngine
*
createTcfEngine
(
DebuggerManager
*
parent
);
IDebuggerEngine
*
createQmlEngine
(
DebuggerManager
*
parent
);
// The createCdbEngine function takes a list of options pages it can add to.
// This allows for having a "enabled" toggle on the page independently
...
...
@@ -254,6 +255,7 @@ static Debugger::Internal::IDebuggerEngine *gdbEngine = 0;
static
Debugger
::
Internal
::
IDebuggerEngine
*
scriptEngine
=
0
;
static
Debugger
::
Internal
::
IDebuggerEngine
*
cdbEngine
=
0
;
static
Debugger
::
Internal
::
IDebuggerEngine
*
pdbEngine
=
0
;
static
Debugger
::
Internal
::
IDebuggerEngine
*
qmlEngine
=
0
;
static
Debugger
::
Internal
::
IDebuggerEngine
*
tcfEngine
=
0
;
struct
DebuggerManagerPrivate
...
...
@@ -351,6 +353,7 @@ DebuggerManager::~DebuggerManager()
doDelete
(
gdbEngine
);
doDelete
(
cdbEngine
);
doDelete
(
tcfEngine
);
doDelete
(
qmlEngine
);
doDelete
(
d
->
m_breakHandler
);
doDelete
(
d
->
m_threadsHandler
);
...
...
@@ -359,11 +362,6 @@ DebuggerManager::~DebuggerManager()
doDelete
(
d
->
m_snapshotHandler
);
doDelete
(
d
->
m_stackHandler
);
doDelete
(
d
->
m_watchHandler
);
doDelete
(
gdbEngine
);
doDelete
(
scriptEngine
);
doDelete
(
cdbEngine
);
doDelete
(
tcfEngine
);
# undef doDelete
DebuggerManagerPrivate
::
instance
=
0
;
delete
d
;
...
...
@@ -692,6 +690,11 @@ QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(unsigned enabledTy
tcfEngine
->
addOptionPages
(
&
rc
);
}
if
(
enabledTypeFlags
&
QmlEngineType
)
{
qmlEngine
=
createQmlEngine
(
this
);
//qmlEngine->addOptionPages(&rc);
}
d
->
m_engine
=
0
;
STATE_DEBUG
(
gdbEngine
<<
cdbEngine
<<
scriptEngine
<<
pdbEngine
<<
rc
.
size
());
...
...
@@ -976,6 +979,15 @@ static IDebuggerEngine *debuggerEngineForExecutable(const QString &executable,
QString
*
errorMessage
,
QString
*
settingsIdHint
)
{
if
(
executable
.
endsWith
(
_
(
"qmlviewer"
)))
{
qDebug
()
<<
"HERE"
;
if
(
!
qmlEngine
)
{
*
errorMessage
=
msgEngineNotAvailable
(
"Qml Engine"
);
return
0
;
}
return
qmlEngine
;
}
if
(
executable
.
endsWith
(
_
(
".js"
)))
{
if
(
!
scriptEngine
)
{
*
errorMessage
=
msgEngineNotAvailable
(
"Script Engine"
);
...
...
@@ -1016,7 +1028,8 @@ static IDebuggerEngine *debuggerEngineForExecutable(const QString &executable,
// We need the CDB debugger in order to be able to debug VS
// executables
if
(
!
DebuggerManager
::
instance
()
->
checkDebugConfiguration
(
ProjectExplorer
::
ToolChain
::
MSVC
,
errorMessage
,
0
,
settingsIdHint
))
if
(
!
DebuggerManager
::
instance
()
->
checkDebugConfiguration
(
ProjectExplorer
::
ToolChain
::
MSVC
,
errorMessage
,
0
,
settingsIdHint
))
return
0
;
return
cdbEngine
;
#endif
...
...
@@ -1049,6 +1062,7 @@ static IDebuggerEngine *debuggerEngineForMode(DebuggerStartMode startMode, QStri
void
DebuggerManager
::
startNewDebugger
(
const
DebuggerStartParametersPtr
&
sp
)
{
qDebug
()
<<
"TARGET: "
<<
sp
->
executable
;
if
(
d
->
m_state
!=
DebuggerNotReady
)
return
;
d
->
m_startParameters
=
sp
;
...
...
@@ -1067,7 +1081,9 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp)
// Figure out engine: toolchain, executable, attach or default
const
DebuggerStartMode
startMode
=
sp
->
startMode
;
if
(
sp
->
executable
.
endsWith
(
_
(
".js"
)))
if
(
sp
->
executable
.
endsWith
(
_
(
"qmlviewer"
)))
d
->
m_engine
=
qmlEngine
;
else
if
(
sp
->
executable
.
endsWith
(
_
(
".js"
)))
d
->
m_engine
=
scriptEngine
;
else
if
(
sp
->
executable
.
endsWith
(
_
(
".py"
)))
d
->
m_engine
=
pdbEngine
;
...
...
src/plugins/debugger/debuggermanager.h
View file @
17a2f671
...
...
@@ -95,6 +95,7 @@ class CdbDumperInitThread;
class
CdbExceptionLoggerEventCallback
;
class
GdbEngine
;
class
TcfEngine
;
class
QmlEngine
;
class
CdbDebugEngine
;
class
CdbDebugEnginePrivate
;
class
TrkGdbAdapter
;
...
...
@@ -145,11 +146,13 @@ enum DebuggerEngineTypeFlags
CdbEngineType
=
0x04
,
PdbEngineType
=
0x08
,
TcfEngineType
=
0x10
,
QmlEngineType
=
0x20
,
AllEngineTypes
=
GdbEngineType
|
ScriptEngineType
|
CdbEngineType
|
PdbEngineType
|
TcfEngineType
|
QmlEngineType
};
QDebug
operator
<<
(
QDebug
d
,
DebuggerState
state
);
...
...
@@ -178,6 +181,7 @@ public:
friend
class
Internal
::
ScriptEngine
;
friend
class
Internal
::
PdbEngine
;
friend
class
Internal
::
TcfEngine
;
friend
class
Internal
::
QmlEngine
;
friend
class
Internal
::
CdbDebugEngine
;
friend
class
Internal
::
CdbDebugEnginePrivate
;
friend
class
Internal
::
TrkGdbAdapter
;
...
...
src/plugins/debugger/debuggerplugin.cpp
View file @
17a2f671
...
...
@@ -637,11 +637,15 @@ static bool parseArgument(QStringList::const_iterator &it,
*
enabledEngines
&=
~
Debugger
::
GdbEngineType
;
return
true
;
}
if
(
option
==
_
(
"-disable-qmldb"
))
{
*
enabledEngines
&=
~
Debugger
::
QmlEngineType
;
return
true
;
}
if
(
option
==
_
(
"-disable-sdb"
))
{
*
enabledEngines
&=
~
Debugger
::
ScriptEngineType
;
return
true
;
}
if
(
option
==
QLatin1String
(
"-disable-tcf"
))
{
if
(
option
==
_
(
"-disable-tcf"
))
{
*
enabledEngines
&=
~
TcfEngineType
;
return
true
;
}
...
...
@@ -1358,7 +1362,6 @@ void DebuggerPlugin::languageChanged(const QString &language)
m_attachCoreAction
->
setVisible
(
debuggerIsCPP
);
m_startRemoteAction
->
setVisible
(
debuggerIsCPP
);
m_detachAction
->
setVisible
(
debuggerIsCPP
);
}
void
DebuggerPlugin
::
writeSettings
()
const
...
...
@@ -1398,12 +1401,9 @@ void DebuggerPlugin::onModeChanged(IMode *mode)
if
(
isCurrentProjectCppBased
())
m_uiSwitcher
->
setActiveLanguage
(
LANG_CPP
);
}
}
void
DebuggerPlugin
::
showSettingsDialog
()
{
Core
::
ICore
::
instance
()
->
showOptionsDialog
(
...
...
src/plugins/debugger/debuggerrunner.cpp
View file @
17a2f671
...
...
@@ -48,6 +48,7 @@
namespace
Debugger
{
namespace
Internal
{
using
ProjectExplorer
::
BuildConfiguration
;
using
ProjectExplorer
::
RunConfiguration
;
using
ProjectExplorer
::
RunControl
;
using
ProjectExplorer
::
LocalApplicationRunConfiguration
;
...
...
@@ -65,6 +66,7 @@ DebuggerRunControlFactory::DebuggerRunControlFactory(DebuggerManager *manager)
bool
DebuggerRunControlFactory
::
canRun
(
RunConfiguration
*
runConfiguration
,
const
QString
&
mode
)
const
{
// return mode == ProjectExplorer::Constants::DEBUGMODE;
return
mode
==
ProjectExplorer
::
Constants
::
DEBUGMODE
&&
qobject_cast
<
LocalApplicationRunConfiguration
*>
(
runConfiguration
);
}
...
...
@@ -130,8 +132,9 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
break
;
}
if
(
runConfiguration
->
target
()
->
project
())
{
m_startParameters
->
buildDirectory
=
runConfiguration
->
target
()
->
activeBuildConfiguration
()
->
buildDirectory
();
BuildConfiguration
*
bc
=
runConfiguration
->
target
()
->
activeBuildConfiguration
();
if
(
bc
)
m_startParameters
->
buildDirectory
=
bc
->
buildDirectory
();
}
m_startParameters
->
useTerminal
=
runConfiguration
->
runMode
()
==
LocalApplicationRunConfiguration
::
Console
;
...
...
src/plugins/debugger/qml/qml.pri
0 → 100644
View file @
17a2f671
HEADERS += \
$$PWD/qmlengine.h \
SOURCES += \
$$PWD/qmlengine.cpp \
FORMS +=
RESOURCES +=
src/plugins/debugger/qml/qmlengine.cpp
0 → 100644
View file @
17a2f671
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include
"qmlengine.h"
#include
"debuggerstringutils.h"
#include
"debuggerdialogs.h"
#include
"breakhandler.h"
#include
"debuggerconstants.h"
#include
"debuggermanager.h"
#include
"moduleshandler.h"
#include
"registerhandler.h"
#include
"stackhandler.h"
#include
"watchhandler.h"
#include
"watchutils.h"
#include
"moduleshandler.h"
#include
<utils/qtcassert.h>
#include
<QtCore/QDateTime>
#include
<QtCore/QDebug>
#include
<QtCore/QDir>
#include
<QtCore/QFileInfo>
#include
<QtCore/QTimer>
#include
<QtGui/QAction>
#include
<QtGui/QApplication>
#include
<QtGui/QMainWindow>
#include
<QtGui/QMessageBox>
#include
<QtGui/QToolTip>
#include
<QtNetwork/QTcpSocket>
#define DEBUG_QML 1
#if DEBUG_QML
# define SDEBUG(s) qDebug() << s
#else
# define SDEBUG(s)
#endif
# define XSDEBUG(s) qDebug() << s
#define CB(callback) &QmlEngine::callback, STRINGIFY(callback)
//#define USE_CONGESTION_CONTROL
namespace
Debugger
{
namespace
Internal
{
class
QmlResponse
{
public:
QmlResponse
()
{}
QmlResponse
(
const
QByteArray
&
data_
)
:
data
(
data_
)
{}
QString
toString
()
const
{
return
data
;
}
QByteArray
data
;
};
///////////////////////////////////////////////////////////////////////
//
// QmlCommand
//
///////////////////////////////////////////////////////////////////////
QString
QmlEngine
::
QmlCommand
::
toString
()
const
{
return
quoteUnprintableLatin1
(
command
);
}
///////////////////////////////////////////////////////////////////////
//
// QmlEngine
//
///////////////////////////////////////////////////////////////////////
QmlEngine
::
QmlEngine
(
DebuggerManager
*
manager
)
:
IDebuggerEngine
(
manager
)
{
m_congestion
=
0
;
m_inAir
=
0
;
m_sendTimer
.
setSingleShot
(
true
);
m_sendTimer
.
setInterval
(
100
);
// ms
connect
(
&
m_sendTimer
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
handleSendTimer
()));
m_socket
=
new
QTcpSocket
(
this
);
connect
(
m_socket
,
SIGNAL
(
connected
()),
this
,
SLOT
(
socketConnected
()));
connect
(
m_socket
,
SIGNAL
(
disconnected
()),
this
,
SLOT
(
socketDisconnected
()));
connect
(
m_socket
,
SIGNAL
(
error
(
QAbstractSocket
::
SocketError
)),
this
,
SLOT
(
socketError
(
QAbstractSocket
::
SocketError
)));
//void aboutToClose ()
//void bytesWritten ( qint64 bytes )
//void readChannelFinished ()
connect
(
m_socket
,
SIGNAL
(
readyRead
()),
this
,
SLOT
(
socketReadyRead
()));
//connect(m_socket, SIGNAL(hostFound())
//connect(m_socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy, QAuthenticator *)))
//connect(m_socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
// thism SLOT(socketStateChanged(QAbstractSocket::SocketState)));
}
QmlEngine
::~
QmlEngine
()
{
}
void
QmlEngine
::
socketReadyRead
()
{
//XSDEBUG("QmlEngine::socketReadyRead()");
m_inbuffer
.
append
(
m_socket
->
readAll
());
int
pos
=
0
;
while
(
1
)
{
// the "\3" is followed by either "\1" or "\2"
int
next
=
m_inbuffer
.
indexOf
(
"
\3
"
,
pos
);
//qDebug() << "pos: " << pos << "next: " << next;
if
(
next
==
-
1
)
break
;
handleResponse
(
m_inbuffer
.
mid
(
pos
,
next
-
pos
));
pos
=
next
+
2
;
}
m_inbuffer
.
clear
();
}
void
QmlEngine
::
socketConnected
()
{
showStatusMessage
(
"Socket connected."
);
m_socket
->
waitForConnected
(
2000
);
//sendCommand("Locator", "redirect", "ID");
}
void
QmlEngine
::
socketDisconnected
()
{
XSDEBUG
(
"FIXME: QmlEngine::socketDisconnected()"
);
}
void
QmlEngine
::
socketError
(
QAbstractSocket
::
SocketError
)
{
QString
msg
=
tr
(
"%1."
).
arg
(
m_socket
->
errorString
());
//QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
showStatusMessage
(
msg
);
manager
()
->
notifyInferiorExited
();
}
void
QmlEngine
::
executeDebuggerCommand
(
const
QString
&
command
)
{
QByteArray
cmd
=
command
.
toUtf8
();
cmd
=
cmd
.
mid
(
cmd
.
indexOf
(
' '
)
+
1
);
QByteArray
null
;
null
.
append
(
'\0'
);
// FIXME: works for single-digit escapes only
cmd
.
replace
(
"
\\
0"
,
null
);
cmd
.
replace
(
"
\\
1"
,
"
\1
"
);
cmd
.
replace
(
"
\\
3"
,
"
\3
"
);
QmlCommand
tcf
;
tcf
.
command
=
cmd
;
enqueueCommand
(
tcf
);
}
void
QmlEngine
::
shutdown
()
{
m_congestion
=
0
;
m_inAir
=
0
;
m_services
.
clear
();
exitDebugger
();
}
void
QmlEngine
::
exitDebugger
()
{
SDEBUG
(
"QmlEngine::exitDebugger()"
);
manager
()
->
notifyInferiorExited
();
}
void
QmlEngine
::
startDebugger
(
const
DebuggerStartParametersPtr
&
sp
)
{
qDebug
()
<<
"STARTING QML ENGINE"
;
setState
(
InferiorRunningRequested
);
showStatusMessage
(
tr
(
"Running requested..."
),
5000
);
const
int
pos
=
sp
->
remoteChannel
.
indexOf
(
QLatin1Char
(
':'
));
const
QString
host
=
sp
->
remoteChannel
.
left
(
pos
);
const
quint16
port
=
sp
->
remoteChannel
.
mid
(
pos
+
1
).
toInt
();
//QTimer::singleShot(0, this, SLOT(runInferior()));
m_socket
->
connectToHost
(
host
,
port
);
emit
startSuccessful
();
}
void
QmlEngine
::
continueInferior
()
{
SDEBUG
(
"QmlEngine::continueInferior()"
);
}
void
QmlEngine
::
runInferior
()
{
}
void
QmlEngine
::
interruptInferior
()
{
XSDEBUG
(
"QmlEngine::interruptInferior()"
);
}
void
QmlEngine
::
executeStep
()
{
//SDEBUG("QmlEngine::executeStep()");
}
void
QmlEngine
::
executeStepI
()
{
//SDEBUG("QmlEngine::executeStepI()");
}
void
QmlEngine
::
executeStepOut
()
{
//SDEBUG("QmlEngine::executeStepOut()");
}
void
QmlEngine
::
executeNext
()
{
//SDEBUG("QmlEngine::nextExec()");
}
void
QmlEngine
::
executeNextI
()
{
//SDEBUG("QmlEngine::executeNextI()");
}
void
QmlEngine
::
executeRunToLine
(
const
QString
&
fileName
,
int
lineNumber
)
{
Q_UNUSED
(
fileName
)
Q_UNUSED
(
lineNumber
)
SDEBUG
(
"FIXME: QmlEngine::executeRunToLine()"
);
}
void
QmlEngine
::
executeRunToFunction
(
const
QString
&
functionName
)
{
Q_UNUSED
(
functionName
)
XSDEBUG
(
"FIXME: QmlEngine::executeRunToFunction()"
);
}
void
QmlEngine
::
executeJumpToLine
(
const
QString
&
fileName
,
int
lineNumber
)
{
Q_UNUSED
(
fileName
)
Q_UNUSED
(
lineNumber
)
XSDEBUG
(
"FIXME: QmlEngine::executeJumpToLine()"
);
}
void
QmlEngine
::
activateFrame
(
int
index
)
{
Q_UNUSED
(
index
)
}
void
QmlEngine
::
selectThread
(
int
index
)
{
Q_UNUSED
(
index
)
}
void
QmlEngine
::
attemptBreakpointSynchronization
()
{
}
void
QmlEngine
::
loadSymbols
(
const
QString
&
moduleName
)
{
Q_UNUSED
(
moduleName
)
}
void
QmlEngine
::
loadAllSymbols
()
{
}
void
QmlEngine
::
reloadModules
()
{
}
void
QmlEngine
::
requestModuleSymbols
(
const
QString
&
moduleName
)
{
Q_UNUSED
(
moduleName
)
}
void
QmlEngine
::
handleResponse
(
const
QByteArray
&
response
)
{
Q_UNUSED
(
response
);
/*
static QTime lastTime;
//debugMessage(_(" "), currentTime());
QList<QByteArray> parts = response.split('\0');
if (parts.size() < 2 || !parts.last().isEmpty()) {
SDEBUG("WRONG RESPONSE PACKET LAYOUT" << parts);
//if (response.isEmpty())
acknowledgeResult();
return;
}
parts.removeLast(); // always empty
QByteArray tag = parts.at(0);
int n = parts.size();
if (n == 2 && tag == "N") { // unidentified command
int token = parts.at(1).toInt();
QmlCommand tcf = m_cookieForToken[token];
SDEBUG("COMMAND NOT RECOGNIZED FOR TOKEN" << token << tcf.toString());
showDebuggerOutput(LogOutput, QString::number(token) + "^"
+ "NOT RECOQNIZED: " + quoteUnprintableLatin1(response));
acknowledgeResult();
} else if (n == 2 && tag == "F") { // flow control
m_congestion = parts.at(1).toInt();
SDEBUG("CONGESTION: " << m_congestion);
} else if (n == 4 && tag == "R") { // result data
acknowledgeResult();
int token = parts.at(1).toInt();
QByteArray message = parts.at(2);
QmlResponse data(parts.at(3));
showDebuggerOutput(LogOutput, QString("%1^%2%3").arg(token)
.arg(quoteUnprintableLatin1(response))
.arg(QString::fromUtf8(data.toString())));
QmlCommand tcf = m_cookieForToken[token];
QmlResponse result(data);
SDEBUG("GOOD RESPONSE: " << quoteUnprintableLatin1(response));
if (tcf.callback)
(this->*(tcf.callback))(result, tcf.cookie);
} else if (n == 3 && tag == "P") { // progress data (partial result)
//int token = parts.at(1).toInt();
QByteArray data = parts.at(2);
SDEBUG(_("\nTCF PARTIAL:") << quoteUnprintableLatin1(response));
} else if (n == 4 && tag == "E") { // an event
QByteArray service = parts.at(1);
QByteArray eventName = parts.at(2);
QmlResponse data(parts.at(3));
if (eventName != "peerHeartBeat")
SDEBUG(_("\nTCF EVENT:") << quoteUnprintableLatin1(response)
<< data.toString());
if (service == "Locator" && eventName == "Hello") {
m_services.clear();
foreach (const QmlResponse &service, data.children())
m_services.append(service.data());
QTimer::singleShot(0, this, SLOT(startDebugging()));
}
} else {
SDEBUG("UNKNOWN RESPONSE PACKET:"
<< quoteUnprintableLatin1(response) << parts);
}
*/
}
void
QmlEngine
::
startDebugging
()
{
qDebug
()
<<
"START"
;
}
void
QmlEngine
::
postCommand
(
const
QByteArray
&
cmd
,
QmlCommandCallback
callback
,
const
char
*
callbackName
)
{
/*
static int token = 20;
++token;
//const char marker_eom = -1;
//const char marker_eos = -2;
//const char marker_null = -3;
QByteArray ba = "C";
ba.append('\0');
ba.append(QByteArray::number(token));
ba.append('\0');
ba.append(cmd);
ba.append('\0');
ba.append('\3');
ba.append('\1');
QmlCommand tcf;
tcf.command = ba;
tcf.callback = callback;
tcf.callbackName = callbackName;
tcf.token = token;
m_cookieForToken[token] = tcf;
enqueueCommand(tcf);
*/
}
// Congestion control does not seem to work that way. Basically it's
// already too late when we get a flow control packet
void
QmlEngine
::
enqueueCommand
(
const
QmlCommand
&
cmd
)
{
/*
#ifdef USE_CONGESTION_CONTROL