forked from qt-creator/qt-creator
Debugger[New CDB]: Update all variables on assignment.
Some documentation/comment changes.
This commit is contained in:
@@ -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 @@
|
|||||||
#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:
|
|||||||
// 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:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 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 @@
|
|||||||
#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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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(
|
|||||||
// 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 @@
|
|||||||
|
|
||||||
#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 @@
|
|||||||
#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 @@
|
|||||||
#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;
|
|||||||
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
|
|||||||
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:
|
|||||||
// '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:
|
|||||||
* 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,8 +272,8 @@ 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:
|
||||||
@@ -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:
|
|||||||
* 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:
|
|||||||
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;
|
|||||||
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
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* 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:
|
|||||||
// 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,
|
|||||||
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 };
|
|||||||
|
|
||||||
/* 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
|
|||||||
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)
|
|||||||
} 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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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:
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user