forked from qt-creator/qt-creator
Debugger: Documentation work on qtcreatorcdbext/Debugger.
Add comments, introduce internal switch in doc/api/qtcreator-api.qdocconf.
This commit is contained in:
@@ -39,7 +39,9 @@
|
||||
To get an overview of what parts of Qt Creator are extensible, have a look at the \l{Common Extension Tasks} page.
|
||||
Also read and follow the Qt Creator \l{Qt Creator Coding Rules}{coding style and best practice patterns}.
|
||||
|
||||
\section1 Core Libraries
|
||||
\section1 Libraries
|
||||
|
||||
\section2 Core Libraries
|
||||
|
||||
There are a few core libraries used by many parts of Qt Creator.
|
||||
|
||||
@@ -60,6 +62,19 @@
|
||||
|
||||
\endtable
|
||||
|
||||
\section2 Additional libraries
|
||||
|
||||
\table
|
||||
\header
|
||||
\o Library Name
|
||||
\o Description
|
||||
|
||||
\row
|
||||
\o \l{qtcreatorcdbext}
|
||||
\o Windows CDB debugger extension
|
||||
|
||||
\endtable
|
||||
|
||||
\section1 Plugins
|
||||
|
||||
As already mentioned, Qt Creator is basically only a plugin loader framework
|
||||
|
||||
@@ -9,6 +9,7 @@ headerdirs = . \
|
||||
../../src/libs/aggregation \
|
||||
../../src/libs/cplusplus \
|
||||
../../src/libs/extensionsystem \
|
||||
../../src/libs/qtcreatorcdbext \
|
||||
../../src/plugins/coreplugin \
|
||||
../../src/plugins/find \
|
||||
../../src/plugins/locator \
|
||||
@@ -18,12 +19,18 @@ sourcedirs = . \
|
||||
../../src/libs/aggregation \
|
||||
../../src/libs/cplusplus \
|
||||
../../src/libs/extensionsystem \
|
||||
../../src/libs/qtcreatorcdbext \
|
||||
../../src/plugins/coreplugin \
|
||||
../../src/plugins/find \
|
||||
../../src/plugins/locator \
|
||||
../../src/plugins/debugger
|
||||
|
||||
headers.fileextesnions = "*.h"
|
||||
# -- Generate complete documentation. Set this to 'false'
|
||||
# to generate public API documentation only.
|
||||
|
||||
showinternal = true
|
||||
|
||||
headers.fileextensions = "*.h"
|
||||
sources.fileextensions = "*.cpp *.qdoc"
|
||||
|
||||
imagedirs = images ../templates/images
|
||||
|
||||
@@ -131,7 +131,7 @@ int containerSize(KnownType kt, SymbolGroupNode *n, const SymbolGroupValueContex
|
||||
return ct;
|
||||
}
|
||||
|
||||
// Determine size of containers
|
||||
/*! Determine size of containers \ingroup qtcreatorcdbext */
|
||||
int containerSize(KnownType kt, const SymbolGroupValue &v)
|
||||
{
|
||||
switch (kt) {
|
||||
@@ -1008,6 +1008,7 @@ static inline AbstractSymbolGroupNodePtrVector
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*! Determine children of containers \ingroup qtcreatorcdbext */
|
||||
AbstractSymbolGroupNodePtrVector containerChildren(SymbolGroupNode *node, int type,
|
||||
int size, const SymbolGroupValueContext &ctx)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,14 @@ enum { winExceptionCppException = 0xe06d7363,
|
||||
winExceptionAppInitFailed = 0xc0000143
|
||||
};
|
||||
|
||||
/*!
|
||||
\class IDebugEventCallbacks
|
||||
|
||||
Event handler wrapping the original IDebugEventCallbacks
|
||||
to catch and store exceptions (report crashes as stop reasons).
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
EventCallback::EventCallback(IDebugEventCallbacks *wrapped) :
|
||||
m_wrapped(wrapped)
|
||||
{
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
#include "common.h"
|
||||
#include "extensioncontext.h"
|
||||
|
||||
/* IDebugEventCallbacks event handler wrapping the original IDebugEventCallbacks
|
||||
* to catch and store exceptions (report crashes as stop reasons). */
|
||||
class EventCallback : public IDebugEventCallbacks
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -47,6 +47,13 @@ WINDBG_EXTENSION_APIS ExtensionApis = {sizeof(WINDBG_EXTENSION_APIS), 0, 0, 0,
|
||||
const char *ExtensionContext::stopReasonKeyC = "reason";
|
||||
const char *ExtensionContext::breakPointStopReasonC = "breakpoint";
|
||||
|
||||
/*! \class ExtensionContext
|
||||
|
||||
Global singleton with context.
|
||||
Caches a symbolgroup per frame and thread as long as the session is accessible.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
ExtensionContext::ExtensionContext() :
|
||||
m_hookedClient(0),
|
||||
m_oldEventCallback(0), m_oldOutputCallback(0),
|
||||
@@ -376,7 +383,11 @@ void CALLBACK DebugExtensionNotify(ULONG Notify, ULONG64)
|
||||
|
||||
} // extern "C"
|
||||
|
||||
// -------- ExtensionCommandContext
|
||||
/*! \class ExtensionCommandContext
|
||||
|
||||
Context for extension commands to be instantiated on stack in a command handler.
|
||||
Provides the IDebug objects on demand. \ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
ExtensionCommandContext *ExtensionCommandContext::m_instance = 0;
|
||||
|
||||
|
||||
@@ -38,6 +38,13 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
/* \class OutputCallback
|
||||
|
||||
OutputCallback catches DEBUG_OUTPUT_DEBUGGEE and reports it
|
||||
base64-encoded back to Qt Creator.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
OutputCallback::OutputCallback(IDebugOutputCallbacksWide *wrapped) :
|
||||
m_wrapped(wrapped), m_recording(false)
|
||||
{
|
||||
|
||||
@@ -44,17 +44,27 @@
|
||||
#include <list>
|
||||
#include <iterator>
|
||||
|
||||
/* QtCreatorCDB ext is an extension loaded into CDB.exe (see cdbengine.cpp)
|
||||
* providing:
|
||||
* - Notification about the state of the debugging session:
|
||||
* + idle: (hooked with .idle_cmd) debuggee stopped
|
||||
* + accessible: Debuggee stopped, cdb.exe accepts commands
|
||||
* + inaccessible: Debuggee runs, no way to post commands
|
||||
* + session active/inactive: Lost debuggee, terminating.
|
||||
* - Hook up with output/event callbacks and produce formatted output
|
||||
* - Provide some extension commands that produce output in a standardized (GDBMI)
|
||||
* format that ends up in handleExtensionMessage().
|
||||
*/
|
||||
/*!
|
||||
\group qtcreatorcdbext
|
||||
\title Qt Creator CDB extension
|
||||
|
||||
\brief QtCreatorCDB ext is an extension loaded into CDB.exe (see cdbengine.cpp).
|
||||
|
||||
|
||||
It provides
|
||||
|
||||
\list
|
||||
\o Notification about the state of the debugging session:
|
||||
\list
|
||||
\o idle: (hooked with .idle_cmd) debuggee stopped
|
||||
\o accessible: Debuggee stopped, cdb.exe accepts commands
|
||||
\o inaccessible: Debuggee runs, no way to post commands
|
||||
\o session active/inactive: Lost debuggee, terminating.
|
||||
\endlist
|
||||
\o Hook up with output/event callbacks and produce formatted output
|
||||
\o Provide some extension commands that produce output in a standardized (GDBMI)
|
||||
format that ends up in handleExtensionMessage().
|
||||
*/
|
||||
|
||||
// Data struct and helpers for formatting help
|
||||
struct CommandDescription {
|
||||
|
||||
@@ -48,6 +48,18 @@ typedef std::vector<std::string> StringVector;
|
||||
enum { debug = 0 };
|
||||
|
||||
// ------------- SymbolGroup
|
||||
|
||||
/*!
|
||||
\class SymbolGroup A symbol group storing a tree of expanded symbols rooted on a fake "locals" root element.
|
||||
|
||||
Provides a find() method based on inames ("locals.this.i1.data") and
|
||||
dump() methods used for GDBMI-format dumping and debug helpers.
|
||||
Qt Creator's WatchModel is fed from this class. It basically represents the
|
||||
symbol group tree with some additional node types (Reference and Map Node
|
||||
types.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
SymbolGroup::SymbolGroup(IDebugSymbolGroup2 *sg,
|
||||
const SymbolParameterVector &vec,
|
||||
const std::string &rootModule,
|
||||
@@ -525,7 +537,14 @@ AbstractSymbolGroupNode *SymbolGroup::find(const std::string &iname) const
|
||||
return rc;
|
||||
}
|
||||
|
||||
// --------- LocalsSymbolGroup
|
||||
/*!
|
||||
\class LocalsSymbolGroup
|
||||
|
||||
Symbol group representing the Locals view. It is firmly associated
|
||||
with stack frame, function (module) and thread.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
LocalsSymbolGroup::LocalsSymbolGroup(CIDebugSymbolGroup *sg,
|
||||
const SymbolParameterVector &vec,
|
||||
ULONG threadId, unsigned frame,
|
||||
@@ -608,7 +627,13 @@ std::string LocalsSymbolGroup::module() const
|
||||
return root()->module();
|
||||
}
|
||||
|
||||
// ----------- WatchSymbolGroup
|
||||
/*!
|
||||
\class WatchesSymbolGroup
|
||||
|
||||
Watch symbol group. Contains watches as added by Qt Creator as iname='watch.0',
|
||||
name='<expression>'. The IDebugSymbolGroup is created without scope.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
const char *WatchesSymbolGroup::watchInamePrefix = "watch";
|
||||
|
||||
@@ -854,3 +879,5 @@ WatchesSymbolGroup *WatchesSymbolGroup::create(CIDebugSymbols *symbols,
|
||||
}
|
||||
return new WatchesSymbolGroup(idebugSymbols);
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -39,14 +39,6 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
/* A symbol group storing a tree of expanded symbols rooted on
|
||||
* a fake "locals" root element.
|
||||
* Provides a find() method based on inames ("locals.this.i1.data") and
|
||||
* dump() methods used for GDBMI-format dumping and debug helpers.
|
||||
* Qt Creator's WatchModel is fed from this class. It basically represents the
|
||||
* symbol group tree with some additional node types (Reference and Map Node
|
||||
* types. */
|
||||
|
||||
class SymbolGroup {
|
||||
public:
|
||||
typedef std::vector<DEBUG_SYMBOL_PARAMETERS> SymbolParameterVector;
|
||||
@@ -136,9 +128,6 @@ private:
|
||||
SymbolGroupNode *m_root;
|
||||
};
|
||||
|
||||
/* Symbol group representing the Locals view. It is firmly associated
|
||||
* with stack frame, function (module) and thread. */
|
||||
|
||||
class LocalsSymbolGroup : public SymbolGroup {
|
||||
protected:
|
||||
explicit LocalsSymbolGroup(CIDebugSymbolGroup *,
|
||||
@@ -163,8 +152,6 @@ private:
|
||||
std::string m_function;
|
||||
};
|
||||
|
||||
// Watch symbol group. Contains watches as added by Qt Creator as iname='watch.0',
|
||||
// name='<expression>'. The IDebugSymbolGroup is created without scope.
|
||||
class WatchesSymbolGroup : public SymbolGroup {
|
||||
public:
|
||||
typedef std::map<std::string, std::string> InameExpressionMap;
|
||||
|
||||
@@ -91,8 +91,12 @@ inline std::ostream &operator<<(std::ostream &str, const DebugNodeFlags &f)
|
||||
return str;
|
||||
}
|
||||
|
||||
// -------------- AbstractSymbolGroupNode
|
||||
/*!
|
||||
\class AbstractSymbolGroupNode
|
||||
|
||||
Abstract base class for a node of SymbolGroup providing the child list interface.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
AbstractSymbolGroupNode::AbstractSymbolGroupNode(const std::string &name,
|
||||
const std::string &iname) :
|
||||
m_name(name), m_iname(iname), m_parent(0), m_flags(0)
|
||||
@@ -205,7 +209,12 @@ void AbstractSymbolGroupNode::setParent(AbstractSymbolGroupNode *n)
|
||||
m_parent = n;
|
||||
}
|
||||
|
||||
// -------- BaseSymbolGroupNode
|
||||
/*! \class BaseSymbolGroupNode
|
||||
|
||||
Base class for a node of SymbolGroup with a flat list of children.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
BaseSymbolGroupNode::BaseSymbolGroupNode(const std::string &name, const std::string &iname) :
|
||||
AbstractSymbolGroupNode(name, iname)
|
||||
{
|
||||
@@ -272,7 +281,14 @@ std::ostream &operator<<(std::ostream &str, const DEBUG_SYMBOL_PARAMETERS ¶m
|
||||
return str;
|
||||
}
|
||||
|
||||
// --------------- DumpParameters
|
||||
/*! \struct DumpParameters
|
||||
|
||||
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.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
DumpParameters::DumpParameters() : dumpFlags(0)
|
||||
{
|
||||
}
|
||||
@@ -459,7 +475,29 @@ void ErrorSymbolGroupNode::debug(std::ostream &os, const std::string &visitingFu
|
||||
os << "ErrorSymbolGroupNode '" << name() << "','" << iName() << "', '" << visitingFullIname << "'\n";
|
||||
}
|
||||
|
||||
// ------- SymbolGroupNode
|
||||
/*! \class SymbolGroupNode
|
||||
|
||||
\brief 'Real' node within a symbol group, identified by its index in IDebugSymbolGroup.
|
||||
|
||||
Provides accessors for fixed-up symbol group value and a dumping facility
|
||||
consisting of:
|
||||
\list
|
||||
\o 'Simple' dumping done when running the DumpVisitor. This produces one
|
||||
line of formatted output shown for the class. These values
|
||||
values are always displayed, while still allowing for expansion of the structure
|
||||
in the debugger.
|
||||
It also pre-determines some information for complex dumping (type, container).
|
||||
\o 'Complex' dumping: Obscures the symbol group children by fake children, for
|
||||
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
|
||||
obscured for GDBMI dumping so that SymbolGroupValue expressions still work as before).
|
||||
\endlist
|
||||
|
||||
The dumping is mostly based on SymbolGroupValue expressions.
|
||||
in the debugger. Evaluating those dumpers might expand symbol nodes, which are
|
||||
then marked as 'ExpandedByDumper'. This stops the dump recursion to prevent
|
||||
outputting data that were not explicitly expanded by the watch handler.
|
||||
\ingroup qtcreatorcdbext */
|
||||
|
||||
SymbolGroupNode::SymbolGroupNode(SymbolGroup *symbolGroup,
|
||||
ULONG index,
|
||||
@@ -1204,8 +1242,6 @@ SymbolGroupNode *SymbolGroupNode::addSymbolByName(const std::string &module,
|
||||
return node;
|
||||
}
|
||||
|
||||
// --------- ReferenceSymbolGroupNode
|
||||
|
||||
// Utility returning a pair ('[42]','42') as name/iname pair
|
||||
// for a node representing an array index
|
||||
typedef std::pair<std::string, std::string> StringStringPair;
|
||||
@@ -1219,6 +1255,13 @@ static inline StringStringPair arrayIndexNameIname(int index)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*! \class ReferenceSymbolGroupNode
|
||||
|
||||
Artificial node referencing another (real) SymbolGroupNode (added symbol or
|
||||
symbol from within an expanded linked list structure). Forwards the
|
||||
dumping to the referenced node using its own name.
|
||||
\ingroup qtcreatorcdbext */
|
||||
|
||||
ReferenceSymbolGroupNode::ReferenceSymbolGroupNode(const std::string &name,
|
||||
const std::string &iname,
|
||||
SymbolGroupNode *referencedNode) :
|
||||
@@ -1249,7 +1292,13 @@ void ReferenceSymbolGroupNode::debug(std::ostream &str, const std::string &visit
|
||||
m_referencedNode->debug(str, visitingFullIname, verbosity, depth);
|
||||
}
|
||||
|
||||
// ---------------- MapNodeSymbolGroupNode
|
||||
/*! \class MapNodeSymbolGroupNode
|
||||
|
||||
\brief A [fake] map node with a fake array index and key/value entries consisting
|
||||
of ReferenceSymbolGroupNode.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
MapNodeSymbolGroupNode::MapNodeSymbolGroupNode(const std::string &name,
|
||||
const std::string &iname,
|
||||
ULONG64 address,
|
||||
@@ -1293,7 +1342,18 @@ void MapNodeSymbolGroupNode::debug(std::ostream &os, const std::string &visiting
|
||||
os << "MapNode " << name() << '/' << visitingFullIname << '\n';
|
||||
}
|
||||
|
||||
// --------- DebugSymbolGroupNodeVisitor
|
||||
/*! \class SymbolGroupNodeVisitor
|
||||
|
||||
Visitor that takes care of iterating over the nodes and
|
||||
building the full iname path ('local.foo.bar') that is required for
|
||||
GDBMI dumping. The full name depends on the path on which a node was reached
|
||||
for referenced nodes (a linked list element can be reached via array index
|
||||
or by expanding the whole structure).
|
||||
visit() is not called for the (invisible) root node, but starting with the
|
||||
root's children with depth=0.
|
||||
Return VisitStop from visit() to terminate the recursion.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
// "local.vi" -> "local"
|
||||
std::string SymbolGroupNodeVisitor::parentIname(const std::string &iname)
|
||||
@@ -1302,6 +1362,11 @@ std::string SymbolGroupNodeVisitor::parentIname(const std::string &iname)
|
||||
return lastSep == std::string::npos ? std::string() : iname.substr(0, lastSep);
|
||||
}
|
||||
|
||||
/*! \class DebugSymbolGroupNodeVisitor
|
||||
\brief Debug output visitor.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
DebugSymbolGroupNodeVisitor::DebugSymbolGroupNodeVisitor(std::ostream &os, unsigned verbosity) :
|
||||
m_os(os), m_verbosity(verbosity)
|
||||
{
|
||||
@@ -1316,6 +1381,11 @@ SymbolGroupNodeVisitor::VisitResult
|
||||
return VisitContinue;
|
||||
}
|
||||
|
||||
/*! \class DebugFilterSymbolGroupNodeVisitor
|
||||
\brief Debug filtering output visitor.
|
||||
\ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
DebugFilterSymbolGroupNodeVisitor::DebugFilterSymbolGroupNodeVisitor(std::ostream &os,
|
||||
const std::string &filter,
|
||||
const unsigned verbosity) :
|
||||
@@ -1334,7 +1404,12 @@ SymbolGroupNodeVisitor::VisitResult
|
||||
return DebugSymbolGroupNodeVisitor::visit(node, fullIname, child, depth);
|
||||
}
|
||||
|
||||
// --------------------- DumpSymbolGroupNodeVisitor
|
||||
/*! \class DumpSymbolGroupNodeVisitor
|
||||
|
||||
GDBMI dump output visitor used to report locals values back to the
|
||||
debugging engine. \ingroup qtcreatorcdbext
|
||||
*/
|
||||
|
||||
DumpSymbolGroupNodeVisitor::DumpSymbolGroupNodeVisitor(std::ostream &os,
|
||||
const SymbolGroupValueContext &context,
|
||||
const DumpParameters ¶meters) :
|
||||
|
||||
@@ -50,9 +50,6 @@ class SymbolGroup;
|
||||
struct SymbolGroupValueContext;
|
||||
class SymbolGroupNode;
|
||||
|
||||
// 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
|
||||
{
|
||||
typedef std::map<std::string, int> FormatMap; // type or iname to format
|
||||
@@ -77,7 +74,6 @@ struct DumpParameters
|
||||
FormatMap individualFormats;
|
||||
};
|
||||
|
||||
// Abstract base class for a node of SymbolGroup providing the child list interface.
|
||||
class AbstractSymbolGroupNode
|
||||
{
|
||||
AbstractSymbolGroupNode(const AbstractSymbolGroupNode&);
|
||||
@@ -148,7 +144,6 @@ private:
|
||||
unsigned m_flags;
|
||||
};
|
||||
|
||||
// Base class for a node of SymbolGroup with a flat list of children.
|
||||
class BaseSymbolGroupNode : public AbstractSymbolGroupNode
|
||||
{
|
||||
public:
|
||||
@@ -179,24 +174,6 @@ public:
|
||||
unsigned verbosity, unsigned depth) const;
|
||||
};
|
||||
|
||||
/* SymbolGroupNode: 'Real' node within a symbol group, identified by its index
|
||||
* in IDebugSymbolGroup.
|
||||
* Provides accessors for fixed-up symbol group value and a dumping facility
|
||||
* consisting of:
|
||||
* - 'Simple' dumping done when running the DumpVisitor. This produces one
|
||||
* line of formatted output shown for the class. These values
|
||||
* values are always displayed, while still allowing for expansion of the structure
|
||||
* in the debugger.
|
||||
* It also pre-determines some information for complex dumping (type, container).
|
||||
* - 'Complex' dumping: Obscures the symbol group children by fake children, for
|
||||
* 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
|
||||
* obscured for GDBMI dumping so that SymbolGroupValue expressions still work as before).
|
||||
* The dumping is mostly based on SymbolGroupValue expressions.
|
||||
* in the debugger. Evaluating those dumpers might expand symbol nodes, which are
|
||||
* then marked as 'ExpandedByDumper'. This stops the dump recursion to prevent
|
||||
* outputting data that were not explicitly expanded by the watch handler. */
|
||||
|
||||
class SymbolGroupNode : public BaseSymbolGroupNode
|
||||
{
|
||||
explicit SymbolGroupNode(SymbolGroup *symbolGroup,
|
||||
@@ -296,9 +273,6 @@ private:
|
||||
void *m_dumperSpecialInfo; // Opaque information passed from simple to complex dumpers
|
||||
};
|
||||
|
||||
// Artificial node referencing another (real) SymbolGroupNode (added symbol or
|
||||
// symbol from within an expanded linked list structure). Forwards the
|
||||
// dumping to the referenced node using its own name.
|
||||
class ReferenceSymbolGroupNode : public AbstractSymbolGroupNode
|
||||
{
|
||||
public:
|
||||
@@ -323,8 +297,6 @@ private:
|
||||
SymbolGroupNode * const m_referencedNode;
|
||||
};
|
||||
|
||||
// A [fake] map node with a fake array index and key/value entries consisting
|
||||
// of ReferenceSymbolGroupNode.
|
||||
class MapNodeSymbolGroupNode : public BaseSymbolGroupNode
|
||||
{
|
||||
private:
|
||||
@@ -350,15 +322,6 @@ private:
|
||||
const std::string m_type;
|
||||
};
|
||||
|
||||
/* Visitor that takes care of iterating over the nodes and
|
||||
* building the full iname path ('local.foo.bar') that is required for
|
||||
* GDBMI dumping. The full name depends on the path on which a node was reached
|
||||
* for referenced nodes (a linked list element can be reached via array index
|
||||
* or by expanding the whole structure).
|
||||
* visit() is not called for the (invisible) root node, but starting with the
|
||||
* root's children with depth=0.
|
||||
* Return VisitStop from visit() to terminate the recursion. */
|
||||
|
||||
class SymbolGroupNodeVisitor {
|
||||
SymbolGroupNodeVisitor(const SymbolGroupNodeVisitor&);
|
||||
SymbolGroupNodeVisitor& operator=(const SymbolGroupNodeVisitor&);
|
||||
@@ -389,7 +352,6 @@ protected:
|
||||
virtual void childrenVisited(const AbstractSymbolGroupNode * /* node */, unsigned /* depth */) {}
|
||||
};
|
||||
|
||||
// Debug output visitor.
|
||||
class DebugSymbolGroupNodeVisitor : public SymbolGroupNodeVisitor {
|
||||
public:
|
||||
explicit DebugSymbolGroupNodeVisitor(std::ostream &os, unsigned verbosity = 0);
|
||||
@@ -404,7 +366,6 @@ private:
|
||||
const unsigned m_verbosity;
|
||||
};
|
||||
|
||||
// Debug filtering output visitor.
|
||||
class DebugFilterSymbolGroupNodeVisitor : public DebugSymbolGroupNodeVisitor {
|
||||
public:
|
||||
explicit DebugFilterSymbolGroupNodeVisitor(std::ostream &os,
|
||||
@@ -420,8 +381,6 @@ private:
|
||||
const std::string m_filter;
|
||||
};
|
||||
|
||||
// GDBMI dump output visitor used to report locals values back to the
|
||||
// debugging engine.
|
||||
class DumpSymbolGroupNodeVisitor : public SymbolGroupNodeVisitor {
|
||||
public:
|
||||
explicit DumpSymbolGroupNodeVisitor(std::ostream &os,
|
||||
|
||||
@@ -41,6 +41,24 @@
|
||||
|
||||
typedef std::vector<int>::size_type VectorIndexType;
|
||||
|
||||
/*! \struct SymbolGroupValueContext
|
||||
\brief Structure to pass all IDebug interfaces required for SymbolGroupValue
|
||||
\ingroup qtcreatorcdbext */
|
||||
|
||||
/*! \class SymbolGroupValue
|
||||
|
||||
Flyweight tied to a SymbolGroupNode
|
||||
providing a convenient operator[] (name, index) and value
|
||||
getters for notation of dumpers.
|
||||
Inaccessible members return a SymbolGroupValue in state 'invalid'.
|
||||
Example:
|
||||
\code
|
||||
SymbolGroupValue container(symbolGroupNode, symbolGroupValueContext);
|
||||
if (SymbolGroupValue sizeV = container["d"]["size"])
|
||||
int size = sizeV.intValue()
|
||||
\endcode
|
||||
etc. \ingroup qtcreatorcdbext */
|
||||
|
||||
unsigned SymbolGroupValue::verbose = 0;
|
||||
|
||||
SymbolGroupValue::SymbolGroupValue(const std::string &parentError) :
|
||||
@@ -436,6 +454,12 @@ static inline std::string resolveQtSymbol(const char *symbolC,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*! \struct QtInfo
|
||||
|
||||
Qt Information determined on demand: Namespace, modules and basic class
|
||||
names containing the module for fast lookup.
|
||||
\ingroup qtcreatorcdbext */
|
||||
|
||||
const QtInfo &QtInfo::get(const SymbolGroupValueContext &ctx)
|
||||
{
|
||||
static const char qtCoreDefaultModule[] = "QtCored4";
|
||||
|
||||
@@ -45,7 +45,6 @@ class AbstractSymbolGroupNode;
|
||||
class SymbolGroupNode;
|
||||
class SymbolGroup;
|
||||
|
||||
// Structure to pass all IDebug interfaces required for SymbolGroupValue
|
||||
struct SymbolGroupValueContext
|
||||
{
|
||||
SymbolGroupValueContext(CIDebugDataSpaces *ds, CIDebugSymbols *s) : dataspaces(ds), symbols(s) {}
|
||||
@@ -55,16 +54,6 @@ struct SymbolGroupValueContext
|
||||
CIDebugSymbols *symbols;
|
||||
};
|
||||
|
||||
/* SymbolGroupValue: Flyweight tied to a SymbolGroupNode
|
||||
* providing a convenient operator[] (name, index) and value
|
||||
* 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
|
||||
{
|
||||
explicit SymbolGroupValue(const std::string &parentError);
|
||||
@@ -161,8 +150,6 @@ private:
|
||||
// For debugging purposes
|
||||
std::ostream &operator<<(std::ostream &, const SymbolGroupValue &v);
|
||||
|
||||
// Qt Information determined on demand: Namespace, modules and basic class
|
||||
// names containing the module for fast lookup.
|
||||
struct QtInfo
|
||||
{
|
||||
static const QtInfo &get(const SymbolGroupValueContext &ctx);
|
||||
|
||||
@@ -45,6 +45,12 @@ namespace Internal {
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\class Debugger::Internal::BreakpointParameters
|
||||
|
||||
Data type holding the parameters of a breakpoint.
|
||||
*/
|
||||
|
||||
BreakpointParameters::BreakpointParameters(BreakpointType t)
|
||||
: type(t), enabled(true), useFullPath(false),
|
||||
ignoreCount(0), lineNumber(0), address(0), threadSpec(-1),
|
||||
@@ -97,10 +103,17 @@ QString BreakpointParameters::toString() const
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BreakpointParameters
|
||||
// BreakpointResponse
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\class Debugger::Internal::BreakpointResponse
|
||||
|
||||
This is what debuggers produce in response to the attempt to
|
||||
insert a breakpoint. The data might differ from the requested bits.
|
||||
*/
|
||||
|
||||
BreakpointResponse::BreakpointResponse()
|
||||
: number(0), pending(true), multiple(false), correctedLineNumber(0)
|
||||
{}
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef quint64 BreakpointId;
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
//! \enum Debugger::Internal::BreakpointType
|
||||
enum BreakpointType
|
||||
{
|
||||
UnknownType,
|
||||
@@ -61,10 +62,11 @@ enum BreakpointType
|
||||
Watchpoint
|
||||
};
|
||||
|
||||
//! \enum Debugger::Internal::BreakpointState
|
||||
enum BreakpointState
|
||||
{
|
||||
BreakpointNew,
|
||||
BreakpointInsertRequested, // Inferior was told about bp, not ack'ed.
|
||||
BreakpointInsertRequested, //!< Inferior was told about bp, not ack'ed.
|
||||
BreakpointInsertProceeding,
|
||||
BreakpointChangeRequested,
|
||||
BreakpointChangeProceeding,
|
||||
@@ -89,24 +91,21 @@ public:
|
||||
bool operator==(const BreakpointParameters &p) const { return equals(p); }
|
||||
bool operator!=(const BreakpointParameters &p) const { return !equals(p); }
|
||||
|
||||
BreakpointType type; // Type of breakpoint.
|
||||
bool enabled; // Should we talk to the debugger engine?
|
||||
bool useFullPath; // Should we use the full path when setting the bp?
|
||||
QString fileName; // Short name of source file.
|
||||
QByteArray condition; // Condition associated with breakpoint.
|
||||
int ignoreCount; // Ignore count associated with breakpoint.
|
||||
int lineNumber; // Line in source file.
|
||||
quint64 address; // Address for watchpoints.
|
||||
int threadSpec; // Thread specification.
|
||||
BreakpointType type; //!< Type of breakpoint.
|
||||
bool enabled; //!< Should we talk to the debugger engine?
|
||||
bool useFullPath; //!< Should we use the full path when setting the bp?
|
||||
QString fileName; //!< Short name of source file.
|
||||
QByteArray condition; //!< Condition associated with breakpoint.
|
||||
int ignoreCount; //!< Ignore count associated with breakpoint.
|
||||
int lineNumber; //!< Line in source file.
|
||||
quint64 address; //!< Address for watchpoints.
|
||||
int threadSpec; //!< Thread specification.
|
||||
QString functionName;
|
||||
QString module; // module for file name
|
||||
QString command; // command to execute
|
||||
QString module; //!< module for file name
|
||||
QString command; //!< command to execute
|
||||
bool tracepoint;
|
||||
};
|
||||
|
||||
|
||||
// This is what debuggers produced in response to the attempt to
|
||||
// insert a breakpoint. The data might differ from the requested bits.
|
||||
class BreakpointResponse : public BreakpointParameters
|
||||
{
|
||||
public:
|
||||
@@ -116,11 +115,11 @@ public:
|
||||
public:
|
||||
void fromParameters(const BreakpointParameters &p);
|
||||
|
||||
int number; // Breakpoint number assigned by the debugger engine.
|
||||
bool pending; // Breakpoint not fully resolved.
|
||||
QString fullName; // Full file name acknowledged by the debugger engine.
|
||||
bool multiple; // Happens in constructors/gdb.
|
||||
QByteArray extra; // gdb: <PENDING>, <MULTIPLE>
|
||||
int number; //!< Breakpoint number assigned by the debugger engine.
|
||||
bool pending; //!< Breakpoint not fully resolved.
|
||||
QString fullName; //!< Full file name acknowledged by the debugger engine.
|
||||
bool multiple; //!< Happens in constructors/gdb.
|
||||
QByteArray extra; //!< gdb: <PENDING>, <MULTIPLE>
|
||||
int correctedLineNumber;
|
||||
};
|
||||
|
||||
|
||||
@@ -97,42 +97,60 @@ enum { debugBreakpoints = 0 };
|
||||
# define STATE_DEBUG(state, func, line, notifyFunc)
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
* library (32/64bit), which is loaded into cdb.exe. It serves to:
|
||||
* - Notify the engine about the state of the debugging session:
|
||||
* + idle: (hooked up with .idle_cmd) debuggee stopped
|
||||
* + accessible: Debuggee stopped, cdb.exe accepts commands
|
||||
* + inaccessible: Debuggee runs, no way to post commands
|
||||
* + session active/inactive: Lost debuggee, terminating.
|
||||
* - 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)
|
||||
* format that ends up in handleExtensionMessage().
|
||||
* + pid Return debuggee pid for interrupting.
|
||||
* + locals Print locals from SymbolGroup
|
||||
* + expandLocals Expand locals in symbol group
|
||||
* + registers, modules, threads
|
||||
* Commands can be posted by calling:
|
||||
* 1) postCommand(): Does not expect a reply
|
||||
* 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
|
||||
* then invokes a callback with a CdbBuiltinCommand structure.
|
||||
* 3) postExtensionCommand(): Run a command provided by the extension producing
|
||||
* one-line output and invoke a callback with a CdbExtensionCommand structure
|
||||
* (output is potentially split up in chunks).
|
||||
*
|
||||
* Startup sequence:
|
||||
* [Console: The console stub launches the process. On process startup,
|
||||
* launchCDB() is called with AttachExternal.
|
||||
* setupEngine() calls launchCDB() with the startparameters. The debuggee
|
||||
* runs into the initial breakpoint (session idle). EngineSetupOk is
|
||||
* notified (inferior still stopped). setupInferior() is then called
|
||||
* which does breakpoint synchronization and issues the extension 'pid'
|
||||
* command to obtain the inferior pid. handlePid() notifies notifyInferiorSetupOk.
|
||||
* runEngine() is then called which issues 'g' to continue the inferior.
|
||||
* Shutdown mostly uses notifyEngineSpontaneousShutdown() as cdb just quits
|
||||
* when the inferior exits (except attach modes). */
|
||||
/*!
|
||||
\class Debugger::Internal::CdbEngine
|
||||
|
||||
Cdb engine 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
|
||||
library (32/64bit), which is loaded into cdb.exe. It serves to:
|
||||
|
||||
\list
|
||||
\o Notify the engine about the state of the debugging session:
|
||||
\list
|
||||
\o idle: (hooked up with .idle_cmd) debuggee stopped
|
||||
\o accessible: Debuggee stopped, cdb.exe accepts commands
|
||||
\o inaccessible: Debuggee runs, no way to post commands
|
||||
\o session active/inactive: Lost debuggee, terminating.
|
||||
\endlist
|
||||
\o Hook up with output/event callbacks and produce formatted output to be able
|
||||
to catch application output and exceptions.
|
||||
\o Provide some extension commands that produce output in a standardized (GDBMI)
|
||||
format that ends up in handleExtensionMessage(), for example:
|
||||
\list
|
||||
\o pid Return debuggee pid for interrupting.
|
||||
\o locals Print locals from SymbolGroup
|
||||
\o expandLocals Expand locals in symbol group
|
||||
\o registers, modules, threads
|
||||
\endlist
|
||||
\endlist
|
||||
|
||||
Debugger commands can be posted by calling:
|
||||
|
||||
\list
|
||||
|
||||
\o postCommand(): Does not expect a reply
|
||||
\o postBuiltinCommand(): Run a builtin-command producing free-format, multiline output
|
||||
that is captured by enclosing it in special tokens using the 'echo' command and
|
||||
then invokes a callback with a CdbBuiltinCommand structure.
|
||||
\o postExtensionCommand(): Run a command provided by the extension producing
|
||||
one-line output and invoke a callback with a CdbExtensionCommand structure
|
||||
(output is potentially split up in chunks).
|
||||
\endlist
|
||||
|
||||
|
||||
Startup sequence:
|
||||
[Console: The console stub launches the process. On process startup,
|
||||
launchCDB() is called with AttachExternal].
|
||||
setupEngine() calls launchCDB() with the startparameters. The debuggee
|
||||
runs into the initial breakpoint (session idle). EngineSetupOk is
|
||||
notified (inferior still stopped). setupInferior() is then called
|
||||
which does breakpoint synchronization and issues the extension 'pid'
|
||||
command to obtain the inferior pid (which also hooks up the output callbacks).
|
||||
handlePid() notifies notifyInferiorSetupOk.
|
||||
runEngine() is then called which issues 'g' to continue the inferior.
|
||||
Shutdown mostly uses notifyEngineSpontaneousShutdown() as cdb just quits
|
||||
when the inferior exits (except attach modes).
|
||||
*/
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
|
||||
@@ -229,16 +229,16 @@ private:
|
||||
DebuggerStartMode m_effectiveStartMode;
|
||||
QByteArray m_outputBuffer;
|
||||
unsigned long m_inferiorPid;
|
||||
// Debugger accessible (expecting commands)
|
||||
//! Debugger accessible (expecting commands)
|
||||
bool m_accessible;
|
||||
SpecialStopMode m_specialStopMode;
|
||||
int m_nextCommandToken;
|
||||
QList<CdbBuiltinCommandPtr> m_builtinCommandQueue;
|
||||
int m_currentBuiltinCommandIndex; // Current command whose output is recorded.
|
||||
int m_currentBuiltinCommandIndex; //!< Current command whose output is recorded.
|
||||
QList<CdbExtensionCommandPtr> m_extensionCommandQueue;
|
||||
QMap<QString, QString> m_normalizedFileCache;
|
||||
const QByteArray m_extensionCommandPrefixBA; // Library name used as prefix
|
||||
bool m_operateByInstructionPending; // Creator operate by instruction action changed.
|
||||
const QByteArray m_extensionCommandPrefixBA; //!< Library name used as prefix
|
||||
bool m_operateByInstructionPending; //!< Creator operate by instruction action changed.
|
||||
bool m_operateByInstruction;
|
||||
bool m_notifyEngineShutdownOnTermination;
|
||||
bool m_hasDebuggee;
|
||||
|
||||
@@ -62,10 +62,6 @@ class BreakHandler;
|
||||
class SnapshotHandler;
|
||||
class Symbol;
|
||||
|
||||
// This is the "internal" interface of the debugger plugin that's
|
||||
// used by debugger views and debugger engines. The interface is
|
||||
// implemented in DebuggerPluginPrivate.
|
||||
|
||||
class DebuggerCore : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -146,6 +146,7 @@
|
||||
/*!
|
||||
\namespace Debugger::Internal
|
||||
Internal namespace of the Debugger plugin
|
||||
\internal
|
||||
*/
|
||||
|
||||
/*!
|
||||
@@ -878,6 +879,20 @@ namespace Internal {
|
||||
|
||||
static DebuggerPluginPrivate *theDebuggerCore = 0;
|
||||
|
||||
/*!
|
||||
\class Debugger::Internal::DebuggerCore
|
||||
|
||||
This is the "internal" interface of the debugger plugin that's
|
||||
used by debugger views and debugger engines. The interface is
|
||||
implemented in DebuggerPluginPrivate.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class Debugger::Internal::DebuggerPluginPrivate
|
||||
|
||||
Implementation of DebuggerCore.
|
||||
*/
|
||||
|
||||
class DebuggerPluginPrivate : public DebuggerCore
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -3204,6 +3219,14 @@ void DebuggerPluginPrivate::aboutToShutdown()
|
||||
|
||||
using namespace Debugger::Internal;
|
||||
|
||||
/*!
|
||||
\class Debugger::DebuggerPlugin
|
||||
|
||||
This is the "external" interface of the debugger plugin that's visible
|
||||
from Qt Creator core. The internal interface to global debugger
|
||||
functionality that is used by debugger views and debugger engines
|
||||
is DebuggerCore, implemented in DebuggerPluginPrivate. */
|
||||
|
||||
DebuggerPlugin::DebuggerPlugin()
|
||||
{
|
||||
theDebuggerCore = new DebuggerPluginPrivate(this);
|
||||
|
||||
@@ -49,11 +49,6 @@ class DebuggerMainWindow;
|
||||
class DebuggerRunControl;
|
||||
class DebuggerStartParameters;
|
||||
|
||||
// This is the "external" interface of the debugger plugin that's visible
|
||||
// from Qt Creator core. The internal interface to global debugger
|
||||
// functionality that is used by debugger views and debugger engines
|
||||
// is DebuggerCore, implemented in DebuggerPluginPrivate.
|
||||
|
||||
class DEBUGGER_EXPORT DebuggerPlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -118,6 +118,13 @@ QDebug operator<<(QDebug d, const SnapshotData &f)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\class Debugger::Internal::SnapshotHandler
|
||||
\brief A model to represent the snapshots in a QTreeView.
|
||||
|
||||
A snapshot represents a debugging session.
|
||||
*/
|
||||
|
||||
SnapshotHandler::SnapshotHandler()
|
||||
: m_positionIcon(QIcon(QLatin1String(":/debugger/images/location_16.png"))),
|
||||
m_emptyIcon(QIcon(QLatin1String(":/debugger/images/debugger_empty_14.png")))
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Internal {
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*! A model to represent the snapshots in a QTreeView. */
|
||||
|
||||
class SnapshotHandler : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -52,6 +52,11 @@ namespace Internal {
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\class Debugger::Internal::StackHandler
|
||||
\brief A model to represent the stack in a QTreeView.
|
||||
*/
|
||||
|
||||
StackHandler::StackHandler()
|
||||
: m_positionIcon(QIcon(QLatin1String(":/debugger/images/location_16.png"))),
|
||||
m_emptyIcon(QIcon(QLatin1String(":/debugger/images/debugger_empty_14.png")))
|
||||
|
||||
@@ -62,7 +62,6 @@ struct StackCookie
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*! A model to represent the stack in a QTreeView. */
|
||||
class StackHandler : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -90,6 +90,16 @@ static QString threadToolTip(const ThreadData &thread)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
\struct Debugger::Internal::ThreadData
|
||||
\brief A structure containing information about a single thread
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class Debugger::Internal::ThreadsHandler
|
||||
\brief A model to represent the running threads in a QTreeView or ComboBox
|
||||
*/
|
||||
|
||||
ThreadsHandler::ThreadsHandler()
|
||||
: m_currentIndex(0),
|
||||
m_positionIcon(QLatin1String(":/debugger/images/location_16.png")),
|
||||
|
||||
@@ -48,7 +48,6 @@ class GdbMi;
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*! A model to represent the running threads in a QTreeView or ComboBox */
|
||||
class ThreadsHandler : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Reference in New Issue
Block a user