Commit f05683ac authored by Aurindam Jana's avatar Aurindam Jana

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/4758Reviewed-by: default avatarQt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent 1285a638
......@@ -122,6 +122,8 @@ static QString typeToString(BreakpointType type)
return BreakHandler::tr("Watchpoint at Address");
case WatchpointAtExpression:
return BreakHandler::tr("Watchpoint at Expression");
case BreakpointOnSignalHandler:
return BreakHandler::tr("Breakpoint on Signal Handler");
case UnknownType:
break;
}
......
......@@ -260,6 +260,7 @@ QString BreakpointParameters::toString() const
<< " PathUsage: " << pathUsage;
break;
case BreakpointByFunction:
case BreakpointOnSignalHandler:
ts << " FunctionName: " << functionName;
break;
case BreakpointByAddress:
......
......@@ -139,7 +139,8 @@ enum BreakpointType
//BreakpointAtVFork,
BreakpointAtSysCall,
WatchpointAtAddress,
WatchpointAtExpression
WatchpointAtExpression,
BreakpointOnSignalHandler
};
//! \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 system call is executed")
<< tr("Break on data access at fixed address")
<< tr("Break on data access at address given by expression");
QTC_ASSERT(types.size() == WatchpointAtExpression, return; )
<< tr("Break on data access at address given by expression")
<< tr("Break on QML signal handler");
QTC_ASSERT(types.size() == BreakpointOnSignalHandler, return; )
m_ui.comboBoxType->addItems(types);
m_ui.pathChooserFileName->setExpectedKind(Utils::PathChooser::File);
connect(m_ui.comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int)));
......@@ -358,6 +360,8 @@ void BreakpointDialog::typeChanged(int)
case WatchpointAtExpression:
getParts(ExpressionPart|AllConditionParts|TracePointPart, &m_savedParameters);
break;
case BreakpointOnSignalHandler:
getParts(FunctionPart, &m_savedParameters);
}
// Enable and set up new state from saved values.
......@@ -399,6 +403,10 @@ void BreakpointDialog::typeChanged(int)
setPartsEnabled(ExpressionPart|AllConditionParts|TracePointPart|TracePointPart);
clearOtherParts(ExpressionPart|AllConditionParts|TracePointPart);
break;
case BreakpointOnSignalHandler:
setParts(FunctionPart, m_savedParameters);
setPartsEnabled(FunctionPart);
clearOtherParts(FunctionPart);
}
}
......
......@@ -2552,6 +2552,7 @@ bool CdbEngine::acceptsBreakpoint(BreakpointModelId id) const
case BreakpointAtFork:
case WatchpointAtExpression:
case BreakpointAtSysCall:
case BreakpointOnSignalHandler:
return false;
case WatchpointAtAddress:
case BreakpointByFileAndLine:
......
......@@ -107,6 +107,7 @@ static BreakpointParameters fixWinMSVCBreakpoint(const BreakpointParameters &p)
case WatchpointAtExpression:
case BreakpointAtSysCall:
case WatchpointAtAddress:
case BreakpointOnSignalHandler:
break;
case BreakpointAtExec: { // Emulate by breaking on CreateProcessW().
BreakpointParameters rc(BreakpointByFunction);
......@@ -163,6 +164,7 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
case BreakpointAtCatch:
case BreakpointAtThrow:
case BreakpointAtMain:
case BreakpointOnSignalHandler:
QTC_ASSERT(false, return QByteArray(); )
break;
case BreakpointByAddress:
......
......@@ -30,6 +30,7 @@
**
**************************************************************************/
#include "qmldebuggerclient.h"
#include "breakpoint.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
......@@ -54,6 +55,11 @@ QmlDebuggerClient::~QmlDebuggerClient()
delete d;
}
bool QmlDebuggerClient::acceptsBreakpoint(const BreakpointModelId &/*id*/)
{
return false;
}
void QmlDebuggerClient::statusChanged(Status status)
{
emit newStatus(status);
......
......@@ -65,13 +65,14 @@ public:
virtual void activateFrame(int index) = 0;
virtual void insertBreakpoint(BreakpointModelId id) = 0;
virtual void removeBreakpoint(BreakpointModelId id) = 0;
virtual void changeBreakpoint(BreakpointModelId id) = 0;
virtual bool acceptsBreakpoint(const BreakpointModelId &id);
virtual void insertBreakpoint(const BreakpointModelId &id) = 0;
virtual void removeBreakpoint(const BreakpointModelId &id) = 0;
virtual void changeBreakpoint(const BreakpointModelId &id) = 0;
virtual void updateBreakpoints() = 0;
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 executeDebuggerCommand(const QString &command) = 0;
......
......@@ -603,7 +603,18 @@ void QmlEngine::attemptBreakpointSynchronization()
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)
......
......@@ -312,7 +312,13 @@ void QmlV8DebuggerClient::activateFrame(int 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();
QByteArray request;
......@@ -327,6 +333,9 @@ void QmlV8DebuggerClient::insertBreakpoint(BreakpointModelId id)
} else if (handler->breakpointData(id).type == BreakpointByFunction) {
JsonInputStream(request) << "type" << ':' << "function";
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) << '}';
......@@ -335,7 +344,7 @@ void QmlV8DebuggerClient::insertBreakpoint(BreakpointModelId id)
sendMessage(packMessage(request));
}
void QmlV8DebuggerClient::removeBreakpoint(BreakpointModelId id)
void QmlV8DebuggerClient::removeBreakpoint(const BreakpointModelId &id)
{
int breakpoint = d->breakpoints.value(id);
d->breakpoints.remove(id);
......@@ -354,7 +363,7 @@ void QmlV8DebuggerClient::removeBreakpoint(BreakpointModelId id)
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*/,
const QString &/*property*/, const QString /*value*/)
const QString &/*property*/, const QString &/*value*/)
{
//TODO::
}
......@@ -468,7 +477,7 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
ds >> response;
JsonValue value(response);
QString type = value.findChild("type").toVariant().toString();
const QString type = value.findChild("type").toVariant().toString();
if (type == "response") {
......@@ -478,7 +487,7 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
return;
}
QString debugCommand(value.findChild("command").toVariant().toString());
const QString debugCommand(value.findChild("command").toVariant().toString());
if (debugCommand == "backtrace") {
setStackFrames(response);
......@@ -491,6 +500,12 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
BreakpointModelId id = d->breakpointsSync.take(sequence);
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") {
setExpression(response);
......@@ -504,7 +519,7 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
}
} else if (type == "event") {
QString event(value.findChild("event").toVariant().toString());
const QString event(value.findChild("event").toVariant().toString());
if (event == "break") {
d->engine->inferiorSpontaneousStop();
......
......@@ -80,13 +80,14 @@ public:
void activateFrame(int index);
void insertBreakpoint(BreakpointModelId id);
void removeBreakpoint(BreakpointModelId id);
void changeBreakpoint(BreakpointModelId id);
bool acceptsBreakpoint(const BreakpointModelId &id);
void insertBreakpoint(const BreakpointModelId &id);
void removeBreakpoint(const BreakpointModelId &id);
void changeBreakpoint(const BreakpointModelId &id);
void updateBreakpoints();
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 executeDebuggerCommand(const QString &command);
......
......@@ -216,7 +216,7 @@ void QScriptDebuggerClient::activateFrame(int index)
sendMessage(reply);
}
void QScriptDebuggerClient::insertBreakpoint(BreakpointModelId id)
void QScriptDebuggerClient::insertBreakpoint(const BreakpointModelId &id)
{
BreakHandler *handler = d->engine->breakHandler();
JSAgentBreakpointData bp;
......@@ -226,7 +226,7 @@ void QScriptDebuggerClient::insertBreakpoint(BreakpointModelId id)
d->breakpoints.insert(bp);
}
void QScriptDebuggerClient::removeBreakpoint(BreakpointModelId id)
void QScriptDebuggerClient::removeBreakpoint(const BreakpointModelId &id)
{
BreakHandler *handler = d->engine->breakHandler();
JSAgentBreakpointData bp;
......@@ -236,7 +236,7 @@ void QScriptDebuggerClient::removeBreakpoint(BreakpointModelId id)
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,
const QString &property, const QString value)
const QString &property, const QString &value)
{
QByteArray reply;
QDataStream rs(&reply, QIODevice::WriteOnly);
......
......@@ -64,13 +64,13 @@ public:
void activateFrame(int index);
void insertBreakpoint(BreakpointModelId id);
void removeBreakpoint(BreakpointModelId id);
void changeBreakpoint(BreakpointModelId id);
void insertBreakpoint(const BreakpointModelId &id);
void removeBreakpoint(const BreakpointModelId &id);
void changeBreakpoint(const BreakpointModelId &id);
void updateBreakpoints();
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 executeDebuggerCommand(const QString &command);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment