Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Marco Bubke
flatpak-qt-creator
Commits
cbd85651
Commit
cbd85651
authored
Apr 29, 2009
by
mae
Browse files
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
parents
ffe9fe58
df2c805c
Changes
30
Expand all
Hide whitespace changes
Inline
Side-by-side
share/qtcreator/gdbmacros/gdbmacros.cpp
View file @
cbd85651
...
...
@@ -60,6 +60,10 @@ int qtGhVersion = QT_VERSION;
# include <QtGui/QImage>
#endif
#ifdef Q_OS_WIN
# include <windows.h>
#endif
#include
<list>
#include
<map>
#include
<string>
...
...
@@ -231,11 +235,17 @@ static QByteArray stripPointerType(QByteArray type)
}
// This is used to abort evaluation of custom data dumpers in a "coordinated"
// way. Abortion will happen a
nyway
when we try to access a non-initialized
// way. Abortion will happen a
t the latest
when we try to access a non-initialized
// non-trivial object, so there is no way to prevent this from occuring at all
// conceptionally. Gdb will catch SIGSEGV and return to the calling frame.
// This is just fine provided we only _read_ memory in the custom handlers
// below.
// conceptionally. Ideally, if there is API to check memory access, it should
// be used to terminate nicely, especially with CDB.
// 1) Gdb will catch SIGSEGV and return to the calling frame.
// This is just fine provided we only _read_ memory in the custom handlers
// below.
// 2) For MSVC/CDB, exceptions must be handled in the dumper, which is
// achieved using __try/__except. The exception will be reported in the
// debugger, which will then execute a 'gN' command, passing handling back
// to the __except clause.
volatile
int
qProvokeSegFaultHelper
;
...
...
@@ -269,11 +279,16 @@ static bool startsWith(const char *s, const char *t)
return
qstrncmp
(
s
,
t
,
qstrlen
(
t
))
==
0
;
}
// provoke segfault when address is not readable
#define qCheckAccess(d) do { qProvokeSegFaultHelper = *(char*)d; } while (0)
#define qCheckPointer(d) do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0)
// provoke segfault unconditionally
#define qCheck(b) do { if (!(b)) qProvokeSegFaultHelper = *(char*)0; } while (0)
// Check memory for read access and provoke segfault if nothing else helps.
// On Windows, try to be less crash-prone by checking memory using WinAPI
#ifdef Q_OS_WIN
# define qCheckAccess(d) if (IsBadReadPtr(d, 1)) return; do { qProvokeSegFaultHelper = *(char*)d; } while (0)
# define qCheckPointer(d) if (d && IsBadReadPtr(d, 1)) return; do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0)
#else
# define qCheckAccess(d) do { qProvokeSegFaultHelper = *(char*)d; } while (0)
# define qCheckPointer(d) do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0)
#endif
const
char
*
stripNamespace
(
const
char
*
type
)
{
...
...
@@ -692,11 +707,14 @@ void QDumper::putEllipsis()
#define TT(type, value) \
"<tr><td>" << type << "</td><td> : </td><td>" << value << "</td></tr>"
static
void
qDumpUnknown
(
QDumper
&
d
)
#define DUMPUNKNOWN_MESSAGE "<internal error>"
static
void
qDumpUnknown
(
QDumper
&
d
,
const
char
*
why
=
0
)
{
P
(
d
,
"iname"
,
d
.
iname
);
P
(
d
,
"addr"
,
d
.
data
);
P
(
d
,
"value"
,
"<internal error>"
);
if
(
!
why
)
why
=
DUMPUNKNOWN_MESSAGE
;
P
(
d
,
"value"
,
why
);
P
(
d
,
"type"
,
d
.
outertype
);
P
(
d
,
"numchild"
,
"0"
);
d
.
disarm
();
...
...
@@ -1078,7 +1096,7 @@ static void qDumpQHash(QDumper &d)
int
n
=
h
->
size
;
if
(
n
<
0
)
qCheck
(
false
)
;
return
;
if
(
n
>
0
)
{
qCheckPointer
(
h
->
fakeNext
);
qCheckPointer
(
*
h
->
buckets
);
...
...
@@ -1181,19 +1199,21 @@ static void qDumpQList(QDumper &d)
{
// This uses the knowledge that QList<T> has only a single member
// of type union { QListData p; QListData::Data *d; };
const
QListData
&
ldata
=
*
reinterpret_cast
<
const
QListData
*>
(
d
.
data
);
const
QListData
::
Data
*
pdata
=
*
reinterpret_cast
<
const
QListData
::
Data
*
const
*>
(
d
.
data
);
qCheckAccess
(
pdata
);
int
nn
=
ldata
.
size
();
if
(
nn
<
0
)
qCheck
(
false
)
;
return
;
if
(
nn
>
0
)
{
qCheckAccess
(
ldata
.
d
->
array
);
//qCheckAccess(ldata.d->array[0]);
//qCheckAccess(ldata.d->array[nn - 1]);
#if QT_VERSION >= 0x040400
if
(
ldata
.
d
->
ref
.
_q_value
<=
0
)
qCheck
(
false
)
;
return
;
#endif
}
...
...
@@ -1262,7 +1282,7 @@ static void qDumpQLinkedList(QDumper &d)
reinterpret_cast
<
const
QLinkedListData
*>
(
deref
(
d
.
data
));
int
nn
=
ldata
->
size
;
if
(
nn
<
0
)
qCheck
(
false
)
;
return
;
int
n
=
nn
;
P
(
d
,
"value"
,
"<"
<<
n
<<
" items>"
);
...
...
@@ -1386,7 +1406,7 @@ static void qDumpQMap(QDumper &d)
int
n
=
h
->
size
;
if
(
n
<
0
)
qCheck
(
false
)
;
return
;
if
(
n
>
0
)
{
qCheckAccess
(
h
->
backward
);
qCheckAccess
(
h
->
forward
[
0
]);
...
...
@@ -1899,7 +1919,7 @@ static void qDumpQSet(QDumper &d)
int
n
=
hd
->
size
;
if
(
n
<
0
)
qCheck
(
false
)
;
return
;
if
(
n
>
0
)
{
qCheckAccess
(
node
);
qCheckPointer
(
node
->
next
);
...
...
@@ -1952,8 +1972,23 @@ static void qDumpQSharedPointer(QDumper &d)
P
(
d
,
"name"
,
"data"
);
qDumpInnerValue
(
d
,
d
.
innertype
,
ptr
.
data
());
d
.
endHash
();
I
(
d
,
"strongref"
,
44
);
I
(
d
,
"weakref"
,
45
);
const
int
v
=
sizeof
(
void
*
);
d
.
beginHash
();
const
void
*
weak
=
addOffset
(
deref
(
addOffset
(
d
.
data
,
v
)),
v
);
P
(
d
,
"name"
,
"weakref"
);
P
(
d
,
"value"
,
*
static_cast
<
const
int
*>
(
weak
));
P
(
d
,
"type"
,
"int"
);
P
(
d
,
"addr"
,
weak
);
P
(
d
,
"numchild"
,
"0"
);
d
.
endHash
();
d
.
beginHash
();
const
void
*
strong
=
addOffset
(
weak
,
sizeof
(
int
));
P
(
d
,
"name"
,
"strongref"
);
P
(
d
,
"value"
,
*
static_cast
<
const
int
*>
(
strong
));
P
(
d
,
"type"
,
"int"
);
P
(
d
,
"addr"
,
strong
);
P
(
d
,
"numchild"
,
"0"
);
d
.
endHash
();
d
<<
"]"
;
}
d
.
disarm
();
...
...
@@ -1982,7 +2017,7 @@ static void qDumpQStringList(QDumper &d)
const
QStringList
&
list
=
*
reinterpret_cast
<
const
QStringList
*>
(
d
.
data
);
int
n
=
list
.
size
();
if
(
n
<
0
)
qCheck
(
false
)
;
return
;
if
(
n
>
0
)
{
qCheckAccess
(
&
list
.
front
());
qCheckAccess
(
&
list
.
back
());
...
...
@@ -2117,7 +2152,7 @@ static void qDumpQVector(QDumper &d)
// from asking for unavailable child details
int
nn
=
v
->
size
;
if
(
nn
<
0
)
qCheck
(
false
)
;
return
;
if
(
nn
>
0
)
{
//qCheckAccess(&vec.front());
//qCheckAccess(&vec.back());
...
...
@@ -2209,7 +2244,8 @@ static void qDumpStdMap(QDumper &d)
p
=
deref
(
p
);
int
nn
=
map
.
size
();
qCheck
(
nn
>=
0
);
if
(
nn
<
0
)
return
;
DummyType
::
const_iterator
it
=
map
.
begin
();
for
(
int
i
=
0
;
i
<
nn
&&
i
<
10
&&
it
!=
map
.
end
();
++
i
,
++
it
)
qCheckAccess
(
it
.
operator
->
());
...
...
@@ -2274,7 +2310,8 @@ static void qDumpStdSet(QDumper &d)
p
=
deref
(
p
);
int
nn
=
set
.
size
();
qCheck
(
nn
>=
0
);
if
(
nn
<
0
)
return
;
DummyType
::
const_iterator
it
=
set
.
begin
();
for
(
int
i
=
0
;
i
<
nn
&&
i
<
10
&&
it
!=
set
.
end
();
++
i
,
++
it
)
qCheckAccess
(
it
.
operator
->
());
...
...
@@ -2361,7 +2398,7 @@ static void qDumpStdVector(QDumper &d)
// from asking for unavailable child details
int
nn
=
(
v
->
finish
-
v
->
start
)
/
d
.
extraInt
[
0
];
if
(
nn
<
0
)
qCheck
(
false
)
;
return
;
if
(
nn
>
0
)
{
qCheckAccess
(
v
->
start
);
qCheckAccess
(
v
->
finish
);
...
...
@@ -2402,10 +2439,14 @@ static void qDumpStdVectorBool(QDumper &d)
static
void
handleProtocolVersion2and3
(
QDumper
&
d
)
{
if
(
!
d
.
outertype
[
0
])
{
qDumpUnknown
(
d
);
return
;
}
#ifdef Q_CC_MSVC // Catch exceptions with MSVC/CDB
__try
{
#endif
d
.
setupTemplateParameters
();
P
(
d
,
"iname"
,
d
.
iname
);
...
...
@@ -2551,6 +2592,12 @@ static void handleProtocolVersion2and3(QDumper & d)
if
(
!
d
.
success
)
qDumpUnknown
(
d
);
#ifdef Q_CC_MSVC // Catch exceptions with MSVC/CDB
}
__except
(
EXCEPTION_EXECUTE_HANDLER
)
{
qDumpUnknown
(
d
,
DUMPUNKNOWN_MESSAGE
" <exception>"
);
}
#endif
}
}
// anonymous namespace
...
...
src/plugins/coreplugin/outputpane.cpp
View file @
cbd85651
...
...
@@ -384,7 +384,7 @@ void OutputPaneManager::ensurePageVisible(int idx)
}
}
// Slot connected to showPage signal of each page
void
OutputPaneManager
::
showPage
(
bool
focus
)
{
int
idx
=
findIndexForPage
(
qobject_cast
<
IOutputPane
*>
(
sender
()));
...
...
src/plugins/debugger/cdb/cdb.pri
View file @
cbd85651
...
...
@@ -34,6 +34,7 @@ HEADERS += \
$$PWD/cdbdebugoutput.h \
$$PWD/cdbsymbolgroupcontext.h \
$$PWD/cdbstacktracecontext.h \
$$PWD/cdbstackframecontext.h \
$$PWD/cdbbreakpoint.h \
$$PWD/cdbmodules.h \
$$PWD/cdbassembler.h \
...
...
@@ -46,6 +47,7 @@ SOURCES += \
$$PWD/cdbdebugeventcallback.cpp \
$$PWD/cdbdebugoutput.cpp \
$$PWD/cdbsymbolgroupcontext.cpp \
$$PWD/cdbstackframecontext.cpp \
$$PWD/cdbstacktracecontext.cpp \
$$PWD/cdbbreakpoint.cpp \
$$PWD/cdbmodules.cpp \
...
...
src/plugins/debugger/cdb/cdbdebugengine.cpp
View file @
cbd85651
...
...
@@ -29,8 +29,9 @@
#include
"cdbdebugengine.h"
#include
"cdbdebugengine_p.h"
#include
"cdbsymbolgroupcontext.h"
#include
"cdbstacktracecontext.h"
#include
"cdbstackframecontext.h"
#include
"cdbsymbolgroupcontext.h"
#include
"cdbbreakpoint.h"
#include
"cdbmodules.h"
#include
"cdbassembler.h"
...
...
@@ -274,7 +275,7 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent,
m_hDebuggeeProcess
(
0
),
m_hDebuggeeThread
(
0
),
m_breakEventMode
(
BreakEventHandle
),
m_dumper
(
&
m_cif
),
m_dumper
(
new
CdbDumperHelper
(
parent
,
&
m_cif
)
)
,
m_watchTimer
(
-
1
),
m_debugEventCallBack
(
engine
),
m_engine
(
engine
),
...
...
@@ -464,7 +465,7 @@ bool CdbDebugEngine::startDebugger()
dumperEnabled
=
false
;
}
}
m_d
->
m_dumper
.
reset
(
dumperLibName
,
dumperEnabled
);
m_d
->
m_dumper
->
reset
(
dumperLibName
,
dumperEnabled
);
m_d
->
m_debuggerManager
->
showStatusMessage
(
"Starting Debugger"
,
-
1
);
QString
errorMessage
;
bool
rc
=
false
;
...
...
@@ -590,19 +591,20 @@ void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG6
}
else
{
m_currentThreadId
=
0
;
}
// Set initial breakpoints
// Clear any saved breakpoints and set initial breakpoints
m_engine
->
executeDebuggerCommand
(
QLatin1String
(
"bc"
));
if
(
m_debuggerManagerAccess
->
breakHandler
()
->
hasPendingBreakpoints
())
m_engine
->
attemptBreakpointSynchronization
();
// At any event, we want a temporary breakpoint at main() to load
// the dumpers.
if
(
m_dumper
.
state
()
==
CdbDumperHelper
::
NotLoaded
)
{
if
(
m_dumper
->
state
()
==
CdbDumperHelper
::
NotLoaded
)
{
if
(
!
hasBreakPointAtMain
(
m_debuggerManagerAccess
->
breakHandler
()))
{
QString
errorMessage
;
CDBBreakPoint
mainBP
;
// Do not resolve at this point in the rare event someone
// has main in a module
mainBP
.
funcName
=
QLatin1String
(
"main"
);
mainBP
.
oneShot
=
true
;
QString
errorMessage
;
if
(
!
mainBP
.
add
(
m_cif
.
debugControl
,
&
errorMessage
))
m_debuggerManagerAccess
->
showQtDumperLibraryWarning
(
errorMessage
);
}
...
...
@@ -675,13 +677,13 @@ void CdbDebugEngine::exitDebugger()
killWatchTimer
();
}
CdbS
ymbolGroup
Context
*
CdbDebugEnginePrivate
::
getStackFrame
SymbolGroup
Context
(
int
frameIndex
,
QString
*
errorMessage
)
const
CdbS
tackFrame
Context
*
CdbDebugEnginePrivate
::
getStackFrameContext
(
int
frameIndex
,
QString
*
errorMessage
)
const
{
if
(
!
m_currentStackTrace
)
{
*
errorMessage
=
QLatin1String
(
msgNoStackTraceC
);
return
0
;
}
if
(
CdbS
ymbolGroup
Context
*
sg
=
m_currentStackTrace
->
symbolGroup
ContextAt
(
frameIndex
,
errorMessage
))
if
(
CdbS
tackFrame
Context
*
sg
=
m_currentStackTrace
->
frame
ContextAt
(
frameIndex
,
errorMessage
))
return
sg
;
return
0
;
}
...
...
@@ -718,8 +720,8 @@ bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
}
bool
success
=
false
;
if
(
CdbS
ymbolGroup
Context
*
sgc
=
getStackFrame
SymbolGroup
Context
(
frameIndex
,
errorMessage
))
success
=
CdbSymbolGroupContext
::
populateModelInitially
(
sgc
,
wh
,
errorMessage
);
if
(
CdbS
tackFrame
Context
*
sgc
=
getStackFrameContext
(
frameIndex
,
errorMessage
))
success
=
sgc
->
populateModelInitially
(
wh
,
errorMessage
);
wh
->
rebuildModel
();
return
success
;
...
...
@@ -800,8 +802,8 @@ void CdbDebugEngine::updateWatchModel()
filterEvaluateWatchers
(
&
incomplete
,
watchHandler
);
// Do locals. We might get called while running when someone enters watchers
if
(
!
incomplete
.
empty
())
{
CdbS
ymbolGroup
Context
*
sg
=
m_d
->
m_currentStackTrace
->
symbolGroup
ContextAt
(
frameIndex
,
&
errorMessage
);
if
(
!
sg
||
!
CdbSymbolGroupContext
::
completeModel
(
sg
,
incomplete
,
watchHandler
,
&
errorMessage
))
CdbS
tackFrame
Context
*
sg
=
m_d
->
m_currentStackTrace
->
frame
ContextAt
(
frameIndex
,
&
errorMessage
);
if
(
!
sg
||
!
sg
->
completeModel
(
incomplete
,
watchHandler
,
&
errorMessage
))
break
;
}
watchHandler
->
rebuildModel
();
...
...
@@ -1016,7 +1018,7 @@ void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &v
bool
success
=
false
;
do
{
QString
newValue
;
CdbS
ymbolGroup
Context
*
sg
=
m_d
->
getStackFrame
SymbolGroup
Context
(
frameIndex
,
&
errorMessage
);
CdbS
tackFrame
Context
*
sg
=
m_d
->
getStackFrameContext
(
frameIndex
,
&
errorMessage
);
if
(
!
sg
)
break
;
if
(
!
sg
->
assignValue
(
expr
,
value
,
&
newValue
,
&
errorMessage
))
...
...
@@ -1061,17 +1063,30 @@ bool CdbDebugEngine::evaluateExpression(const QString &expression,
QString
*
value
,
QString
*
type
,
QString
*
errorMessage
)
{
DEBUG_VALUE
debugValue
;
if
(
!
m_d
->
evaluateExpression
(
m_d
->
m_cif
.
debugControl
,
expression
,
&
debugValue
,
errorMessage
))
return
false
;
*
value
=
CdbSymbolGroupContext
::
debugValueToString
(
debugValue
,
m_d
->
m_cif
.
debugControl
,
type
);
return
true
;
}
bool
CdbDebugEnginePrivate
::
evaluateExpression
(
CIDebugControl
*
ctrl
,
const
QString
&
expression
,
DEBUG_VALUE
*
debugValue
,
QString
*
errorMessage
)
{
if
(
debugCDB
>
1
)
qDebug
()
<<
Q_FUNC_INFO
<<
expression
;
DEBUG_VALUE
debugValue
;
memset
(
&
debugValue
,
0
,
sizeof
(
DEBUG_VALUE
));
memset
(
debugValue
,
0
,
sizeof
(
DEBUG_VALUE
));
// Original syntax must be restored, else setting breakpoints will fail.
SyntaxSetter
syntaxSetter
(
m_d
->
m_cif
.
debugCon
tr
o
l
,
DEBUG_EXPR_CPLUSPLUS
);
SyntaxSetter
syntaxSetter
(
c
trl
,
DEBUG_EXPR_CPLUSPLUS
);
ULONG
errorPosition
=
0
;
const
HRESULT
hr
=
m_d
->
m_cif
.
debugControl
->
EvaluateWide
(
expression
.
utf16
(),
DEBUG_VALUE_INVALID
,
&
debugValue
,
&
errorPosition
);
if
(
FAILED
(
hr
))
{
const
HRESULT
hr
=
ctrl
->
EvaluateWide
(
expression
.
utf16
(),
DEBUG_VALUE_INVALID
,
debugValue
,
&
errorPosition
);
if
(
FAILED
(
hr
))
{
if
(
HRESULT_CODE
(
hr
)
==
517
)
{
*
errorMessage
=
QString
::
fromLatin1
(
"Unable to evaluate '%1': Expression out of scope."
).
arg
(
expression
);
...
...
@@ -1081,7 +1096,6 @@ bool CdbDebugEngine::evaluateExpression(const QString &expression,
}
return
false
;
}
*
value
=
CdbSymbolGroupContext
::
debugValueToString
(
debugValue
,
m_d
->
m_cif
.
debugControl
,
type
);
return
true
;
}
...
...
@@ -1355,14 +1369,14 @@ void CdbDebugEnginePrivate::handleDebugEvent()
case
BreakEventHandle
:
case
BreakEventMain
:
if
(
mode
==
BreakEventMain
)
m_dumper
.
load
(
m_debuggerManager
,
m_debuggerManagerAccess
);
m_dumper
->
load
(
m_debuggerManager
);
m_debuggerManagerAccess
->
notifyInferiorStopped
();
updateThreadList
();
updateStackTrace
();
break
;
case
BreakEventMainLoadDumpers
:
// Temp stop to load dumpers
m_dumper
.
load
(
m_debuggerManager
,
m_debuggerManagerAccess
);
m_dumper
->
load
(
m_debuggerManager
);
m_engine
->
startWatchTimer
();
continueInferiorProcess
();
break
;
...
...
@@ -1436,7 +1450,7 @@ void CdbDebugEnginePrivate::updateStackTrace()
QString
errorMessage
;
m_engine
->
reloadRegisters
();
m_currentStackTrace
=
CdbStackTraceContext
::
create
(
&
m_
cif
,
m_currentThreadId
,
&
errorMessage
);
CdbStackTraceContext
::
create
(
m_
dumper
,
m_currentThreadId
,
&
errorMessage
);
if
(
!
m_currentStackTrace
)
{
qWarning
(
"%s: failed to create trace context: %s"
,
Q_FUNC_INFO
,
qPrintable
(
errorMessage
));
return
;
...
...
src/plugins/debugger/cdb/cdbdebugengine_p.h
View file @
cbd85651
...
...
@@ -46,7 +46,7 @@ namespace Internal {
class
DebuggerManager
;
class
IDebuggerManagerAccessForEngines
;
class
WatchHandler
;
class
CdbS
ymbolGroup
Context
;
class
CdbS
tackFrame
Context
;
class
CdbStackTraceContext
;
// Thin wrapper around the 'DBEng' debugger engine shared library
...
...
@@ -125,7 +125,7 @@ struct CdbDebugEnginePrivate
void
cleanStackTrace
();
void
clearForRun
();
void
handleModuleLoad
(
const
QString
&
);
CdbS
ymbolGroup
Context
*
getStackFrame
SymbolGroup
Context
(
int
frameIndex
,
QString
*
errorMessage
)
const
;
CdbS
tackFrame
Context
*
getStackFrameContext
(
int
frameIndex
,
QString
*
errorMessage
)
const
;
void
clearDisplay
();
bool
interruptInterferiorProcess
(
QString
*
errorMessage
);
...
...
@@ -136,6 +136,7 @@ struct CdbDebugEnginePrivate
bool
attemptBreakpointSynchronization
(
QString
*
errorMessage
);
static
bool
executeDebuggerCommand
(
CIDebugControl
*
ctrl
,
const
QString
&
command
,
QString
*
errorMessage
);
static
bool
evaluateExpression
(
CIDebugControl
*
ctrl
,
const
QString
&
expression
,
DEBUG_VALUE
*
v
,
QString
*
errorMessage
);
const
QSharedPointer
<
CdbOptions
>
m_options
;
HANDLE
m_hDebuggeeProcess
;
...
...
@@ -147,7 +148,7 @@ struct CdbDebugEnginePrivate
CdbComInterfaces
m_cif
;
CdbDebugEventCallback
m_debugEventCallBack
;
CdbDebugOutput
m_debugOutputCallBack
;
CdbDumperHelper
m_dumper
;
QSharedPointer
<
CdbDumperHelper
>
m_dumper
;
CdbDebugEngine
*
m_engine
;
DebuggerManager
*
m_debuggerManager
;
...
...
src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
View file @
cbd85651
...
...
@@ -318,14 +318,16 @@ void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str)
}
// Format exception with stacktrace in case of C++ exception
void
formatException
(
const
EXCEPTION_RECORD64
*
e
,
CdbComInterfaces
&
cif
,
QTextStream
&
str
)
void
formatException
(
const
EXCEPTION_RECORD64
*
e
,
const
QSharedPointer
<
CdbDumperHelper
>
&
dumper
,
QTextStream
&
str
)
{
formatException
(
e
,
str
);
if
(
e
->
ExceptionCode
==
cppExceptionCode
)
{
QString
errorMessage
;
ULONG
currentThreadId
=
0
;
cif
.
debugSystemObjects
->
GetCurrentThreadId
(
&
currentThreadId
);
if
(
CdbStackTraceContext
*
stc
=
CdbStackTraceContext
::
create
(
&
cif
,
currentThreadId
,
&
errorMessage
))
{
dumper
->
comInterfaces
()
->
debugSystemObjects
->
GetCurrentThreadId
(
&
currentThreadId
);
if
(
CdbStackTraceContext
*
stc
=
CdbStackTraceContext
::
create
(
dumper
,
currentThreadId
,
&
errorMessage
))
{
str
<<
"at:
\n
"
;
stc
->
format
(
str
);
str
<<
'\n'
;
...
...
@@ -343,7 +345,7 @@ STDMETHODIMP CdbDebugEventCallback::Exception(
QString
msg
;
{
QTextStream
str
(
&
msg
);
formatException
(
Exception
,
m_pEngine
->
m_d
->
m_
cif
,
str
);
formatException
(
Exception
,
m_pEngine
->
m_d
->
m_
dumper
,
str
);
}
if
(
debugCDB
)
qDebug
()
<<
Q_FUNC_INFO
<<
'\n'
<<
msg
;
...
...
@@ -469,6 +471,37 @@ STDMETHODIMP CdbDebugEventCallback::SystemError(
return
S_OK
;
}
// -----------ExceptionLoggerEventCallback
CdbExceptionLoggerEventCallback
::
CdbExceptionLoggerEventCallback
(
const
QString
&
logPrefix
,
IDebuggerManagerAccessForEngines
*
access
)
:
m_logPrefix
(
logPrefix
),
m_access
(
access
)
{
}
STDMETHODIMP
CdbExceptionLoggerEventCallback
::
GetInterestMask
(
THIS_
__out
PULONG
mask
)
{
*
mask
=
DEBUG_EVENT_EXCEPTION
;
return
S_OK
;
}
STDMETHODIMP
CdbExceptionLoggerEventCallback
::
Exception
(
THIS_
__in
PEXCEPTION_RECORD64
Exception
,
__in
ULONG
/* FirstChance */
)
{
m_exceptionMessages
.
push_back
(
QString
());
{
QTextStream
str
(
&
m_exceptionMessages
.
back
());
formatException
(
Exception
,
str
);
}
if
(
debugCDB
)
qDebug
()
<<
Q_FUNC_INFO
<<
'\n'
<<
m_exceptionMessages
.
back
();
m_access
->
showDebuggerOutput
(
m_logPrefix
,
m_exceptionMessages
.
back
());
return
S_OK
;
}
// -----------IgnoreDebugEventCallback
IgnoreDebugEventCallback
::
IgnoreDebugEventCallback
()
{
...
...
src/plugins/debugger/cdb/cdbdebugeventcallback.h
View file @
cbd85651
...
...
@@ -32,12 +32,13 @@
#include
"cdbcom.h"
#include
<QtCore/Q
tGlobal
>
#include
<QtCore/Q
StringList
>
namespace
Debugger
{
namespace
Internal
{
class
CdbDebugEngine
;
class
IDebuggerManagerAccessForEngines
;
// Base class for event callbacks that takes care
// Active X magic. Provides base implementations with
...
...
@@ -235,6 +236,34 @@ private:
CdbDebugEngine
*
m_pEngine
;
};
// Event handler logs exceptions to the debugger window
// and ignores the rest. To be used for running dumper calls.
class
CdbExceptionLoggerEventCallback
:
public
CdbDebugEventCallbackBase
{
public:
explicit
CdbExceptionLoggerEventCallback
(
const
QString
&
logPrefix
,
IDebuggerManagerAccessForEngines
*
access
);
STDMETHOD
(
GetInterestMask
)(
THIS_
__out
PULONG
mask
);
STDMETHOD
(
Exception
)(
THIS_
__in
PEXCEPTION_RECORD64
Exception
,
__in
ULONG
FirstChance
);
int
exceptionCount
()
const
{
return
m_exceptionMessages
.
size
();
}
QStringList
exceptionMessages
()
const
{
return
m_exceptionMessages
;
}
private:
const
QString
m_logPrefix
;
IDebuggerManagerAccessForEngines
*
m_access
;
QStringList
m_exceptionMessages
;
};
// Event handler that ignores everything
class
IgnoreDebugEventCallback
:
public
CdbDebugEventCallbackBase
{
...
...
src/plugins/debugger/cdb/cdbdebugoutput.cpp
View file @
cbd85651
...
...
@@ -80,7 +80,8 @@ STDMETHODIMP CdbDebugOutputBase::Output(
IN
PCWSTR
text
)
{
output
(
mask
,
QString
::
fromUtf16
(
text
));
const
QString
msg
=
QString
::
fromUtf16
(
text
);
output
(
mask
,
msg
.
trimmed
());
return
S_OK
;
}
...
...
src/plugins/debugger/cdb/cdbdumperhelper.cpp
View file @
cbd85651
This diff is collapsed.
Click to expand it.
src/plugins/debugger/cdb/cdbdumperhelper.h
View file @
cbd85651
...
...
@@ -30,7 +30,10 @@
#ifndef CDBDUMPERHELPER_H
#define CDBDUMPERHELPER_H
#include
"watchutils.h"
#include
"cdbcom.h"
#include
<QtCore/QStringList>
#include
<QtCore/QMap>
namespace
Debugger
{
namespace
Internal
{
...
...
@@ -66,7 +69,8 @@ public:
Failed
};
explicit
CdbDumperHelper
(
CdbComInterfaces
*
cif
);
explicit
CdbDumperHelper
(
IDebuggerManagerAccessForEngines
*
access
,
CdbComInterfaces
*
cif
);
~
CdbDumperHelper
();