Commit b74ecbdb authored by Friedemann Kleint's avatar Friedemann Kleint

Debugger[New CDB]: Update all variables on assignment.

Some documentation/comment changes.
parent e32cd328
...@@ -46,8 +46,6 @@ ...@@ -46,8 +46,6 @@
#include <wdbgexts.h> #include <wdbgexts.h>
#include <dbgeng.h> #include <dbgeng.h>
static const char creatorOutputPrefixC[] = "QtCreatorExt: ";
typedef IDebugControl CIDebugControl; typedef IDebugControl CIDebugControl;
typedef IDebugSymbols3 CIDebugSymbols; typedef IDebugSymbols3 CIDebugSymbols;
typedef IDebugSymbolGroup2 CIDebugSymbolGroup; typedef IDebugSymbolGroup2 CIDebugSymbolGroup;
......
...@@ -37,8 +37,8 @@ ...@@ -37,8 +37,8 @@
#include "common.h" #include "common.h"
#include "extensioncontext.h" #include "extensioncontext.h"
/* IDebugEventCallbacks event handler wrapping IDebugEventCallbacks to catch some output */ /* IDebugEventCallbacks event handler wrapping the original IDebugEventCallbacks
* to catch and store exceptions (report crashes as stop reasons). */
class EventCallback : public IDebugEventCallbacks class EventCallback : public IDebugEventCallbacks
{ {
public: public:
......
...@@ -85,11 +85,11 @@ public: ...@@ -85,11 +85,11 @@ public:
// register as '.idle_cmd' to notify creator about stop // register as '.idle_cmd' to notify creator about stop
void notifyIdle(); void notifyIdle();
// Return symbol group for frame (cache as long as frame does not change). // Return symbol group for frame (cached as long as frame/thread do not change).
SymbolGroup *symbolGroup(CIDebugSymbols *symbols, ULONG threadId, int frame, std::string *errorMessage); SymbolGroup *symbolGroup(CIDebugSymbols *symbols, ULONG threadId, int frame, std::string *errorMessage);
int symbolGroupFrame() const; int symbolGroupFrame() const;
// Stop reason is reported with the next idle notification // Set a stop reason to be reported with the next idle notification (exception).
void setStopReason(const StopReasonMap &, const std::string &reason = std::string()); void setStopReason(const StopReasonMap &, const std::string &reason = std::string());
private: private:
...@@ -109,6 +109,7 @@ private: ...@@ -109,6 +109,7 @@ private:
}; };
// Context for extension commands to be instantiated on stack in a command handler. // Context for extension commands to be instantiated on stack in a command handler.
// Provides the IDebug objects on demand.
class ExtensionCommandContext class ExtensionCommandContext
{ {
ExtensionCommandContext(const ExtensionCommandContext&); ExtensionCommandContext(const ExtensionCommandContext&);
......
...@@ -34,10 +34,11 @@ ...@@ -34,10 +34,11 @@
#ifndef KNOWNTYPE_H #ifndef KNOWNTYPE_H
#define KNOWNTYPE_H #define KNOWNTYPE_H
// Helpers for detecting types // Enumeration describing a type.
enum KnownType enum KnownType
{ {
KT_Unknown =0, KT_Unknown =0,
// Flags to be used in type values.
KT_POD_Type = 0x10000, KT_POD_Type = 0x10000,
KT_Qt_Type = 0x20000, KT_Qt_Type = 0x20000,
KT_Qt_PrimitiveType = 0x40000, KT_Qt_PrimitiveType = 0x40000,
...@@ -46,7 +47,7 @@ enum KnownType ...@@ -46,7 +47,7 @@ enum KnownType
KT_ContainerType = 0x200000, KT_ContainerType = 0x200000,
KT_HasSimpleDumper = 0x400000, KT_HasSimpleDumper = 0x400000,
KT_HasComplexDumper = 0x800000, // Non-container complex dumper KT_HasComplexDumper = 0x800000, // Non-container complex dumper
// PODs // Types: PODs
KT_Char = KT_POD_Type + 1, KT_Char = KT_POD_Type + 1,
KT_UnsignedChar = KT_POD_Type + 2, KT_UnsignedChar = KT_POD_Type + 2,
KT_IntType = KT_POD_Type + 3, // any signed short, long, int KT_IntType = KT_POD_Type + 3, // any signed short, long, int
...@@ -54,7 +55,7 @@ enum KnownType ...@@ -54,7 +55,7 @@ enum KnownType
KT_FloatType = KT_POD_Type + 5, // float, double KT_FloatType = KT_POD_Type + 5, // float, double
KT_POD_PointerType = KT_POD_Type + 6, // pointer to some POD KT_POD_PointerType = KT_POD_Type + 6, // pointer to some POD
KT_PointerType = KT_POD_Type + 7, // pointer to class or complex type KT_PointerType = KT_POD_Type + 7, // pointer to class or complex type
// Qt Basic // Types: Qt Basic
KT_QChar = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 1, KT_QChar = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 1,
KT_QByteArray = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 2, KT_QByteArray = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 2,
KT_QString = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 3, KT_QString = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 3,
...@@ -75,7 +76,7 @@ enum KnownType ...@@ -75,7 +76,7 @@ enum KnownType
KT_QAtomicInt = KT_Qt_Type + KT_HasSimpleDumper + 19, KT_QAtomicInt = KT_Qt_Type + KT_HasSimpleDumper + 19,
KT_QObject = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 20, KT_QObject = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 20,
KT_QWidget = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 21, KT_QWidget = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 21,
// Various QT movable types // Types: Various QT movable types
KT_QPen = KT_Qt_Type + KT_Qt_MovableType + 30, KT_QPen = KT_Qt_Type + KT_Qt_MovableType + 30,
KT_QUrl = KT_Qt_Type + KT_Qt_MovableType + 31, KT_QUrl = KT_Qt_Type + KT_Qt_MovableType + 31,
KT_QIcon = KT_Qt_Type + KT_Qt_MovableType + 32, KT_QIcon = KT_Qt_Type + KT_Qt_MovableType + 32,
...@@ -134,7 +135,7 @@ enum KnownType ...@@ -134,7 +135,7 @@ enum KnownType
KT_QPatternist_ItemSequenceCacheCell = KT_Qt_Type + KT_Qt_MovableType + 86, KT_QPatternist_ItemSequenceCacheCell = KT_Qt_Type + KT_Qt_MovableType + 86,
KT_QNetworkHeadersPrivate_RawHeaderPair = KT_Qt_Type + KT_Qt_MovableType + 87, KT_QNetworkHeadersPrivate_RawHeaderPair = KT_Qt_Type + KT_Qt_MovableType + 87,
KT_QPatternist_AccelTree_BasicNodeData = KT_Qt_Type + KT_Qt_MovableType + 88, KT_QPatternist_AccelTree_BasicNodeData = KT_Qt_Type + KT_Qt_MovableType + 88,
// Qt primitive types // Types: Qt primitive types
KT_QFixed = KT_Qt_Type + KT_Qt_PrimitiveType + 90, KT_QFixed = KT_Qt_Type + KT_Qt_PrimitiveType + 90,
KT_QTextItem = KT_Qt_Type + KT_Qt_PrimitiveType + 91, KT_QTextItem = KT_Qt_Type + KT_Qt_PrimitiveType + 91,
KT_QFixedSize = KT_Qt_Type + KT_Qt_PrimitiveType + 92, KT_QFixedSize = KT_Qt_Type + KT_Qt_PrimitiveType + 92,
...@@ -144,7 +145,7 @@ enum KnownType ...@@ -144,7 +145,7 @@ enum KnownType
KT_QTextUndoCommand = KT_Qt_Type + KT_Qt_PrimitiveType + 96, KT_QTextUndoCommand = KT_Qt_Type + KT_Qt_PrimitiveType + 96,
KT_QGlyphJustification = KT_Qt_Type + KT_Qt_PrimitiveType + 97, KT_QGlyphJustification = KT_Qt_Type + KT_Qt_PrimitiveType + 97,
KT_QPainterPath_Element = KT_Qt_Type + KT_Qt_PrimitiveType + 98, KT_QPainterPath_Element = KT_Qt_Type + KT_Qt_PrimitiveType + 98,
// Qt Containers // Types: Qt Containers
KT_QStringList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 1, KT_QStringList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 1,
KT_QList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 2, KT_QList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 2,
KT_QLinkedList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 3, KT_QLinkedList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 3,
...@@ -156,10 +157,10 @@ enum KnownType ...@@ -156,10 +157,10 @@ enum KnownType
KT_QMultiHash = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 9, KT_QMultiHash = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 9,
KT_QMap = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 10, KT_QMap = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 10,
KT_QMultiMap = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 11, KT_QMultiMap = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 11,
// STL // Types: STL
KT_StdString = KT_STL_Type + KT_HasSimpleDumper + 1, KT_StdString = KT_STL_Type + KT_HasSimpleDumper + 1,
KT_StdWString = KT_STL_Type + KT_HasSimpleDumper + 2, KT_StdWString = KT_STL_Type + KT_HasSimpleDumper + 2,
// STL containers // Types: STL containers
KT_StdVector = KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 1, KT_StdVector = KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 1,
KT_StdList = KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 2, KT_StdList = KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 2,
KT_StdStack = KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 3, KT_StdStack = KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 3,
......
...@@ -97,6 +97,6 @@ STDMETHODIMP OutputCallback::Output( ...@@ -97,6 +97,6 @@ STDMETHODIMP OutputCallback::Output(
// Base encode as GDBMI is not really made for wide chars // Base encode as GDBMI is not really made for wide chars
std::ostringstream str; std::ostringstream str;
base64Encode(str, reinterpret_cast<const unsigned char *>(text), sizeof(wchar_t) * std::wcslen(text)); base64Encode(str, reinterpret_cast<const unsigned char *>(text), sizeof(wchar_t) * std::wcslen(text));
ExtensionContext::instance().report('E', 0, 0, "debuggee_output", str.str().c_str()); ExtensionContext::instance().reportLong('E', 0, "debuggee_output", str.str().c_str());
return S_OK; return S_OK;
} }
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include "common.h" #include "common.h"
/* OutputCallback catches DEBUG_OUTPUT_DEBUGGEE and reports it
* base64-encoded back to Qt Creator. */
class OutputCallback : public IDebugOutputCallbacksWide class OutputCallback : public IDebugOutputCallbacksWide
{ {
public: public:
......
...@@ -44,7 +44,8 @@ ...@@ -44,7 +44,8 @@
#include <list> #include <list>
#include <iterator> #include <iterator>
/* QtCreatorCDB ext is an extension loaded into CDB.exe (see cdbengine2.cpp): /* QtCreatorCDB ext is an extension loaded into CDB.exe (see cdbengine.cpp)
* providing:
* - Notification about the state of the debugging session: * - Notification about the state of the debugging session:
* + idle: (hooked with .idle_cmd) debuggee stopped * + idle: (hooked with .idle_cmd) debuggee stopped
* + accessible: Debuggee stopped, cdb.exe accepts commands * + accessible: Debuggee stopped, cdb.exe accepts commands
......
...@@ -39,11 +39,12 @@ ...@@ -39,11 +39,12 @@
#include <map> #include <map>
#include <functional> #include <functional>
void trimFront(std::string &s); void trimFront(std::string &s); // Strip blanks off front
void trimBack(std::string &s); void trimBack(std::string &s); // Strip blanks off back
// Simplify blanks, that is " A \tB " -> "A B".
void simplify(std::string &s); void simplify(std::string &s);
// Split by character separator. // Split a token sequence in a string by character separator.
template <class Iterator> template <class Iterator>
void split(const std::string &s, char sep, Iterator it) void split(const std::string &s, char sep, Iterator it)
{ {
......
...@@ -50,7 +50,9 @@ class SymbolGroup; ...@@ -50,7 +50,9 @@ class SymbolGroup;
struct SymbolGroupValueContext; struct SymbolGroupValueContext;
class SymbolGroupNode; class SymbolGroupNode;
// All parameters for GDBMI dumping in one struct. // All parameters for GDBMI dumping of a symbol group in one struct.
// The debugging engine passes maps of type names/inames to special
// integer values indicating hex/dec, etc.
struct DumpParameters struct DumpParameters
{ {
typedef std::map<std::string, int> FormatMap; // type or iname to format typedef std::map<std::string, int> FormatMap; // type or iname to format
...@@ -75,7 +77,7 @@ struct DumpParameters ...@@ -75,7 +77,7 @@ struct DumpParameters
FormatMap individualFormats; FormatMap individualFormats;
}; };
// Base class for a node of SymbolGroup, handling the list of children. // Abstract base class for a node of SymbolGroup providing the child list interface.
class AbstractSymbolGroupNode class AbstractSymbolGroupNode
{ {
AbstractSymbolGroupNode(const AbstractSymbolGroupNode&); AbstractSymbolGroupNode(const AbstractSymbolGroupNode&);
...@@ -93,7 +95,7 @@ public: ...@@ -93,7 +95,7 @@ public:
// 'iname' used as an internal id. // 'iname' used as an internal id.
const std::string &iName() const { return m_iname; } const std::string &iName() const { return m_iname; }
// Full iname 'local.x.foo': WARNING: this returns the absolute path not // Full iname 'local.x.foo': WARNING: this returns the absolute path not
// taking reference nodes into account. // taking reference nodes into account by recursing up the parents.
std::string absoluteFullIName() const; std::string absoluteFullIName() const;
virtual const AbstractSymbolGroupNodePtrVector &children() const = 0; virtual const AbstractSymbolGroupNodePtrVector &children() const = 0;
...@@ -169,11 +171,11 @@ private: ...@@ -169,11 +171,11 @@ private:
* consisting of: * consisting of:
* - 'Simple' dumping done when running the DumpVisitor. This produces one * - 'Simple' dumping done when running the DumpVisitor. This produces one
* line of formatted output shown for the class. These values * line of formatted output shown for the class. These values
* values should are displayed, while still allowing for expansion of the structure * values are always displayed, while still allowing for expansion of the structure
* in the debugger. * in the debugger.
* It also pre-determines some information for complex dumping (type, container). * It also pre-determines some information for complex dumping (type, container).
* - 'Complex' dumping: Obscures the symbol group children by fake children, for * - 'Complex' dumping: Obscures the symbol group children by fake children, for
* example container children, run when calling SymbolGroup::dump with an iname. * example container children, to be run when calling SymbolGroup::dump with an iname.
* The fake children are appended to the child list (other children are just marked as * The fake children are appended to the child list (other children are just marked as
* obscured for GDBMI dumping so that SymbolGroupValue expressions still work as before). * obscured for GDBMI dumping so that SymbolGroupValue expressions still work as before).
* The dumping is mostly based on SymbolGroupValue expressions. * The dumping is mostly based on SymbolGroupValue expressions.
...@@ -270,9 +272,9 @@ private: ...@@ -270,9 +272,9 @@ private:
}; };
// Artificial node referencing another (real) SymbolGroupNode (added symbol or // Artificial node referencing another (real) SymbolGroupNode (added symbol or
// symbol from within a linked list structure. Forwards dumping to referenced node // symbol from within an expanded linked list structure). Forwards the
// using its own name. // dumping to the referenced node using its own name.
class ReferenceSymbolGroupNode : public AbstractSymbolGroupNode class ReferenceSymbolGroupNode : public AbstractSymbolGroupNode
{ {
public: public:
explicit ReferenceSymbolGroupNode(const std::string &name, explicit ReferenceSymbolGroupNode(const std::string &name,
...@@ -296,7 +298,8 @@ private: ...@@ -296,7 +298,8 @@ private:
SymbolGroupNode * const m_referencedNode; SymbolGroupNode * const m_referencedNode;
}; };
// Base class for a [fake] map node with a fake array index and key/value entries. // A [fake] map node with a fake array index and key/value entries consisting
// of ReferenceSymbolGroupNode.
class MapNodeSymbolGroupNode : public BaseSymbolGroupNode class MapNodeSymbolGroupNode : public BaseSymbolGroupNode
{ {
private: private:
...@@ -329,7 +332,7 @@ private: ...@@ -329,7 +332,7 @@ private:
* or by expanding the whole structure). * or by expanding the whole structure).
* visit() is not called for the (invisible) root node, but starting with the * visit() is not called for the (invisible) root node, but starting with the
* root's children with depth=0. * root's children with depth=0.
* Return true from visit() to terminate the recursion. */ * Return VisitStop from visit() to terminate the recursion. */
class SymbolGroupNodeVisitor { class SymbolGroupNodeVisitor {
SymbolGroupNodeVisitor(const SymbolGroupNodeVisitor&); SymbolGroupNodeVisitor(const SymbolGroupNodeVisitor&);
...@@ -392,7 +395,8 @@ private: ...@@ -392,7 +395,8 @@ private:
const std::string m_filter; const std::string m_filter;
}; };
// GDBMI dump output visitor. // GDBMI dump output visitor used to report locals values back to the
// debugging engine.
class DumpSymbolGroupNodeVisitor : public SymbolGroupNodeVisitor { class DumpSymbolGroupNodeVisitor : public SymbolGroupNodeVisitor {
public: public:
explicit DumpSymbolGroupNodeVisitor(std::ostream &os, explicit DumpSymbolGroupNodeVisitor(std::ostream &os,
......
...@@ -45,7 +45,7 @@ class AbstractSymbolGroupNode; ...@@ -45,7 +45,7 @@ class AbstractSymbolGroupNode;
class SymbolGroupNode; class SymbolGroupNode;
class SymbolGroup; class SymbolGroup;
// Structure to pass all IDebug interfaces used for SymbolGroupValue // Structure to pass all IDebug interfaces required for SymbolGroupValue
struct SymbolGroupValueContext struct SymbolGroupValueContext
{ {
SymbolGroupValueContext(CIDebugDataSpaces *ds, CIDebugSymbols *s) : dataspaces(ds), symbols(s) {} SymbolGroupValueContext(CIDebugDataSpaces *ds, CIDebugSymbols *s) : dataspaces(ds), symbols(s) {}
...@@ -56,8 +56,14 @@ struct SymbolGroupValueContext ...@@ -56,8 +56,14 @@ struct SymbolGroupValueContext
}; };
/* SymbolGroupValue: Flyweight tied to a SymbolGroupNode /* SymbolGroupValue: Flyweight tied to a SymbolGroupNode
* providing a convenient operator[] + value getters for notation of dumpers. * providing a convenient operator[] (name, index) and value
* Inaccesible members return a SymbolGroupValue in state 'invalid'. */ * getters for notation of dumpers.
* Inaccessible members return a SymbolGroupValue in state 'invalid'.
* Example:
* SymbolGroupValue container(symbolGroupNode, symbolGroupValueContext);
* if (SymbolGroupValue sizeV = container["d"]["size"])
* int size = sizeV.intValue()
* etc. */
class SymbolGroupValue class SymbolGroupValue
{ {
...@@ -141,7 +147,8 @@ private: ...@@ -141,7 +147,8 @@ private:
// For debugging purposes // For debugging purposes
std::ostream &operator<<(std::ostream &, const SymbolGroupValue &v); std::ostream &operator<<(std::ostream &, const SymbolGroupValue &v);
// Qt Information: Namespace and module. // Qt Information determined on demand: Namespace, modules and basic class
// names containing the module for fast lookup.
struct QtInfo struct QtInfo
{ {
static const QtInfo &get(const SymbolGroupValueContext &ctx); static const QtInfo &get(const SymbolGroupValueContext &ctx);
...@@ -196,6 +203,7 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx, ...@@ -196,6 +203,7 @@ unsigned dumpSimpleType(SymbolGroupNode *n, const SymbolGroupValueContext &ctx,
int *containerSizeIn = 0, int *containerSizeIn = 0,
void **specialInfoIn = 0); void **specialInfoIn = 0);
// Non-container complex dumpers (QObjects/QVariants).
std::vector<AbstractSymbolGroupNode *> std::vector<AbstractSymbolGroupNode *>
dumpComplexType(SymbolGroupNode *node, int type, void *specialInfo, dumpComplexType(SymbolGroupNode *node, int type, void *specialInfo,
const SymbolGroupValueContext &ctx); const SymbolGroupValueContext &ctx);
......
...@@ -95,29 +95,30 @@ enum { debugBreakpoints = 0 }; ...@@ -95,29 +95,30 @@ enum { debugBreakpoints = 0 };
/* CdbEngine version 2: Run the CDB process on pipes and parse its output. /* CdbEngine version 2: Run the CDB process on pipes and parse its output.
* The engine relies on a CDB extension Qt Creator provides as an extension * The engine relies on a CDB extension Qt Creator provides as an extension
* library (32/64bit). It serves to: * library (32/64bit), which is loaded into cdb.exe. It serves to:
* - Notify the engine about the state of the debugging session: * - Notify the engine about the state of the debugging session:
* + idle: (hooked with .idle_cmd) debuggee stopped * + idle: (hooked up with .idle_cmd) debuggee stopped
* + accessible: Debuggee stopped, cdb.exe accepts commands * + accessible: Debuggee stopped, cdb.exe accepts commands
* + inaccessible: Debuggee runs, no way to post commands * + inaccessible: Debuggee runs, no way to post commands
* + session active/inactive: Lost debuggee, terminating. * + session active/inactive: Lost debuggee, terminating.
* - Hook up with output/event callbacks and produce formatted output * - Hook up with output/event callbacks and produce formatted output to be able
* to catch application output and exceptions.
* - Provide some extension commands that produce output in a standardized (GDBMI) * - Provide some extension commands that produce output in a standardized (GDBMI)
* format that ends up in handleExtensionMessage(). * format that ends up in handleExtensionMessage().
* + pid Return debuggee pid for interrupting. * + pid Return debuggee pid for interrupting.
* + locals Print locals from SymbolGroup * + locals Print locals from SymbolGroup
* + expandLocals Expand locals in symbol group * + expandLocals Expand locals in symbol group
* + registers, modules, threads * + registers, modules, threads
* Commands can be posted: * Commands can be posted by calling:
* postCommand: Does not expect a reply * 1) postCommand(): Does not expect a reply
* postBuiltinCommand: Run a builtin-command producing free-format, multiline output * 2) postBuiltinCommand(): Run a builtin-command producing free-format, multiline output
* that is captured by enclosing it in special tokens using the 'echo' command and * that is captured by enclosing it in special tokens using the 'echo' command and
* then invokes a callback with a CdbBuiltinCommand structure. * then invokes a callback with a CdbBuiltinCommand structure.
* postExtensionCommand: Run a command provided by the extension producing * 3) postExtensionCommand(): Run a command provided by the extension producing
* one-line output and invoke a callback with a CdbExtensionCommand structure. */ * one-line output and invoke a callback with a CdbExtensionCommand structure
* (output is potentially split up in chunks). */
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Debugger::Internal;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
...@@ -899,7 +900,9 @@ void CdbEngine::assignValueInDebugger(const WatchData *w, const QString &expr, c ...@@ -899,7 +900,9 @@ void CdbEngine::assignValueInDebugger(const WatchData *w, const QString &expr, c
ByteArrayInputStream str(cmd); ByteArrayInputStream str(cmd);
str << m_extensionCommandPrefixBA << "assign " << w->iname << '=' << value.toString(); str << m_extensionCommandPrefixBA << "assign " << w->iname << '=' << value.toString();
postCommand(cmd, 0); postCommand(cmd, 0);
updateLocalVariable(w->iname); // Update all locals in case we change a union or something pointed to
// that affects other variables, too.
updateLocals();
} }
void CdbEngine::handleThreads(const CdbExtensionCommandPtr &reply) void CdbEngine::handleThreads(const CdbExtensionCommandPtr &reply)
...@@ -1034,9 +1037,26 @@ void CdbEngine::activateFrame(int index) ...@@ -1034,9 +1037,26 @@ void CdbEngine::activateFrame(int index)
} else { } else {
assemblerAction->trigger(); // Seems to trigger update assemblerAction->trigger(); // Seems to trigger update
} }
} else {
gotoLocation(frame);
updateLocals();
}
}
void CdbEngine::updateLocals()
{
const int frameIndex = stackHandler()->currentIndex();
if (frameIndex < 0) {
watchHandler()->beginCycle();
watchHandler()->endCycle();
return;
}
const StackFrame frame = stackHandler()->currentFrame();
if (!frame.isUsable()) {
watchHandler()->beginCycle();
watchHandler()->endCycle();
return; return;
} }
gotoLocation(frame);
// Watchers: Initial expand, get uninitialized and query // Watchers: Initial expand, get uninitialized and query
QByteArray arguments; QByteArray arguments;
ByteArrayInputStream str(arguments); ByteArrayInputStream str(arguments);
...@@ -1068,7 +1088,7 @@ void CdbEngine::activateFrame(int index) ...@@ -1068,7 +1088,7 @@ void CdbEngine::activateFrame(int index)
} }
} }
// Required arguments: frame // Required arguments: frame
str << blankSeparator << index; str << blankSeparator << frameIndex;
watchHandler()->beginCycle(); watchHandler()->beginCycle();
postExtensionCommand("locals", arguments, 0, &CdbEngine::handleLocals); postExtensionCommand("locals", arguments, 0, &CdbEngine::handleLocals);
} }
......
...@@ -179,6 +179,7 @@ private: ...@@ -179,6 +179,7 @@ private:
QString normalizeFileName(const QString &f); QString normalizeFileName(const QString &f);
void updateLocalVariable(const QByteArray &iname); void updateLocalVariable(const QByteArray &iname);
void updateLocals();
int elapsedLogTime() const; int elapsedLogTime() const;
void addLocalsOptions(ByteArrayInputStream &s) const; void addLocalsOptions(ByteArrayInputStream &s) const;
......
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