forked from qt-creator/qt-creator
debugger: workaround failing 'info locals' on gdb 6.8-symbianelf
This commit is contained in:
@@ -32,8 +32,8 @@ def isGoodGdb():
|
|||||||
return 'parse_and_eval' in dir(gdb)
|
return 'parse_and_eval' in dir(gdb)
|
||||||
|
|
||||||
def cleanAddress(addr):
|
def cleanAddress(addr):
|
||||||
# we cannot use str(addr) as it yields rubbish for char pointers
|
# We cannot use str(addr) as it yields rubbish for char pointers
|
||||||
# that might trigger Unicode encoding errors
|
# that might trigger Unicode encoding errors.
|
||||||
return addr.cast(gdb.lookup_type("void").pointer())
|
return addr.cast(gdb.lookup_type("void").pointer())
|
||||||
|
|
||||||
def parseAndEvaluate(exp):
|
def parseAndEvaluate(exp):
|
||||||
@@ -50,17 +50,27 @@ def parseAndEvaluate(exp):
|
|||||||
gdb.execute("set logging off")
|
gdb.execute("set logging off")
|
||||||
return gdb.history(0)
|
return gdb.history(0)
|
||||||
|
|
||||||
def listOfLocals():
|
def listOfLocals(varList):
|
||||||
try:
|
try:
|
||||||
frame = gdb.selected_frame()
|
frame = gdb.selected_frame()
|
||||||
#warn("FRAME %s: " % frame)
|
#warn("FRAME %s: " % frame)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
|
warn("FRAME NOT ACCESSIBLE")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
# gdb-6.8-symbianelf fails here
|
||||||
|
hasBlock = 'block' in dir(frame)
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
if isGoodGdb():
|
if hasBlock and isGoodGdb():
|
||||||
# archer-tromey-python
|
warn("IS GOOD: %s " % varList)
|
||||||
block = frame.block()
|
try:
|
||||||
|
block = frame.block()
|
||||||
|
#warn("BLOCK: %s " % block)
|
||||||
|
except:
|
||||||
|
warn("BLOCK NOT ACCESSIBLE")
|
||||||
|
return items
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if block is None:
|
if block is None:
|
||||||
warn("UNEXPECTED 'None' BLOCK")
|
warn("UNEXPECTED 'None' BLOCK")
|
||||||
@@ -94,31 +104,55 @@ def listOfLocals():
|
|||||||
# Assuming gdb 7.0 release or 6.8-symbianelf.
|
# Assuming gdb 7.0 release or 6.8-symbianelf.
|
||||||
file = tempfile.mkstemp(prefix="gdbpy_")
|
file = tempfile.mkstemp(prefix="gdbpy_")
|
||||||
filename = file[1]
|
filename = file[1]
|
||||||
|
#warn("VARLIST: %s " % varList)
|
||||||
|
#warn("VARLIST: %s " % len(varList))
|
||||||
gdb.execute("set logging off")
|
gdb.execute("set logging off")
|
||||||
gdb.execute("set logging redirect off")
|
gdb.execute("set logging redirect off")
|
||||||
gdb.execute("set logging file %s" % filename)
|
gdb.execute("set logging file %s" % filename)
|
||||||
gdb.execute("set logging redirect on")
|
gdb.execute("set logging redirect on")
|
||||||
gdb.execute("set logging on")
|
gdb.execute("set logging on")
|
||||||
gdb.execute("info locals")
|
try:
|
||||||
gdb.execute("info args")
|
gdb.execute("info args")
|
||||||
|
# We cannot use "info locals" as at least 6.8-symbianelf
|
||||||
|
# aborts as soon as we hit unreadable memory.
|
||||||
|
# gdb.execute("interpreter mi '-stack-list-locals 0'")
|
||||||
|
# results in &"Recursive internal problem.\n", so we have
|
||||||
|
# the frontend pass us the list of locals.
|
||||||
|
|
||||||
|
# There are two cases, either varList is empty, so we have
|
||||||
|
# to fetch the list here, or it is not empty with the
|
||||||
|
# first entry being a dummy.
|
||||||
|
if len(varList) == 0:
|
||||||
|
gdb.execute("info locals")
|
||||||
|
else:
|
||||||
|
varList = varList[1:]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
gdb.execute("set logging off")
|
gdb.execute("set logging off")
|
||||||
gdb.execute("set logging redirect off")
|
gdb.execute("set logging redirect off")
|
||||||
|
|
||||||
file = open(filename, "r")
|
file = open(filename, "r")
|
||||||
for line in file:
|
for line in file:
|
||||||
if len(line) == 0 or line.startswith(" "):
|
if len(line) == 0 or line.startswith(" "):
|
||||||
continue
|
continue
|
||||||
|
# The function parameters
|
||||||
pos = line.find(" = ")
|
pos = line.find(" = ")
|
||||||
if pos < 0:
|
if pos < 0:
|
||||||
continue
|
continue
|
||||||
name = line[0:pos]
|
varList.append(line[0:pos])
|
||||||
|
file.close()
|
||||||
|
os.remove(filename)
|
||||||
|
|
||||||
|
#warn("VARLIST: %s " % varList)
|
||||||
|
for name in varList:
|
||||||
|
#warn("NAME %s " % name)
|
||||||
item = Item(0, "local", name, name)
|
item = Item(0, "local", name, name)
|
||||||
try:
|
try:
|
||||||
item.value = frame.read_var(name) # this is a gdb value
|
item.value = frame.read_var(name) # this is a gdb value
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
continue
|
pass
|
||||||
|
#continue
|
||||||
items.append(item)
|
items.append(item)
|
||||||
file.close()
|
|
||||||
os.remove(filename)
|
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
|
||||||
@@ -155,8 +189,8 @@ def isStringType(d, typeobj):
|
|||||||
or type == "wstring"
|
or type == "wstring"
|
||||||
|
|
||||||
def warn(message):
|
def warn(message):
|
||||||
if verbosity > 0:
|
if True or verbosity > 0:
|
||||||
print "XXX: %s " % message.encode("latin1")
|
print "XXX: %s\n" % message.encode("latin1")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def check(exp):
|
def check(exp):
|
||||||
@@ -317,13 +351,24 @@ class FrameCommand(gdb.Command):
|
|||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
args = arg.split(' ')
|
args = arg.split(' ')
|
||||||
|
|
||||||
#warn("ARG: %s" % arg)
|
#warn("ARG: %s" % arg)
|
||||||
#warn("ARGS: %s" % args)
|
#warn("ARGS: %s" % args)
|
||||||
options = args[0].split(",")
|
options = args[0].split(",")
|
||||||
|
varList = args[1][1:]
|
||||||
|
if len(varList) == 0:
|
||||||
|
varList = []
|
||||||
|
else:
|
||||||
|
varList = varList.split(",")
|
||||||
|
expandedINames = set(args[2].split(","))
|
||||||
|
watchers = ""
|
||||||
|
if len(args) > 3:
|
||||||
|
watchers = base64.b16decode(args[3], True)
|
||||||
|
#warn("WATCHERS: %s" % watchers)
|
||||||
|
|
||||||
useFancy = "fancy" in options
|
useFancy = "fancy" in options
|
||||||
expandedINames = set()
|
|
||||||
if len(args) > 1:
|
#warn("VARIABLES: %s" % varList)
|
||||||
expandedINames = set(args[1].split(","))
|
|
||||||
#warn("EXPANDED INAMES: %s" % expandedINames)
|
#warn("EXPANDED INAMES: %s" % expandedINames)
|
||||||
module = sys.modules[__name__]
|
module = sys.modules[__name__]
|
||||||
self.dumpers = {}
|
self.dumpers = {}
|
||||||
@@ -337,7 +382,7 @@ class FrameCommand(gdb.Command):
|
|||||||
output += '"' + key[7:] + '"'
|
output += '"' + key[7:] + '"'
|
||||||
output += "],"
|
output += "],"
|
||||||
#output += "qtversion=[%d,%d,%d]"
|
#output += "qtversion=[%d,%d,%d]"
|
||||||
output += "qtversion=[4,6,0],"
|
#output += "qtversion=[4,6,0],"
|
||||||
output += "namespace=\"%s\"," % qtNamespace()
|
output += "namespace=\"%s\"," % qtNamespace()
|
||||||
output += "dumperversion=\"2.0\","
|
output += "dumperversion=\"2.0\","
|
||||||
output += "sizes=[],"
|
output += "sizes=[],"
|
||||||
@@ -349,7 +394,6 @@ class FrameCommand(gdb.Command):
|
|||||||
|
|
||||||
if useFancy:
|
if useFancy:
|
||||||
for key, value in module.__dict__.items():
|
for key, value in module.__dict__.items():
|
||||||
#if callable(value):
|
|
||||||
if key.startswith("qdump__"):
|
if key.startswith("qdump__"):
|
||||||
self.dumpers[key[7:]] = value
|
self.dumpers[key[7:]] = value
|
||||||
|
|
||||||
@@ -365,14 +409,28 @@ class FrameCommand(gdb.Command):
|
|||||||
#
|
#
|
||||||
# Locals
|
# Locals
|
||||||
#
|
#
|
||||||
for item in listOfLocals():
|
for item in listOfLocals(varList):
|
||||||
#warn("ITEM NAME %s: " % item.name)
|
#warn("ITEM NAME %s: " % item.name)
|
||||||
#warn("ITEM VALUE %s: " % item.value)
|
try:
|
||||||
|
#warn("ITEM VALUE %s: " % item.value)
|
||||||
|
# Throw on funny stuff, catch below.
|
||||||
|
dummy = str(item.value)
|
||||||
|
except:
|
||||||
|
# Locals with failing memory access.
|
||||||
|
d.beginHash()
|
||||||
|
d.put('iname="%s",' % item.iname)
|
||||||
|
d.put('name="%s",' % item.name)
|
||||||
|
d.put('addr="<not accessible>",')
|
||||||
|
d.put('value="<not accessible>",')
|
||||||
|
d.put('type="%s",' % item.value.type)
|
||||||
|
d.put('numchild="0"');
|
||||||
|
d.endHash()
|
||||||
|
continue
|
||||||
|
|
||||||
type = item.value.type
|
type = item.value.type
|
||||||
if type.code == gdb.TYPE_CODE_PTR \
|
if type.code == gdb.TYPE_CODE_PTR \
|
||||||
and item.name == "argv" and str(type) == "char **":
|
and item.name == "argv" and str(type) == "char **":
|
||||||
# Special handling for char** argv:
|
# Special handling for char** argv.
|
||||||
n = 0
|
n = 0
|
||||||
p = item.value
|
p = item.value
|
||||||
while not isNull(p.dereference()) and n <= 100:
|
while not isNull(p.dereference()) and n <= 100:
|
||||||
@@ -398,7 +456,7 @@ class FrameCommand(gdb.Command):
|
|||||||
d.endHash()
|
d.endHash()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# A "normal" local variable or parameter
|
# A "normal" local variable or parameter.
|
||||||
try:
|
try:
|
||||||
addr = cleanAddress(item.value.address)
|
addr = cleanAddress(item.value.address)
|
||||||
d.beginHash()
|
d.beginHash()
|
||||||
@@ -407,9 +465,8 @@ class FrameCommand(gdb.Command):
|
|||||||
d.safePutItemHelper(item)
|
d.safePutItemHelper(item)
|
||||||
d.endHash()
|
d.endHash()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# thrown by cleanAddreas with message
|
# Thrown by cleanAddress with message "'NoneType' object
|
||||||
# "'NoneType' object has no attribute 'cast'"
|
# has no attribute 'cast'" for optimized-out values.
|
||||||
# for optimized-out values
|
|
||||||
d.beginHash()
|
d.beginHash()
|
||||||
d.put('iname="%s",' % item.iname)
|
d.put('iname="%s",' % item.iname)
|
||||||
d.put('name="%s",' % item.name)
|
d.put('name="%s",' % item.name)
|
||||||
@@ -426,9 +483,6 @@ class FrameCommand(gdb.Command):
|
|||||||
# Watchers
|
# Watchers
|
||||||
#
|
#
|
||||||
d.safeoutput = ""
|
d.safeoutput = ""
|
||||||
watchers = ""
|
|
||||||
if len(args) > 2:
|
|
||||||
watchers = base64.b16decode(args[2], True)
|
|
||||||
if len(watchers) > 0:
|
if len(watchers) > 0:
|
||||||
for watcher in watchers.split("##"):
|
for watcher in watchers.split("##"):
|
||||||
(exp, iname) = watcher.split("#")
|
(exp, iname) = watcher.split("#")
|
||||||
@@ -764,7 +818,8 @@ class Dumper:
|
|||||||
#warn("REAL VALUE: %s " % item.value)
|
#warn("REAL VALUE: %s " % item.value)
|
||||||
#try:
|
#try:
|
||||||
# warn("REAL VALUE: %s " % item.value)
|
# warn("REAL VALUE: %s " % item.value)
|
||||||
#except UnicodeEncodeError:
|
#except:
|
||||||
|
# #UnicodeEncodeError:
|
||||||
# warn("REAL VALUE: <unprintable>")
|
# warn("REAL VALUE: <unprintable>")
|
||||||
|
|
||||||
value = item.value
|
value = item.value
|
||||||
|
@@ -743,7 +743,7 @@ void GdbEngine::postCommand(const QByteArray &command, GdbCommandFlags flags,
|
|||||||
void GdbEngine::postCommandHelper(const GdbCommand &cmd)
|
void GdbEngine::postCommandHelper(const GdbCommand &cmd)
|
||||||
{
|
{
|
||||||
if (!stateAcceptsGdbCommands(state())) {
|
if (!stateAcceptsGdbCommands(state())) {
|
||||||
PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + cmd.command);
|
PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: " + cmd.command));
|
||||||
debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: %1 %2")
|
debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: %1 %2")
|
||||||
.arg(_(cmd.command)).arg(state()));
|
.arg(_(cmd.command)).arg(state()));
|
||||||
return;
|
return;
|
||||||
@@ -1019,6 +1019,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
|
|||||||
// Called from CoreAdapter and AttachAdapter
|
// Called from CoreAdapter and AttachAdapter
|
||||||
void GdbEngine::updateAll()
|
void GdbEngine::updateAll()
|
||||||
{
|
{
|
||||||
|
PENDING_DEBUG("UPDATING ALL\n");
|
||||||
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/);
|
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/);
|
||||||
tryLoadDebuggingHelpers();
|
tryLoadDebuggingHelpers();
|
||||||
reloadModulesInternal();
|
reloadModulesInternal();
|
||||||
@@ -2469,12 +2470,14 @@ void GdbEngine::handleStackSelectThread(const GdbResponse &)
|
|||||||
|
|
||||||
void GdbEngine::reloadFullStack()
|
void GdbEngine::reloadFullStack()
|
||||||
{
|
{
|
||||||
|
PENDING_DEBUG("RELOAD FULL STACK");
|
||||||
postCommand("-stack-list-frames", WatchUpdate, CB(handleStackListFrames),
|
postCommand("-stack-list-frames", WatchUpdate, CB(handleStackListFrames),
|
||||||
QVariant::fromValue<StackCookie>(StackCookie(true, true)));
|
QVariant::fromValue<StackCookie>(StackCookie(true, true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::reloadStack(bool forceGotoLocation)
|
void GdbEngine::reloadStack(bool forceGotoLocation)
|
||||||
{
|
{
|
||||||
|
PENDING_DEBUG("RELOAD STACK");
|
||||||
QByteArray cmd = "-stack-list-frames";
|
QByteArray cmd = "-stack-list-frames";
|
||||||
int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt();
|
int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt();
|
||||||
if (stackDepth && !m_gdbAdapter->isTrkAdapter())
|
if (stackDepth && !m_gdbAdapter->isTrkAdapter())
|
||||||
@@ -2485,6 +2488,7 @@ void GdbEngine::reloadStack(bool forceGotoLocation)
|
|||||||
// access the memory belonging to the lower frames. But as we know
|
// access the memory belonging to the lower frames. But as we know
|
||||||
// this sometimes happens, ask the second time immediately instead
|
// this sometimes happens, ask the second time immediately instead
|
||||||
// of waiting for the first request to fail.
|
// of waiting for the first request to fail.
|
||||||
|
// FIXME: Seems to work with 6.8.
|
||||||
if (m_gdbAdapter->isTrkAdapter())
|
if (m_gdbAdapter->isTrkAdapter())
|
||||||
postCommand(cmd, WatchUpdate);
|
postCommand(cmd, WatchUpdate);
|
||||||
postCommand(cmd, WatchUpdate, CB(handleStackListFrames),
|
postCommand(cmd, WatchUpdate, CB(handleStackListFrames),
|
||||||
@@ -3640,52 +3644,12 @@ void GdbEngine::updateLocals(const QVariant &cookie)
|
|||||||
{
|
{
|
||||||
m_pendingRequests = 0;
|
m_pendingRequests = 0;
|
||||||
if (isSynchroneous()) {
|
if (isSynchroneous()) {
|
||||||
m_processedNames.clear();
|
if (m_gdbAdapter->isTrkAdapter()) {
|
||||||
manager()->watchHandler()->beginCycle();
|
postCommand("-stack-list-locals 0",
|
||||||
//m_toolTipExpression.clear();
|
WatchUpdate, CB(handleStackListLocals0));
|
||||||
WatchHandler *handler = m_manager->watchHandler();
|
} else {
|
||||||
|
updateLocalsSync(QByteArray());
|
||||||
QByteArray expanded;
|
|
||||||
QSet<QByteArray> expandedINames = handler->expandedINames();
|
|
||||||
QSetIterator<QByteArray> jt(expandedINames);
|
|
||||||
while (jt.hasNext()) {
|
|
||||||
expanded.append(jt.next());
|
|
||||||
expanded.append(',');
|
|
||||||
}
|
}
|
||||||
if (expanded.isEmpty())
|
|
||||||
expanded.append("defaults,");
|
|
||||||
expanded.chop(1);
|
|
||||||
|
|
||||||
QByteArray watchers;
|
|
||||||
if (!m_toolTipExpression.isEmpty())
|
|
||||||
watchers += m_toolTipExpression.toLatin1()
|
|
||||||
+ "#" + tooltipINameForExpression(m_toolTipExpression.toLatin1());
|
|
||||||
|
|
||||||
QHash<QByteArray, int> watcherNames = handler->watcherNames();
|
|
||||||
QHashIterator<QByteArray, int> it(watcherNames);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
it.next();
|
|
||||||
if (!watchers.isEmpty())
|
|
||||||
watchers += "##";
|
|
||||||
if (it.key() == WatchHandler::watcherEditPlaceHolder().toLatin1())
|
|
||||||
watchers += "<Edit>#watch." + QByteArray::number(it.value());
|
|
||||||
else
|
|
||||||
watchers += it.key() + "#watch." + QByteArray::number(it.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray options;
|
|
||||||
if (theDebuggerBoolSetting(UseDebuggingHelpers))
|
|
||||||
options += "fancy,";
|
|
||||||
if (theDebuggerBoolSetting(AutoDerefPointers))
|
|
||||||
options += "autoderef,";
|
|
||||||
if (options.isEmpty())
|
|
||||||
options += "defaults,";
|
|
||||||
options.chop(1);
|
|
||||||
|
|
||||||
postCommand("-interpreter-exec console \"bb "
|
|
||||||
+ options + ' ' + expanded + ' ' + watchers.toHex() + '"',
|
|
||||||
Discardable,
|
|
||||||
CB(handleStackFrame));
|
|
||||||
} else {
|
} else {
|
||||||
m_processedNames.clear();
|
m_processedNames.clear();
|
||||||
|
|
||||||
@@ -3710,6 +3674,69 @@ void GdbEngine::updateLocals(const QVariant &cookie)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GdbEngine::handleStackListLocals0(const GdbResponse &response)
|
||||||
|
{
|
||||||
|
if (response.resultClass == GdbResultDone) {
|
||||||
|
// 44^done,data={locals=[name="model",name="backString",...]}
|
||||||
|
QByteArray varList = "vars"; // Dummy entry, will be stripped by dumper.
|
||||||
|
foreach (const GdbMi &child, response.data.findChild("locals").children()) {
|
||||||
|
varList.append(',');
|
||||||
|
varList.append(child.data());
|
||||||
|
}
|
||||||
|
updateLocalsSync(varList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GdbEngine::updateLocalsSync(const QByteArray &varList)
|
||||||
|
{
|
||||||
|
m_processedNames.clear();
|
||||||
|
manager()->watchHandler()->beginCycle();
|
||||||
|
//m_toolTipExpression.clear();
|
||||||
|
WatchHandler *handler = m_manager->watchHandler();
|
||||||
|
|
||||||
|
QByteArray expanded;
|
||||||
|
QSet<QByteArray> expandedINames = handler->expandedINames();
|
||||||
|
QSetIterator<QByteArray> jt(expandedINames);
|
||||||
|
while (jt.hasNext()) {
|
||||||
|
expanded.append(jt.next());
|
||||||
|
expanded.append(',');
|
||||||
|
}
|
||||||
|
if (expanded.isEmpty())
|
||||||
|
expanded.append("defaults,");
|
||||||
|
expanded.chop(1);
|
||||||
|
|
||||||
|
QByteArray watchers;
|
||||||
|
if (!m_toolTipExpression.isEmpty())
|
||||||
|
watchers += m_toolTipExpression.toLatin1()
|
||||||
|
+ "#" + tooltipINameForExpression(m_toolTipExpression.toLatin1());
|
||||||
|
|
||||||
|
QHash<QByteArray, int> watcherNames = handler->watcherNames();
|
||||||
|
QHashIterator<QByteArray, int> it(watcherNames);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
if (!watchers.isEmpty())
|
||||||
|
watchers += "##";
|
||||||
|
if (it.key() == WatchHandler::watcherEditPlaceHolder().toLatin1())
|
||||||
|
watchers += "<Edit>#watch." + QByteArray::number(it.value());
|
||||||
|
else
|
||||||
|
watchers += it.key() + "#watch." + QByteArray::number(it.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray options;
|
||||||
|
if (theDebuggerBoolSetting(UseDebuggingHelpers))
|
||||||
|
options += "fancy,";
|
||||||
|
if (theDebuggerBoolSetting(AutoDerefPointers))
|
||||||
|
options += "autoderef,";
|
||||||
|
if (options.isEmpty())
|
||||||
|
options += "defaults,";
|
||||||
|
options.chop(1);
|
||||||
|
|
||||||
|
postCommand("bb " + options + " @" + varList + ' '
|
||||||
|
+ expanded + ' ' + watchers.toHex(),
|
||||||
|
WatchUpdate, CB(handleStackFrame));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GdbEngine::handleStackFrame(const GdbResponse &response)
|
void GdbEngine::handleStackFrame(const GdbResponse &response)
|
||||||
{
|
{
|
||||||
if (response.resultClass == GdbResultDone) {
|
if (response.resultClass == GdbResultDone) {
|
||||||
|
@@ -450,6 +450,7 @@ private: ////////// View & Data Stuff //////////
|
|||||||
|
|
||||||
void updateLocals(const QVariant &cookie = QVariant());
|
void updateLocals(const QVariant &cookie = QVariant());
|
||||||
void handleStackListLocals(const GdbResponse &response);
|
void handleStackListLocals(const GdbResponse &response);
|
||||||
|
void handleStackListLocals0(const GdbResponse &response);
|
||||||
WatchData localVariable(const GdbMi &item,
|
WatchData localVariable(const GdbMi &item,
|
||||||
const QStringList &uninitializedVariables,
|
const QStringList &uninitializedVariables,
|
||||||
QMap<QByteArray, int> *seen);
|
QMap<QByteArray, int> *seen);
|
||||||
@@ -484,6 +485,8 @@ private: ////////// Convenience Functions //////////
|
|||||||
int buttons = 0);
|
int buttons = 0);
|
||||||
void debugMessage(const QString &msg);
|
void debugMessage(const QString &msg);
|
||||||
QMainWindow *mainWindow() const;
|
QMainWindow *mainWindow() const;
|
||||||
|
|
||||||
|
void updateLocalsSync(const QByteArray &varList);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
Reference in New Issue
Block a user