forked from qt-creator/qt-creator
JSDebugger: Enable break on events.
The user can request Javascript break on event. The user can provide this info in the Breakpoints Window and provide the slot which will be called when the event occurs. For example: specify "onTriggered" if you need to break on Timer triggered event. Change-Id: If936d7402f5978a182132fdcca75515588364e16 Reviewed-on: http://codereview.qt-project.org/4758 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
This commit is contained in:
@@ -122,6 +122,8 @@ static QString typeToString(BreakpointType type)
|
|||||||
return BreakHandler::tr("Watchpoint at Address");
|
return BreakHandler::tr("Watchpoint at Address");
|
||||||
case WatchpointAtExpression:
|
case WatchpointAtExpression:
|
||||||
return BreakHandler::tr("Watchpoint at Expression");
|
return BreakHandler::tr("Watchpoint at Expression");
|
||||||
|
case BreakpointOnSignalHandler:
|
||||||
|
return BreakHandler::tr("Breakpoint on Signal Handler");
|
||||||
case UnknownType:
|
case UnknownType:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ QString BreakpointParameters::toString() const
|
|||||||
<< " PathUsage: " << pathUsage;
|
<< " PathUsage: " << pathUsage;
|
||||||
break;
|
break;
|
||||||
case BreakpointByFunction:
|
case BreakpointByFunction:
|
||||||
|
case BreakpointOnSignalHandler:
|
||||||
ts << " FunctionName: " << functionName;
|
ts << " FunctionName: " << functionName;
|
||||||
break;
|
break;
|
||||||
case BreakpointByAddress:
|
case BreakpointByAddress:
|
||||||
|
|||||||
@@ -139,7 +139,8 @@ enum BreakpointType
|
|||||||
//BreakpointAtVFork,
|
//BreakpointAtVFork,
|
||||||
BreakpointAtSysCall,
|
BreakpointAtSysCall,
|
||||||
WatchpointAtAddress,
|
WatchpointAtAddress,
|
||||||
WatchpointAtExpression
|
WatchpointAtExpression,
|
||||||
|
BreakpointOnSignalHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \enum Debugger::Internal::BreakpointState
|
//! \enum Debugger::Internal::BreakpointState
|
||||||
|
|||||||
@@ -119,8 +119,10 @@ BreakpointDialog::BreakpointDialog(unsigned engineCapabilities, QWidget *parent)
|
|||||||
<< tr("Break when a new process is executed")
|
<< tr("Break when a new process is executed")
|
||||||
<< tr("Break when a system call is executed")
|
<< tr("Break when a system call is executed")
|
||||||
<< tr("Break on data access at fixed address")
|
<< tr("Break on data access at fixed address")
|
||||||
<< tr("Break on data access at address given by expression");
|
<< tr("Break on data access at address given by expression")
|
||||||
QTC_ASSERT(types.size() == WatchpointAtExpression, return; )
|
<< tr("Break on QML signal handler");
|
||||||
|
|
||||||
|
QTC_ASSERT(types.size() == BreakpointOnSignalHandler, return; )
|
||||||
m_ui.comboBoxType->addItems(types);
|
m_ui.comboBoxType->addItems(types);
|
||||||
m_ui.pathChooserFileName->setExpectedKind(Utils::PathChooser::File);
|
m_ui.pathChooserFileName->setExpectedKind(Utils::PathChooser::File);
|
||||||
connect(m_ui.comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int)));
|
connect(m_ui.comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int)));
|
||||||
@@ -358,6 +360,8 @@ void BreakpointDialog::typeChanged(int)
|
|||||||
case WatchpointAtExpression:
|
case WatchpointAtExpression:
|
||||||
getParts(ExpressionPart|AllConditionParts|TracePointPart, &m_savedParameters);
|
getParts(ExpressionPart|AllConditionParts|TracePointPart, &m_savedParameters);
|
||||||
break;
|
break;
|
||||||
|
case BreakpointOnSignalHandler:
|
||||||
|
getParts(FunctionPart, &m_savedParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable and set up new state from saved values.
|
// Enable and set up new state from saved values.
|
||||||
@@ -399,6 +403,10 @@ void BreakpointDialog::typeChanged(int)
|
|||||||
setPartsEnabled(ExpressionPart|AllConditionParts|TracePointPart|TracePointPart);
|
setPartsEnabled(ExpressionPart|AllConditionParts|TracePointPart|TracePointPart);
|
||||||
clearOtherParts(ExpressionPart|AllConditionParts|TracePointPart);
|
clearOtherParts(ExpressionPart|AllConditionParts|TracePointPart);
|
||||||
break;
|
break;
|
||||||
|
case BreakpointOnSignalHandler:
|
||||||
|
setParts(FunctionPart, m_savedParameters);
|
||||||
|
setPartsEnabled(FunctionPart);
|
||||||
|
clearOtherParts(FunctionPart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2552,6 +2552,7 @@ bool CdbEngine::acceptsBreakpoint(BreakpointModelId id) const
|
|||||||
case BreakpointAtFork:
|
case BreakpointAtFork:
|
||||||
case WatchpointAtExpression:
|
case WatchpointAtExpression:
|
||||||
case BreakpointAtSysCall:
|
case BreakpointAtSysCall:
|
||||||
|
case BreakpointOnSignalHandler:
|
||||||
return false;
|
return false;
|
||||||
case WatchpointAtAddress:
|
case WatchpointAtAddress:
|
||||||
case BreakpointByFileAndLine:
|
case BreakpointByFileAndLine:
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ static BreakpointParameters fixWinMSVCBreakpoint(const BreakpointParameters &p)
|
|||||||
case WatchpointAtExpression:
|
case WatchpointAtExpression:
|
||||||
case BreakpointAtSysCall:
|
case BreakpointAtSysCall:
|
||||||
case WatchpointAtAddress:
|
case WatchpointAtAddress:
|
||||||
|
case BreakpointOnSignalHandler:
|
||||||
break;
|
break;
|
||||||
case BreakpointAtExec: { // Emulate by breaking on CreateProcessW().
|
case BreakpointAtExec: { // Emulate by breaking on CreateProcessW().
|
||||||
BreakpointParameters rc(BreakpointByFunction);
|
BreakpointParameters rc(BreakpointByFunction);
|
||||||
@@ -163,6 +164,7 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
|
|||||||
case BreakpointAtCatch:
|
case BreakpointAtCatch:
|
||||||
case BreakpointAtThrow:
|
case BreakpointAtThrow:
|
||||||
case BreakpointAtMain:
|
case BreakpointAtMain:
|
||||||
|
case BreakpointOnSignalHandler:
|
||||||
QTC_ASSERT(false, return QByteArray(); )
|
QTC_ASSERT(false, return QByteArray(); )
|
||||||
break;
|
break;
|
||||||
case BreakpointByAddress:
|
case BreakpointByAddress:
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
#include "qmldebuggerclient.h"
|
#include "qmldebuggerclient.h"
|
||||||
|
#include "breakpoint.h"
|
||||||
|
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -54,6 +55,11 @@ QmlDebuggerClient::~QmlDebuggerClient()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QmlDebuggerClient::acceptsBreakpoint(const BreakpointModelId &/*id*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void QmlDebuggerClient::statusChanged(Status status)
|
void QmlDebuggerClient::statusChanged(Status status)
|
||||||
{
|
{
|
||||||
emit newStatus(status);
|
emit newStatus(status);
|
||||||
|
|||||||
@@ -65,13 +65,14 @@ public:
|
|||||||
|
|
||||||
virtual void activateFrame(int index) = 0;
|
virtual void activateFrame(int index) = 0;
|
||||||
|
|
||||||
virtual void insertBreakpoint(BreakpointModelId id) = 0;
|
virtual bool acceptsBreakpoint(const BreakpointModelId &id);
|
||||||
virtual void removeBreakpoint(BreakpointModelId id) = 0;
|
virtual void insertBreakpoint(const BreakpointModelId &id) = 0;
|
||||||
virtual void changeBreakpoint(BreakpointModelId id) = 0;
|
virtual void removeBreakpoint(const BreakpointModelId &id) = 0;
|
||||||
|
virtual void changeBreakpoint(const BreakpointModelId &id) = 0;
|
||||||
virtual void updateBreakpoints() = 0;
|
virtual void updateBreakpoints() = 0;
|
||||||
|
|
||||||
virtual void assignValueInDebugger(const QByteArray expr, const quint64 &id,
|
virtual void assignValueInDebugger(const QByteArray expr, const quint64 &id,
|
||||||
const QString &property, const QString value) = 0;
|
const QString &property, const QString &value) = 0;
|
||||||
|
|
||||||
virtual void updateWatchData(const WatchData *data) = 0;
|
virtual void updateWatchData(const WatchData *data) = 0;
|
||||||
virtual void executeDebuggerCommand(const QString &command) = 0;
|
virtual void executeDebuggerCommand(const QString &command) = 0;
|
||||||
|
|||||||
@@ -603,7 +603,18 @@ void QmlEngine::attemptBreakpointSynchronization()
|
|||||||
|
|
||||||
bool QmlEngine::acceptsBreakpoint(BreakpointModelId id) const
|
bool QmlEngine::acceptsBreakpoint(BreakpointModelId id) const
|
||||||
{
|
{
|
||||||
return !DebuggerEngine::isCppBreakpoint(breakHandler()->breakpointData(id));
|
if (!DebuggerEngine::isCppBreakpoint(breakHandler()->breakpointData(id)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
//If it is a Cpp Breakpoint query if the type can be also handled by the debugger client
|
||||||
|
//TODO: enable setting of breakpoints before start of debug session
|
||||||
|
//For now, the event breakpoint can be set after the activeDebuggerClient is known
|
||||||
|
//This is because the older client does not support BreakpointOnSignalHandler
|
||||||
|
bool acceptBreakpoint = false;
|
||||||
|
if (d->m_adapter.activeDebuggerClient()) {
|
||||||
|
acceptBreakpoint = d->m_adapter.activeDebuggerClient()->acceptsBreakpoint(id);
|
||||||
|
}
|
||||||
|
return acceptBreakpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlEngine::loadSymbols(const QString &moduleName)
|
void QmlEngine::loadSymbols(const QString &moduleName)
|
||||||
|
|||||||
@@ -312,7 +312,13 @@ void QmlV8DebuggerClient::activateFrame(int index)
|
|||||||
setLocals(index);
|
setLocals(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlV8DebuggerClient::insertBreakpoint(BreakpointModelId id)
|
bool QmlV8DebuggerClient::acceptsBreakpoint(const BreakpointModelId &id)
|
||||||
|
{
|
||||||
|
BreakpointType type = d->engine->breakHandler()->breakpointData(id).type;
|
||||||
|
return ((type == BreakpointOnSignalHandler) || (type == BreakpointByFunction));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id)
|
||||||
{
|
{
|
||||||
BreakHandler *handler = d->engine->breakHandler();
|
BreakHandler *handler = d->engine->breakHandler();
|
||||||
QByteArray request;
|
QByteArray request;
|
||||||
@@ -327,6 +333,9 @@ void QmlV8DebuggerClient::insertBreakpoint(BreakpointModelId id)
|
|||||||
} else if (handler->breakpointData(id).type == BreakpointByFunction) {
|
} else if (handler->breakpointData(id).type == BreakpointByFunction) {
|
||||||
JsonInputStream(request) << "type" << ':' << "function";
|
JsonInputStream(request) << "type" << ':' << "function";
|
||||||
JsonInputStream(request) << ',' << "target" << ':' << handler->functionName(id).toUtf8();
|
JsonInputStream(request) << ',' << "target" << ':' << handler->functionName(id).toUtf8();
|
||||||
|
} else if (handler->breakpointData(id).type == BreakpointOnSignalHandler) {
|
||||||
|
JsonInputStream(request) << "type" << ':' << "event";
|
||||||
|
JsonInputStream(request) << ',' << "target" << ':' << handler->functionName(id).toUtf8();
|
||||||
}
|
}
|
||||||
JsonInputStream(request) << '}';
|
JsonInputStream(request) << '}';
|
||||||
JsonInputStream(request) << '}';
|
JsonInputStream(request) << '}';
|
||||||
@@ -335,7 +344,7 @@ void QmlV8DebuggerClient::insertBreakpoint(BreakpointModelId id)
|
|||||||
sendMessage(packMessage(request));
|
sendMessage(packMessage(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlV8DebuggerClient::removeBreakpoint(BreakpointModelId id)
|
void QmlV8DebuggerClient::removeBreakpoint(const BreakpointModelId &id)
|
||||||
{
|
{
|
||||||
int breakpoint = d->breakpoints.value(id);
|
int breakpoint = d->breakpoints.value(id);
|
||||||
d->breakpoints.remove(id);
|
d->breakpoints.remove(id);
|
||||||
@@ -354,7 +363,7 @@ void QmlV8DebuggerClient::removeBreakpoint(BreakpointModelId id)
|
|||||||
sendMessage(packMessage(request));
|
sendMessage(packMessage(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlV8DebuggerClient::changeBreakpoint(BreakpointModelId /*id*/)
|
void QmlV8DebuggerClient::changeBreakpoint(const BreakpointModelId &/*id*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +372,7 @@ void QmlV8DebuggerClient::updateBreakpoints()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QmlV8DebuggerClient::assignValueInDebugger(const QByteArray /*expr*/, const quint64 &/*id*/,
|
void QmlV8DebuggerClient::assignValueInDebugger(const QByteArray /*expr*/, const quint64 &/*id*/,
|
||||||
const QString &/*property*/, const QString /*value*/)
|
const QString &/*property*/, const QString &/*value*/)
|
||||||
{
|
{
|
||||||
//TODO::
|
//TODO::
|
||||||
}
|
}
|
||||||
@@ -468,7 +477,7 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
ds >> response;
|
ds >> response;
|
||||||
|
|
||||||
JsonValue value(response);
|
JsonValue value(response);
|
||||||
QString type = value.findChild("type").toVariant().toString();
|
const QString type = value.findChild("type").toVariant().toString();
|
||||||
|
|
||||||
if (type == "response") {
|
if (type == "response") {
|
||||||
|
|
||||||
@@ -478,7 +487,7 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString debugCommand(value.findChild("command").toVariant().toString());
|
const QString debugCommand(value.findChild("command").toVariant().toString());
|
||||||
if (debugCommand == "backtrace") {
|
if (debugCommand == "backtrace") {
|
||||||
setStackFrames(response);
|
setStackFrames(response);
|
||||||
|
|
||||||
@@ -491,6 +500,12 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
BreakpointModelId id = d->breakpointsSync.take(sequence);
|
BreakpointModelId id = d->breakpointsSync.take(sequence);
|
||||||
d->breakpoints.insert(id,breakpoint);
|
d->breakpoints.insert(id,breakpoint);
|
||||||
|
|
||||||
|
//If this is an event breakpoint then set state = BreakpointInsertOk
|
||||||
|
const QString breakpointType = value.findChild("body").findChild("type").toVariant().toString();
|
||||||
|
if (breakpointType == "event") {
|
||||||
|
d->engine->breakHandler()->notifyBreakpointInsertOk(id);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (debugCommand == "evaluate") {
|
} else if (debugCommand == "evaluate") {
|
||||||
setExpression(response);
|
setExpression(response);
|
||||||
|
|
||||||
@@ -504,7 +519,7 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (type == "event") {
|
} else if (type == "event") {
|
||||||
QString event(value.findChild("event").toVariant().toString());
|
const QString event(value.findChild("event").toVariant().toString());
|
||||||
|
|
||||||
if (event == "break") {
|
if (event == "break") {
|
||||||
d->engine->inferiorSpontaneousStop();
|
d->engine->inferiorSpontaneousStop();
|
||||||
|
|||||||
@@ -80,13 +80,14 @@ public:
|
|||||||
|
|
||||||
void activateFrame(int index);
|
void activateFrame(int index);
|
||||||
|
|
||||||
void insertBreakpoint(BreakpointModelId id);
|
bool acceptsBreakpoint(const BreakpointModelId &id);
|
||||||
void removeBreakpoint(BreakpointModelId id);
|
void insertBreakpoint(const BreakpointModelId &id);
|
||||||
void changeBreakpoint(BreakpointModelId id);
|
void removeBreakpoint(const BreakpointModelId &id);
|
||||||
|
void changeBreakpoint(const BreakpointModelId &id);
|
||||||
void updateBreakpoints();
|
void updateBreakpoints();
|
||||||
|
|
||||||
void assignValueInDebugger(const QByteArray expr, const quint64 &id,
|
void assignValueInDebugger(const QByteArray expr, const quint64 &id,
|
||||||
const QString &property, const QString value);
|
const QString &property, const QString &value);
|
||||||
|
|
||||||
void updateWatchData(const WatchData *data);
|
void updateWatchData(const WatchData *data);
|
||||||
void executeDebuggerCommand(const QString &command);
|
void executeDebuggerCommand(const QString &command);
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ void QScriptDebuggerClient::activateFrame(int index)
|
|||||||
sendMessage(reply);
|
sendMessage(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QScriptDebuggerClient::insertBreakpoint(BreakpointModelId id)
|
void QScriptDebuggerClient::insertBreakpoint(const BreakpointModelId &id)
|
||||||
{
|
{
|
||||||
BreakHandler *handler = d->engine->breakHandler();
|
BreakHandler *handler = d->engine->breakHandler();
|
||||||
JSAgentBreakpointData bp;
|
JSAgentBreakpointData bp;
|
||||||
@@ -226,7 +226,7 @@ void QScriptDebuggerClient::insertBreakpoint(BreakpointModelId id)
|
|||||||
d->breakpoints.insert(bp);
|
d->breakpoints.insert(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QScriptDebuggerClient::removeBreakpoint(BreakpointModelId id)
|
void QScriptDebuggerClient::removeBreakpoint(const BreakpointModelId &id)
|
||||||
{
|
{
|
||||||
BreakHandler *handler = d->engine->breakHandler();
|
BreakHandler *handler = d->engine->breakHandler();
|
||||||
JSAgentBreakpointData bp;
|
JSAgentBreakpointData bp;
|
||||||
@@ -236,7 +236,7 @@ void QScriptDebuggerClient::removeBreakpoint(BreakpointModelId id)
|
|||||||
d->breakpoints.remove(bp);
|
d->breakpoints.remove(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QScriptDebuggerClient::changeBreakpoint(BreakpointModelId /*id*/)
|
void QScriptDebuggerClient::changeBreakpoint(const BreakpointModelId &/*id*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ void QScriptDebuggerClient::updateBreakpoints()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QScriptDebuggerClient::assignValueInDebugger(const QByteArray expr, const quint64 &id,
|
void QScriptDebuggerClient::assignValueInDebugger(const QByteArray expr, const quint64 &id,
|
||||||
const QString &property, const QString value)
|
const QString &property, const QString &value)
|
||||||
{
|
{
|
||||||
QByteArray reply;
|
QByteArray reply;
|
||||||
QDataStream rs(&reply, QIODevice::WriteOnly);
|
QDataStream rs(&reply, QIODevice::WriteOnly);
|
||||||
|
|||||||
@@ -64,13 +64,13 @@ public:
|
|||||||
|
|
||||||
void activateFrame(int index);
|
void activateFrame(int index);
|
||||||
|
|
||||||
void insertBreakpoint(BreakpointModelId id);
|
void insertBreakpoint(const BreakpointModelId &id);
|
||||||
void removeBreakpoint(BreakpointModelId id);
|
void removeBreakpoint(const BreakpointModelId &id);
|
||||||
void changeBreakpoint(BreakpointModelId id);
|
void changeBreakpoint(const BreakpointModelId &id);
|
||||||
void updateBreakpoints();
|
void updateBreakpoints();
|
||||||
|
|
||||||
void assignValueInDebugger(const QByteArray expr, const quint64 &id,
|
void assignValueInDebugger(const QByteArray expr, const quint64 &id,
|
||||||
const QString &property, const QString value);
|
const QString &property, const QString &value);
|
||||||
|
|
||||||
void updateWatchData(const WatchData *data);
|
void updateWatchData(const WatchData *data);
|
||||||
void executeDebuggerCommand(const QString &command);
|
void executeDebuggerCommand(const QString &command);
|
||||||
|
|||||||
Reference in New Issue
Block a user