debugger: make parts of python debugger work again with the new states

This commit is contained in:
hjk
2010-07-23 16:05:56 +02:00
parent 97775d9cf9
commit 3cee7dad0a
5 changed files with 342 additions and 286 deletions

View File

@@ -3,239 +3,250 @@ import pdb;
import sys; import sys;
import linecache import linecache
def qdebug(options = None,
class qdebug:
def __init__(self,
options = None,
expanded = None, expanded = None,
typeformats = None, typeformats = None,
individualformats = None, individualformats = None,
watchers = None): watchers = None):
self.options = options
self.expandedINames = expanded
self.typeformats = typeformats
self.individualformats = individualformats
self.watchers = watchers
if self.options == "listmodules":
self.handleListModules()
elif self.options == "listsymbols":
self.handleListSymbols(expanded)
else:
self.handleListVars()
def put(self, value): class QDebug:
sys.stdout.write(value) def __init__(self,
options = None,
expanded = None,
typeformats = None,
individualformats = None,
watchers = None):
self.options = options
self.expandedINames = expanded
self.typeformats = typeformats
self.individualformats = individualformats
self.watchers = watchers
self.buffer = ""
if self.options == "listmodules":
self.handleListModules()
elif self.options == "listsymbols":
self.handleListSymbols(expanded)
else:
self.handleListVars()
def putField(self, name, value): def put(self, value):
self.put('%s="%s",' % (name, value)) #sys.stdout.write(value)
self.buffer += value
def putItemCount(self, count): def putField(self, name, value):
self.put('value="<%s items>",' % count) self.put('%s="%s",' % (name, value))
def putEllipsis(self): def putItemCount(self, count):
self.put('{name="<incomplete>",value="",type="",numchild="0"},') self.put('value="<%s items>",' % count)
def cleanType(self, type): def putEllipsis(self):
t = str(type) self.put('{name="<incomplete>",value="",type="",numchild="0"},')
if t.startswith("<type '") and t.endswith("'>"):
t = t[7:-2]
if t.startswith("<class '") and t.endswith("'>"):
t = t[8:-2]
return t
def putType(self, type, priority = 0): def cleanType(self, type):
self.putField("type", self.cleanType(type)) t = str(type)
if t.startswith("<type '") and t.endswith("'>"):
t = t[7:-2]
if t.startswith("<class '") and t.endswith("'>"):
t = t[8:-2]
return t
def putAddress(self, addr): def putType(self, type, priority = 0):
self.put('addr="%s",' % cleanAddress(addr)) self.putField("type", self.cleanType(type))
def putNumChild(self, numchild): def putAddress(self, addr):
self.put('numchild="%s",' % numchild) self.put('addr="%s",' % cleanAddress(addr))
def putValue(self, value, encoding = None, priority = 0): def putNumChild(self, numchild):
self.putField("value", value) self.put('numchild="%s",' % numchild)
def putName(self, name): def putValue(self, value, encoding = None, priority = 0):
self.put('name="%s",' % name) self.putField("value", value)
def isExpanded(self, iname): def putName(self, name):
#self.warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames)) self.put('name="%s",' % name)
if iname.startswith("None"):
raise "Illegal iname '%s'" % iname
#self.warn(" --> %s" % (iname in self.expandedINames))
return iname in self.expandedINames
def isExpandedIName(self, iname): def isExpanded(self, iname):
return iname in self.expandedINames #self.warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames))
if iname.startswith("None"):
raise "Illegal iname '%s'" % iname
#self.warn(" --> %s" % (iname in self.expandedINames))
return iname in self.expandedINames
def itemFormat(self, item): def isExpandedIName(self, iname):
format = self.formats.get(str(cleanAddress(item.value.address))) return iname in self.expandedINames
if format is None:
format = self.typeformats.get(stripClassTag(str(item.value.type)))
return format
def dumpFrame(self, frame): def itemFormat(self, item):
for var in frame.f_locals.keys(): format = self.formats.get(str(cleanAddress(item.value.address)))
if var == "__file__": if format is None:
continue format = self.typeformats.get(stripClassTag(str(item.value.type)))
#if var == "__name__": return format
# continue
if var == "__package__":
continue
if var == "qdebug":
continue
if var != '__builtins__':
value = frame.f_locals[var]
self.dumpValue(value, var, "local.%s" % var)
def dumpValue(self, value, name, iname): def dumpFrame(self, frame):
t = type(value) for var in frame.f_locals.keys():
tt = self.cleanType(t) if var == "__file__":
if tt == "module" or tt == "function": continue
return #if var == "__name__":
if str(value).startswith("<class '"): # continue
return if var == "__package__":
# FIXME: Should we? continue
if str(value).startswith("<enum-item "): if var == "qdebug":
return continue
self.put("{") if var != '__builtins__':
self.putField("iname", iname) value = frame.f_locals[var]
self.putName(name) self.dumpValue(value, var, "local.%s" % var)
self.putType(tt)
if tt == "NoneType": def dumpValue(self, value, name, iname):
self.putValue("None") t = type(value)
self.putNumChild(0) tt = self.cleanType(t)
elif tt == "list" or tt == "tuple": if tt == "module" or tt == "function":
self.putItemCount(len(value)) return
#self.putValue(value) if str(value).startswith("<class '"):
self.put("children=[") return
for i in xrange(len(value)): # FIXME: Should we?
self.dumpValue(value[i], str(i), "%s.%d" % (iname, i)) if str(value).startswith("<enum-item "):
self.put("]") return
elif tt == "str": self.put("{")
v = value self.putField("iname", iname)
self.putValue(v.encode('hex')) self.putName(name)
self.putField("valueencoded", 6) self.putType(tt)
self.putNumChild(0) if tt == "NoneType":
elif tt == "unicode": self.putValue("None")
v = value self.putNumChild(0)
self.putValue(v.encode('hex')) elif tt == "list" or tt == "tuple":
self.putField("valueencoded", 6) self.putItemCount(len(value))
self.putNumChild(0) #self.putValue(value)
elif tt == "buffer": self.put("children=[")
v = str(value) for i in xrange(len(value)):
self.putValue(v.encode('hex')) self.dumpValue(value[i], str(i), "%s.%d" % (iname, i))
self.putField("valueencoded", 6) self.put("]")
self.putNumChild(0) elif tt == "str":
elif tt == "xrange": v = value
b = iter(value).next() self.putValue(v.encode('hex'))
e = b + len(value) self.putField("valueencoded", 6)
self.putValue("(%d, %d)" % (b, e)) self.putNumChild(0)
self.putNumChild(0) elif tt == "unicode":
elif tt == "dict": v = value
self.putItemCount(len(value)) self.putValue(v.encode('hex'))
self.putField("childnumchild", 2) self.putField("valueencoded", 6)
self.put("children=[") self.putNumChild(0)
i = 0 elif tt == "buffer":
for (k, v) in value.iteritems(): v = str(value)
self.put("{") self.putValue(v.encode('hex'))
self.putType(" ") self.putField("valueencoded", 6)
self.putValue("%s: %s" % (k, v)) self.putNumChild(0)
elif tt == "xrange":
b = iter(value).next()
e = b + len(value)
self.putValue("(%d, %d)" % (b, e))
self.putNumChild(0)
elif tt == "dict":
self.putItemCount(len(value))
self.putField("childnumchild", 2)
self.put("children=[")
i = 0
for (k, v) in value.iteritems():
self.put("{")
self.putType(" ")
self.putValue("%s: %s" % (k, v))
if self.isExpanded(iname):
self.put("children=[")
self.dumpValue(k, "key", "%s.%d.k" % (iname, i))
self.dumpValue(v, "value", "%s.%d.v" % (iname, i))
self.put("]")
self.put("},")
i += 1
self.put("]")
elif tt == "class":
pass
elif tt == "module":
pass
elif tt == "function":
pass
elif str(value).startswith("<enum-item "):
# FIXME: Having enums always shown like this is not nice.
self.putValue(str(value)[11:-1])
self.putNumChild(0)
else:
v = str(value)
p = v.find(" object at ")
if p > 1:
v = "@" + v[p + 11:-1]
self.putValue(v)
if self.isExpanded(iname): if self.isExpanded(iname):
self.put("children=[") self.put("children=[")
self.dumpValue(k, "key", "%s.%d.k" % (iname, i)) for child in dir(value):
self.dumpValue(v, "value", "%s.%d.v" % (iname, i)) if child == "__dict__":
self.put("]") continue
if child == "__doc__":
continue
if child == "__module__":
continue
attr = getattr(value, child)
if callable(attr):
continue
try:
self.dumpValue(attr, child, "%s.%s" % (iname, child))
except:
pass
self.put("],")
self.put("},")
def warn(self, msg):
self.putField("warning", msg)
def handleListVars(self):
# Trigger error to get a backtrace.
frame = None
#self.warn("frame: %s" % frame)
try:
raise ZeroDivisionError
except ZeroDivisionError:
frame = sys.exc_info()[2].tb_frame.f_back
limit = 30
n = 0
isActive = False
while frame is not None and n < limit:
#self.warn("frame: %s" % frame.f_locals.keys())
lineno = frame.f_lineno
code = frame.f_code
filename = code.co_filename
name = code.co_name
if isActive:
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, frame.f_globals)
self.dumpFrame(frame)
if name == "<module>":
isActive = False
if name == "trace_dispatch":
isActive = True
frame = frame.f_back
n = n + 1
#sys.stdout.flush()
def handleListModules(self):
self.put("modules=[");
for name in sys.modules:
self.put("{")
self.putName(name)
self.putValue(sys.modules[name])
self.put("},") self.put("},")
i += 1
self.put("]") self.put("]")
elif tt == "class": #sys.stdout.flush()
pass
elif tt == "module":
pass
elif tt == "function":
pass
elif str(value).startswith("<enum-item "):
# FIXME: Having enums always shown like this is not nice.
self.putValue(str(value)[11:-1])
self.putNumChild(0)
else:
v = str(value)
p = v.find(" object at ")
if p > 1:
v = "@" + v[p + 11:-1]
self.putValue(v)
if self.isExpanded(iname):
self.put("children=[")
for child in dir(value):
if child == "__dict__":
continue
if child == "__doc__":
continue
if child == "__module__":
continue
attr = getattr(value, child)
if callable(attr):
continue
try:
self.dumpValue(attr, child, "%s.%s" % (iname, child))
except:
pass
self.put("],")
self.put("},")
def handleListSymbols(self, module):
#self.put("symbols=%s" % dir(sys.modules[module]))
self.put("symbols=[");
for name in sys.modules:
self.put("{")
self.putName(name)
#self.putValue(sys.modules[name])
self.put("},")
self.put("]")
#sys.stdout.flush()
def warn(self, msg): d = QDebug(options, expanded, typeformats, individualformats, watchers)
self.putField("warning", msg) #print d.buffer
sys.stdout.write(d.buffer)
def handleListVars(self): sys.stdout.flush()
# Trigger error to get a backtrace.
frame = None
#self.warn("frame: %s" % frame)
try:
raise ZeroDivisionError
except ZeroDivisionError:
frame = sys.exc_info()[2].tb_frame.f_back
limit = 30
n = 0
isActive = False
while frame is not None and n < limit:
#self.warn("frame: %s" % frame.f_locals.keys())
lineno = frame.f_lineno
code = frame.f_code
filename = code.co_filename
name = code.co_name
if isActive:
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, frame.f_globals)
self.dumpFrame(frame)
if name == "<module>":
isActive = False
if name == "trace_dispatch":
isActive = True
frame = frame.f_back
n = n + 1
sys.stdout.flush()
def handleListModules(self):
self.put("modules=[");
for name in sys.modules:
self.put("{")
self.putName(name)
self.putValue(sys.modules[name])
self.put("},")
self.put("]")
sys.stdout.flush()
def handleListSymbols(self, module):
#self.put("symbols=%s" % dir(sys.modules[module]))
self.put("symbols=[");
for name in sys.modules:
self.put("{")
self.putName(name)
#self.putValue(sys.modules[name])
self.put("},")
self.put("]")
sys.stdout.flush()

View File

@@ -61,8 +61,8 @@
#include <QtCore/QVariant> #include <QtCore/QVariant>
#include <QtGui/QApplication> #include <QtGui/QApplication>
#include <QtGui/QToolTip>
#include <QtGui/QMessageBox> #include <QtGui/QMessageBox>
#include <QtGui/QToolTip>
#define DEBUG_SCRIPT 1 #define DEBUG_SCRIPT 1
@@ -94,12 +94,26 @@ PdbEngine::~PdbEngine()
void PdbEngine::executeDebuggerCommand(const QString &command) void PdbEngine::executeDebuggerCommand(const QString &command)
{ {
XSDEBUG("PdbEngine::executeDebuggerCommand:" << command); QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
//XSDEBUG("PdbEngine::executeDebuggerCommand:" << command);
if (state() == DebuggerNotReady) { if (state() == DebuggerNotReady) {
showMessage(_("PDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + command); showMessage(_("PDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + command);
return; return;
} }
m_pdbProc.write(command.toLatin1() + "\n"); QTC_ASSERT(m_pdbProc.state() == QProcess::Running, notifyEngineIll());
postCommand(command.toLatin1(), CB(handleExecuteDebuggerCommand));
}
void PdbEngine::handleExecuteDebuggerCommand(const PdbResponse &response)
{
Q_UNUSED(response);
}
void PdbEngine::postDirectCommand(const QByteArray &command)
{
QTC_ASSERT(m_pdbProc.state() == QProcess::Running, notifyEngineIll());
showMessage(_(command), LogInput);
m_pdbProc.write(command + "\n");
} }
void PdbEngine::postCommand(const QByteArray &command, void PdbEngine::postCommand(const QByteArray &command,
@@ -108,12 +122,14 @@ void PdbEngine::postCommand(const QByteArray &command,
const char *callbackName, const char *callbackName,
const QVariant &cookie) const QVariant &cookie)
{ {
QTC_ASSERT(m_pdbProc.state() == QProcess::Running, notifyEngineIll());
PdbCommand cmd; PdbCommand cmd;
cmd.command = command; cmd.command = command;
cmd.callback = callback; cmd.callback = callback;
cmd.callbackName = callbackName; cmd.callbackName = callbackName;
cmd.cookie = cookie; cmd.cookie = cookie;
m_commands.enqueue(cmd); m_commands.enqueue(cmd);
qDebug() << "ENQUEUE: " << command << cmd.callbackName;
showMessage(_(cmd.command), LogInput); showMessage(_(cmd.command), LogInput);
m_pdbProc.write(cmd.command + "\n"); m_pdbProc.write(cmd.command + "\n");
} }
@@ -127,7 +143,6 @@ void PdbEngine::shutdownInferior()
void PdbEngine::shutdownEngine() void PdbEngine::shutdownEngine()
{ {
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
SDEBUG("PdbEngine::shutdownEngine()");
m_pdbProc.kill(); m_pdbProc.kill();
} }
@@ -135,24 +150,8 @@ void PdbEngine::setupEngine()
{ {
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath(); m_pdb = _("python");
QFile scriptFile(m_scriptFileName);
if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
//showMessage("STARTING " +m_scriptFileName + "FAILED");
showMessage(QString::fromLatin1("Cannot open %1: %2").
arg(m_scriptFileName, scriptFile.errorString()), LogError);
notifyEngineSetupFailed();
return;
}
m_pdbProc.disconnect(); // From any previous runs
m_pdb = _("/usr/bin/python");
showMessage(_("STARTING PDB ") + m_pdb); showMessage(_("STARTING PDB ") + m_pdb);
QStringList gdbArgs;
gdbArgs += _("-i");
gdbArgs += _("/usr/bin/pdb");
gdbArgs += m_scriptFileName;
//gdbArgs += args;
connect(&m_pdbProc, SIGNAL(error(QProcess::ProcessError)), connect(&m_pdbProc, SIGNAL(error(QProcess::ProcessError)),
SLOT(handlePdbError(QProcess::ProcessError))); SLOT(handlePdbError(QProcess::ProcessError)));
@@ -163,13 +162,15 @@ void PdbEngine::setupEngine()
connect(&m_pdbProc, SIGNAL(readyReadStandardError()), connect(&m_pdbProc, SIGNAL(readyReadStandardError()),
SLOT(readPdbStandardError())); SLOT(readPdbStandardError()));
connect(this, SIGNAL(outputReady(QByteArray)),
SLOT(handleOutput2(QByteArray)), Qt::QueuedConnection);
// We will stop immediatly, so setup a proper callback. // We will stop immediatly, so setup a proper callback.
PdbCommand cmd; PdbCommand cmd;
cmd.callback = &PdbEngine::handleFirstCommand; cmd.callback = &PdbEngine::handleFirstCommand;
m_commands.enqueue(cmd); m_commands.enqueue(cmd);
m_pdbProc.start(m_pdb, gdbArgs); m_pdbProc.start(m_pdb, QStringList() << _("-i"));
//qDebug() << "STARTING:" << m_pdb << gdbArgs;
if (!m_pdbProc.waitForStarted()) { if (!m_pdbProc.waitForStarted()) {
const QString msg = tr("Unable to start pdb '%1': %2") const QString msg = tr("Unable to start pdb '%1': %2")
@@ -189,21 +190,33 @@ void PdbEngine::setupEngine()
void PdbEngine::setupInferior() void PdbEngine::setupInferior()
{ {
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
attemptBreakpointSynchronization();
showMessage(_("PDB STARTED, INITIALIZING IT")); QString fileName = QFileInfo(startParameters().executable).absoluteFilePath();
const QByteArray dumperSourcePath = QFile scriptFile(fileName);
Core::ICore::instance()->resourcePath().toLocal8Bit() + "/gdbmacros/"; if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
postCommand("execfile('" + dumperSourcePath + "pdumper.py')", showMessageBox(QMessageBox::Critical, tr("Python Error"),
CB(handleLoadDumper)); _("Cannot open script file %1:\n%2").
arg(fileName, scriptFile.errorString()));
notifyInferiorSetupFailed();
return;
}
notifyInferiorSetupOk();
} }
void PdbEngine::runEngine() void PdbEngine::runEngine()
{ {
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
showStatusMessage(tr("Running requested..."), 5000); showStatusMessage(tr("Running requested..."), 5000);
SDEBUG("PdbEngine::runEngine()"); const QByteArray dumperSourcePath =
notifyEngineRunAndInferiorRunOk(); Core::ICore::instance()->resourcePath().toLocal8Bit() + "/gdbmacros/";
postCommand("continue", CB(handleUpdateAll)); QString fileName = QFileInfo(startParameters().executable).absoluteFilePath();
postDirectCommand("import sys");
postDirectCommand("sys.argv.append('" + fileName.toLocal8Bit() + "')");
postDirectCommand("execfile('/usr/bin/pdb')");
postDirectCommand("execfile('" + dumperSourcePath + "pdumper.py')");
attemptBreakpointSynchronization();
notifyEngineRunAndInferiorStopOk();
continueInferior();
} }
void PdbEngine::interruptInferior() void PdbEngine::interruptInferior()
@@ -388,7 +401,7 @@ void PdbEngine::loadAllSymbols()
void PdbEngine::reloadModules() void PdbEngine::reloadModules()
{ {
postCommand("qdebug('listmodules')", CB(handleListModules)); //postCommand("qdebug('listmodules')", CB(handleListModules));
} }
void PdbEngine::handleListModules(const PdbResponse &response) void PdbEngine::handleListModules(const PdbResponse &response)
@@ -549,6 +562,7 @@ void PdbEngine::updateWatchData(const WatchData &data)
void PdbEngine::handlePdbError(QProcess::ProcessError error) void PdbEngine::handlePdbError(QProcess::ProcessError error)
{ {
qDebug() << "HANDLE PDB ERROR";
showMessage(_("HANDLE PDB ERROR")); showMessage(_("HANDLE PDB ERROR"));
switch (error) { switch (error) {
case QProcess::Crashed: case QProcess::Crashed:
@@ -595,6 +609,7 @@ QString PdbEngine::errorMessage(QProcess::ProcessError error) const
void PdbEngine::handlePdbFinished(int code, QProcess::ExitStatus type) void PdbEngine::handlePdbFinished(int code, QProcess::ExitStatus type)
{ {
qDebug() << "PDB FINISHED";
showMessage(_("PDB PROCESS FINISHED, status %1, code %2").arg(type).arg(code)); showMessage(_("PDB PROCESS FINISHED, status %1, code %2").arg(type).arg(code));
notifyEngineSpontaneousShutdown(); notifyEngineSpontaneousShutdown();
} }
@@ -602,35 +617,57 @@ void PdbEngine::handlePdbFinished(int code, QProcess::ExitStatus type)
void PdbEngine::readPdbStandardError() void PdbEngine::readPdbStandardError()
{ {
QByteArray err = m_pdbProc.readAllStandardError(); QByteArray err = m_pdbProc.readAllStandardError();
qWarning() << "Unexpected pdb stderr:" << err; qDebug() << "\nPDB STDERR" << err;
showMessage(_("Unexpected pdb stderr: " + err)); //qWarning() << "Unexpected pdb stderr:" << err;
//showMessage(_("Unexpected pdb stderr: " + err));
//handleOutput(err);
} }
void PdbEngine::readPdbStandardOutput() void PdbEngine::readPdbStandardOutput()
{ {
m_inbuffer.append(m_pdbProc.readAllStandardOutput()); QByteArray out = m_pdbProc.readAllStandardOutput();
//qDebug() << "BUFFER FROM: '" << m_inbuffer << "'"; qDebug() << "\nPDB STDOUT" << out;
int pos = 1; handleOutput(out);
while ((pos = m_inbuffer.indexOf("(Pdb)")) != -1) {
PdbResponse response;
response.data = m_inbuffer.left(pos).trimmed();
showMessage(_(response.data));
m_inbuffer = m_inbuffer.mid(pos + 6);
QTC_ASSERT(!m_commands.isEmpty(),
qDebug() << "RESPONSE: " << response.data; return)
PdbCommand cmd = m_commands.dequeue();
response.cookie = cmd.cookie;
if (cmd.callback) {
//qDebug() << "EXECUTING CALLBACK " << cmd.callbackName
// << " RESPONSE: " << response.data;
(this->*cmd.callback)(response);
} else {
qDebug() << "NO CALLBACK FOR RESPONSE: " << response.data;
}
}
//qDebug() << "BUFFER LEFT: '" << m_inbuffer << "'";
} }
void PdbEngine::handleOutput(const QByteArray &data)
{
//qDebug() << "READ: " << data;
m_inbuffer.append(data);
qDebug() << "BUFFER FROM: '" << m_inbuffer << "'";
while (true) {
int pos = m_inbuffer.indexOf("(Pdb)");
if (pos == -1)
pos = m_inbuffer.indexOf(">>>");
if (pos == -1)
break;
QByteArray response = m_inbuffer.left(pos).trimmed();
m_inbuffer = m_inbuffer.mid(pos + 6);
emit outputReady(response);
}
qDebug() << "BUFFER LEFT: '" << m_inbuffer << "'";
//m_inbuffer.clear();
}
void PdbEngine::handleOutput2(const QByteArray &data)
{
PdbResponse response;
response.data = data;
showMessage(_(data));
QTC_ASSERT(!m_commands.isEmpty(), qDebug() << "RESPONSE: " << data; return)
PdbCommand cmd = m_commands.dequeue();
response.cookie = cmd.cookie;
qDebug() << "DEQUE: " << cmd.command << cmd.callbackName;
if (cmd.callback) {
//qDebug() << "EXECUTING CALLBACK " << cmd.callbackName
// << " RESPONSE: " << response.data;
(this->*cmd.callback)(response);
} else {
qDebug() << "NO CALLBACK FOR RESPONSE: " << response.data;
}
}
/*
void PdbEngine::handleResponse(const QByteArray &response0) void PdbEngine::handleResponse(const QByteArray &response0)
{ {
QByteArray response = response0; QByteArray response = response0;
@@ -649,7 +686,7 @@ void PdbEngine::handleResponse(const QByteArray &response0)
if (pos1 != -1 && pos2 != -1) { if (pos1 != -1 && pos2 != -1) {
int lineNumber = response.mid(pos1 + 1, pos2 - pos1 - 1).toInt(); int lineNumber = response.mid(pos1 + 1, pos2 - pos1 - 1).toInt();
QByteArray fileName = response.mid(2, pos1 - 2); QByteArray fileName = response.mid(2, pos1 - 2);
qDebug() << " " << pos1 << pos2 << lineNumber << fileName qDebug() << " " << pos1 << pos2 << lineNumber << fileName
<< response.mid(pos1 + 1, pos2 - pos1 - 1); << response.mid(pos1 + 1, pos2 - pos1 - 1);
StackFrame frame; StackFrame frame;
frame.file = _(fileName); frame.file = _(fileName);
@@ -663,6 +700,7 @@ void PdbEngine::handleResponse(const QByteArray &response0)
} }
qDebug() << "COULD NOT PARSE RESPONSE: '" << response << "'"; qDebug() << "COULD NOT PARSE RESPONSE: '" << response << "'";
} }
*/
void PdbEngine::handleFirstCommand(const PdbResponse &response) void PdbEngine::handleFirstCommand(const PdbResponse &response)
{ {
@@ -677,6 +715,12 @@ void PdbEngine::handleUpdateAll(const PdbResponse &response)
} }
void PdbEngine::updateAll() void PdbEngine::updateAll()
{
postCommand("bt", CB(handleBacktrace));
//updateLocals();
}
void PdbEngine::updateLocals()
{ {
WatchHandler *handler = watchHandler(); WatchHandler *handler = watchHandler();
@@ -706,7 +750,6 @@ void PdbEngine::updateAll()
options += "defaults,"; options += "defaults,";
options.chop(1); options.chop(1);
postCommand("bt", CB(handleBacktrace));
postCommand("qdebug('" + options + "','" postCommand("qdebug('" + options + "','"
+ handler->expansionRequests() + "','" + handler->expansionRequests() + "','"
+ handler->typeFormatRequests() + "','" + handler->typeFormatRequests() + "','"
@@ -741,7 +784,7 @@ void PdbEngine::handleBacktrace(const PdbResponse &response)
if (pos1 != -1 && pos2 != -1) { if (pos1 != -1 && pos2 != -1) {
int lineNumber = line.mid(pos1 + 1, pos2 - pos1 - 1).toInt(); int lineNumber = line.mid(pos1 + 1, pos2 - pos1 - 1).toInt();
QByteArray fileName = line.mid(2, pos1 - 2); QByteArray fileName = line.mid(2, pos1 - 2);
//qDebug() << " " << pos1 << pos2 << lineNumber << fileName //qDebug() << " " << pos1 << pos2 << lineNumber << fileName
// << line.mid(pos1 + 1, pos2 - pos1 - 1); // << line.mid(pos1 + 1, pos2 - pos1 - 1);
StackFrame frame; StackFrame frame;
frame.file = _(fileName); frame.file = _(fileName);
@@ -758,8 +801,8 @@ void PdbEngine::handleBacktrace(const PdbResponse &response)
} }
} }
const int frameCount = stackFrames.size(); const int frameCount = stackFrames.size();
for (int i = 0; i != frameCount; ++i) for (int i = 0; i != frameCount; ++i)
stackFrames[i].level = frameCount - stackFrames[i].level - 1; stackFrames[i].level = frameCount - stackFrames[i].level - 1;
stackHandler()->setFrames(stackFrames); stackHandler()->setFrames(stackFrames);
// Select current frame. // Select current frame.
@@ -768,6 +811,8 @@ void PdbEngine::handleBacktrace(const PdbResponse &response)
stackHandler()->setCurrentIndex(currentIndex); stackHandler()->setCurrentIndex(currentIndex);
gotoLocation(stackFrames.at(currentIndex), true); gotoLocation(stackFrames.at(currentIndex), true);
} }
updateLocals();
} }
void PdbEngine::handleListLocals(const PdbResponse &response) void PdbEngine::handleListLocals(const PdbResponse &response)
@@ -792,14 +837,6 @@ void PdbEngine::handleListLocals(const PdbResponse &response)
handler->insertBulkData(list); handler->insertBulkData(list);
} }
void PdbEngine::handleLoadDumper(const PdbResponse &response)
{
Q_UNUSED(response);
//qDebug() << " DUMPERS LOADED '" << response.data << "'";
//continueInferior();
notifyInferiorSetupOk();
}
unsigned PdbEngine::debuggerCapabilities() const unsigned PdbEngine::debuggerCapabilities() const
{ {
return ReloadModuleCapability; return ReloadModuleCapability;

View File

@@ -105,6 +105,9 @@ private:
bool isSynchroneous() const { return true; } bool isSynchroneous() const { return true; }
void updateWatchData(const WatchData &data); void updateWatchData(const WatchData &data);
signals:
void outputReady(const QByteArray &data);
private: private:
QString errorMessage(QProcess::ProcessError error) const; QString errorMessage(QProcess::ProcessError error) const;
unsigned debuggerCapabilities() const; unsigned debuggerCapabilities() const;
@@ -113,10 +116,14 @@ private:
Q_SLOT void handlePdbError(QProcess::ProcessError error); Q_SLOT void handlePdbError(QProcess::ProcessError error);
Q_SLOT void readPdbStandardOutput(); Q_SLOT void readPdbStandardOutput();
Q_SLOT void readPdbStandardError(); Q_SLOT void readPdbStandardError();
Q_SLOT void handleOutput2(const QByteArray &data);
void handleResponse(const QByteArray &ba); void handleResponse(const QByteArray &ba);
void handleOutput(const QByteArray &data);
void updateAll(); void updateAll();
void updateLocals();
void handleUpdateAll(const PdbResponse &response); void handleUpdateAll(const PdbResponse &response);
void handleFirstCommand(const PdbResponse &response); void handleFirstCommand(const PdbResponse &response);
void handleExecuteDebuggerCommand(const PdbResponse &response);
typedef void (PdbEngine::*PdbCommandCallback) typedef void (PdbEngine::*PdbCommandCallback)
(const PdbResponse &response); (const PdbResponse &response);
@@ -139,7 +146,6 @@ private:
void handleListLocals(const PdbResponse &response); void handleListLocals(const PdbResponse &response);
void handleListModules(const PdbResponse &response); void handleListModules(const PdbResponse &response);
void handleListSymbols(const PdbResponse &response); void handleListSymbols(const PdbResponse &response);
void handleLoadDumper(const PdbResponse &response);
void handleBreakInsert(const PdbResponse &response); void handleBreakInsert(const PdbResponse &response);
void handleChildren(const WatchData &data0, const GdbMi &item, void handleChildren(const WatchData &data0, const GdbMi &item,
@@ -149,6 +155,7 @@ private:
PdbCommandCallback callback = 0, PdbCommandCallback callback = 0,
const char *callbackName = 0, const char *callbackName = 0,
const QVariant &cookie = QVariant()); const QVariant &cookie = QVariant());
void postDirectCommand(const QByteArray &command);
QQueue<PdbCommand> m_commands; QQueue<PdbCommand> m_commands;

View File

@@ -327,7 +327,8 @@ void ScriptEngine::importExtensions()
"Make sure that the bindings have been built, " "Make sure that the bindings have been built, "
"and that this executable and the plugins are " "and that this executable and the plugins are "
"using compatible Qt libraries.", "using compatible Qt libraries.",
qPrintable(failExtensions.join(QLatin1String(", "))), qPrintable(dir.absolutePath())); qPrintable(failExtensions.join(QLatin1String(", "))),
qPrintable(dir.absolutePath()));
} }
} }
return; // failExtensions.isEmpty(); return; // failExtensions.isEmpty();
@@ -336,12 +337,12 @@ void ScriptEngine::importExtensions()
void ScriptEngine::runEngine() void ScriptEngine::runEngine()
{ {
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
SDEBUG("ScriptEngine::runEngine()");
notifyEngineRunAndInferiorRunOk(); notifyEngineRunAndInferiorRunOk();
showStatusMessage(tr("Running requested..."), 5000); showStatusMessage(tr("Running requested..."), 5000);
showMessage(QLatin1String("Running: ") + m_scriptFileName, LogMisc); showMessage(QLatin1String("Running: ") + m_scriptFileName, LogMisc);
importExtensions(); importExtensions();
const QScriptValue result = m_scriptEngine->evaluate(m_scriptContents, m_scriptFileName); const QScriptValue result =
m_scriptEngine->evaluate(m_scriptContents, m_scriptFileName);
QString msg; QString msg;
if (m_scriptEngine->hasUncaughtException()) { if (m_scriptEngine->hasUncaughtException()) {
msg = _("An exception occurred during execution at line: %1\n%2\n") msg = _("An exception occurred during execution at line: %1\n%2\n")

View File

@@ -46,8 +46,8 @@ def testMath():
print cube(5) print cube(5)
def main(): def main():
#testMath() testMath()
testApp() #testApp()
return 0 return 0
if __name__ == '__main__': if __name__ == '__main__':