Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Marco Bubke
flatpak-qt-creator
Commits
ad5a0010
Commit
ad5a0010
authored
Mar 25, 2009
by
Friedemann Kleint
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Factor out common debugger watch functionality
Factor out watch function, improve debug output.
parent
05587f1f
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
430 additions
and
275 deletions
+430
-275
src/plugins/debugger/cdb/cdb.pri
src/plugins/debugger/cdb/cdb.pri
+6
-2
src/plugins/debugger/cdb/cdbdebugengine.cpp
src/plugins/debugger/cdb/cdbdebugengine.cpp
+21
-5
src/plugins/debugger/cdb/cdbdebugengine.h
src/plugins/debugger/cdb/cdbdebugengine.h
+1
-0
src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
+1
-3
src/plugins/debugger/debugger.pro
src/plugins/debugger/debugger.pro
+2
-0
src/plugins/debugger/debuggermanager.cpp
src/plugins/debugger/debuggermanager.cpp
+25
-3
src/plugins/debugger/gdbengine.cpp
src/plugins/debugger/gdbengine.cpp
+1
-262
src/plugins/debugger/watchutils.cpp
src/plugins/debugger/watchutils.cpp
+303
-0
src/plugins/debugger/watchutils.h
src/plugins/debugger/watchutils.h
+70
-0
No files found.
src/plugins/debugger/cdb/cdb.pri
View file @
ad5a0010
# Detect presence of "Debugging Tools For Windows"
# in case VS compilers are used.
win32 {
# ---- Detect Debugging Tools For Windows
contains(QMAKE_CXX, cl) {
CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows/sdk"
...
...
@@ -26,6 +29,7 @@ SOURCES += \
$$PWD/cdbdebugeventcallback.cpp \
$$PWD/cdbdebugoutput.cpp
} else {
error("Debugging Tools for Windows could not be found in $$CDB_PATH")
message("Debugging Tools for Windows could not be found in $$CDB_PATH")
}
}
}
src/plugins/debugger/cdb/cdbdebugengine.cpp
View file @
ad5a0010
...
...
@@ -360,6 +360,16 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString *
return
true
;
}
void
CdbDebugEngine
::
processTerminated
(
unsigned
long
exitCode
)
{
if
(
debugCDB
)
qDebug
()
<<
Q_FUNC_INFO
<<
exitCode
;
m_d
->
setDebuggeeHandles
(
0
,
0
);
m_d
->
m_debuggerManagerAccess
->
notifyInferiorExited
();
m_d
->
m_debuggerManager
->
exitDebugger
();
}
void
CdbDebugEngine
::
exitDebugger
()
{
if
(
debugCDB
)
...
...
@@ -380,7 +390,9 @@ void CdbDebugEngine::exitDebugger()
break
;
case
StartExternal
:
case
StartInternal
:
// Terminate and waitr for stop events.
hr
=
m_d
->
m_pDebugClient
->
TerminateCurrentProcess
();
QCoreApplication
::
processEvents
(
QEventLoop
::
ExcludeUserInputEvents
);
if
(
debugCDB
)
qDebug
()
<<
Q_FUNC_INFO
<<
"terminated"
<<
msgDebugEngineComResult
(
hr
);
...
...
@@ -469,7 +481,7 @@ bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
value
=
QLatin1String
(
"<unknown>"
);
}
WatchData
wd
;
wd
.
iname
=
QLatin1String
(
"local"
);
wd
.
iname
=
QLatin1String
(
"local
.
"
)
+
name
;
wd
.
name
=
name
;
wd
.
value
=
value
;
wd
.
type
=
type
;
...
...
@@ -592,6 +604,7 @@ void CdbDebugEngine::continueInferior()
m_d
->
m_debuggerManager
->
resetLocation
();
ULONG
executionStatus
;
m_d
->
m_debuggerManagerAccess
->
notifyInferiorRunningRequested
();
HRESULT
hr
=
m_d
->
m_pDebugControl
->
GetExecutionStatus
(
&
executionStatus
);
if
(
SUCCEEDED
(
hr
)
&&
executionStatus
!=
DEBUG_STATUS_GO
)
{
hr
=
m_d
->
m_pDebugControl
->
SetExecutionStatus
(
DEBUG_STATUS_GO
);
...
...
@@ -654,8 +667,10 @@ void CdbDebugEngine::activateFrame(int frameIndex)
if
(
debugCDB
)
qDebug
()
<<
Q_FUNC_INFO
<<
frameIndex
;
if
(
m_d
->
m_debuggerManager
->
status
()
!=
DebuggerInferiorStopped
)
if
(
m_d
->
m_debuggerManager
->
status
()
!=
DebuggerInferiorStopped
)
{
qWarning
(
"WARNING %s: invoked while debuggee is running
\n
"
,
Q_FUNC_INFO
);
return
;
}
QString
errorMessage
;
bool
success
=
false
;
...
...
@@ -793,7 +808,7 @@ void CdbDebugEngine::timerEvent(QTimerEvent* te)
const
HRESULT
hr
=
m_d
->
m_pDebugControl
->
WaitForEvent
(
0
,
1
);
if
(
debugCDB
)
if
(
debugCDB
>
1
||
hr
!=
S_FALSE
)
qDebug
()
<<
Q_FUNC_INFO
<<
"WaitForEvent"
<<
msgDebugEngineComResult
(
hr
);
qDebug
()
<<
Q_FUNC_INFO
<<
"WaitForEvent"
<<
m_d
->
m_debuggerManager
->
status
()
<<
msgDebugEngineComResult
(
hr
);
switch
(
hr
)
{
case
S_OK
:
...
...
@@ -974,9 +989,10 @@ void CdbDebugEnginePrivate::updateStackTrace()
}
}
void
CdbDebugEnginePrivate
::
handleDebugOutput
(
const
char
*
szOutputString
)
void
CdbDebugEnginePrivate
::
handleDebugOutput
(
const
char
*
szOutputString
)
{
qDebug
()
<<
Q_FUNC_INFO
<<
szOutputString
;
if
(
debugCDB
&&
strstr
(
szOutputString
,
"ModLoad:"
)
==
0
)
qDebug
()
<<
Q_FUNC_INFO
<<
szOutputString
;
m_debuggerManagerAccess
->
showApplicationOutput
(
QString
::
fromLocal8Bit
(
szOutputString
));
}
...
...
src/plugins/debugger/cdb/cdbdebugengine.h
View file @
ad5a0010
...
...
@@ -104,6 +104,7 @@ private:
bool
startDebuggerWithExecutable
(
DebuggerStartMode
sm
,
QString
*
errorMessage
);
void
startWatchTimer
();
void
killWatchTimer
();
void
processTerminated
(
unsigned
long
exitCode
);
CdbDebugEnginePrivate
*
m_d
;
...
...
src/plugins/debugger/cdb/cdbdebugeventcallback.cpp
View file @
ad5a0010
...
...
@@ -192,9 +192,7 @@ STDMETHODIMP CdbDebugEventCallback::ExitProcess(
{
if
(
debugCDB
)
qDebug
()
<<
Q_FUNC_INFO
<<
ExitCode
;
m_pEngine
->
m_d
->
setDebuggeeHandles
(
0
,
0
);
m_pEngine
->
m_d
->
m_debuggerManagerAccess
->
notifyInferiorExited
();
m_pEngine
->
processTerminated
(
ExitCode
);
return
S_OK
;
}
...
...
src/plugins/debugger/debugger.pro
View file @
ad5a0010
...
...
@@ -26,6 +26,7 @@ HEADERS += \
debuggerrunner
.
h
\
disassemblerhandler
.
h
\
disassemblerwindow
.
h
\
watchutils
.
h
\
gdbengine
.
h
\
gdbmi
.
h
\
idebuggerengine
.
h
\
...
...
@@ -56,6 +57,7 @@ SOURCES += \
debuggerrunner
.
cpp
\
disassemblerhandler
.
cpp
\
disassemblerwindow
.
cpp
\
watchutils
.
cpp
\
gdbengine
.
cpp
\
gdbmi
.
cpp
\
moduleshandler
.
cpp
\
...
...
src/plugins/debugger/debuggermanager.cpp
View file @
ad5a0010
...
...
@@ -88,6 +88,25 @@ using namespace Debugger::Constants;
static
const
QString
tooltipIName
=
"tooltip"
;
static
const
char
*
stateName
(
int
s
)
{
switch
(
s
)
{
case
DebuggerProcessNotReady
:
return
"DebuggerProcessNotReady"
;
case
DebuggerProcessStartingUp
:
return
"DebuggerProcessStartingUp"
;
case
DebuggerInferiorRunningRequested
:
return
"DebuggerInferiorRunningRequested"
;
case
DebuggerInferiorRunning
:
return
"DebuggerInferiorRunning"
;
case
DebuggerInferiorStopRequested
:
return
"DebuggerInferiorStopRequested"
;
case
DebuggerInferiorStopped
:
return
"DebuggerInferiorStopped"
;
}
return
"<unknown>"
;
}
///////////////////////////////////////////////////////////////////////
//
// BreakByFunctionDialog
...
...
@@ -1133,13 +1152,16 @@ static bool isAllowedTransition(int from, int to)
void
DebuggerManager
::
setStatus
(
int
status
)
{
if
(
Debugger
::
Constants
::
Internal
::
debug
)
qDebug
()
<<
Q_FUNC_INFO
<<
"STATUS CHANGE: from"
<<
m_status
<<
"to"
<<
status
;
qDebug
()
<<
Q_FUNC_INFO
<<
"STATUS CHANGE: from"
<<
stateName
(
m_status
)
<<
"to"
<<
stateName
(
status
)
;
if
(
status
==
m_status
)
return
;
if
(
!
isAllowedTransition
(
m_status
,
status
))
qDebug
()
<<
"UNEXPECTED TRANSITION: "
<<
m_status
<<
status
;
if
(
!
isAllowedTransition
(
m_status
,
status
))
{
const
QString
msg
=
QString
::
fromLatin1
(
"%1: UNEXPECTED TRANSITION: %2 -> %3"
).
arg
(
QLatin1String
(
Q_FUNC_INFO
),
QLatin1String
(
stateName
(
m_status
)),
QLatin1String
(
stateName
(
status
)));
qWarning
(
"%s"
,
qPrintable
(
msg
));
}
m_status
=
status
;
...
...
src/plugins/debugger/gdbengine.cpp
View file @
ad5a0010
...
...
@@ -29,6 +29,7 @@
#include "gdbengine.h"
#include "watchutils.h"
#include "debuggeractions.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
...
...
@@ -152,88 +153,12 @@ enum GdbCommandType
WatchDumpCustomEditValue
,
};
QString
dotEscape
(
QString
str
)
{
str
.
replace
(
' '
,
'.'
);
str
.
replace
(
'\\'
,
'.'
);
str
.
replace
(
'/'
,
'.'
);
return
str
;
}
QString
currentTime
()
{
return
QTime
::
currentTime
().
toString
(
"hh:mm:ss.zzz"
);
}
static
int
&
currentToken
()
{
static
int
token
=
0
;
return
token
;
}
static
bool
isSkippableFunction
(
const
QString
&
funcName
,
const
QString
&
fileName
)
{
if
(
fileName
.
endsWith
(
"kernel/qobject.cpp"
))
return
true
;
if
(
fileName
.
endsWith
(
"kernel/moc_qobject.cpp"
))
return
true
;
if
(
fileName
.
endsWith
(
"kernel/qmetaobject.cpp"
))
return
true
;
if
(
fileName
.
endsWith
(
".moc"
))
return
true
;
if
(
funcName
.
endsWith
(
"::qt_metacall"
))
return
true
;
return
false
;
}
static
bool
isLeavableFunction
(
const
QString
&
funcName
,
const
QString
&
fileName
)
{
if
(
funcName
.
endsWith
(
"QObjectPrivate::setCurrentSender"
))
return
true
;
if
(
fileName
.
endsWith
(
"kernel/qmetaobject.cpp"
)
&&
funcName
.
endsWith
(
"QMetaObject::methodOffset"
))
return
true
;
if
(
fileName
.
endsWith
(
"kernel/qobject.h"
))
return
true
;
if
(
fileName
.
endsWith
(
"kernel/qobject.cpp"
)
&&
funcName
.
endsWith
(
"QObjectConnectionListVector::at"
))
return
true
;
if
(
fileName
.
endsWith
(
"kernel/qobject.cpp"
)
&&
funcName
.
endsWith
(
"~QObject"
))
return
true
;
if
(
fileName
.
endsWith
(
"thread/qmutex.cpp"
))
return
true
;
if
(
fileName
.
endsWith
(
"thread/qthread.cpp"
))
return
true
;
if
(
fileName
.
endsWith
(
"thread/qthread_unix.cpp"
))
return
true
;
if
(
fileName
.
endsWith
(
"thread/qmutex.h"
))
return
true
;
if
(
fileName
.
contains
(
"thread/qbasicatomic"
))
return
true
;
if
(
fileName
.
contains
(
"thread/qorderedmutexlocker_p"
))
return
true
;
if
(
fileName
.
contains
(
"arch/qatomic"
))
return
true
;
if
(
fileName
.
endsWith
(
"tools/qvector.h"
))
return
true
;
if
(
fileName
.
endsWith
(
"tools/qlist.h"
))
return
true
;
if
(
fileName
.
endsWith
(
"tools/qhash.h"
))
return
true
;
if
(
fileName
.
endsWith
(
"tools/qmap.h"
))
return
true
;
if
(
fileName
.
endsWith
(
"tools/qstring.h"
))
return
true
;
if
(
fileName
.
endsWith
(
"global/qglobal.h"
))
return
true
;
return
false
;
}
///////////////////////////////////////////////////////////////////////
//
// GdbEngine
...
...
@@ -364,12 +289,6 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
q
->
exitDebugger
();
}
static
inline
bool
isNameChar
(
char
c
)
{
// could be 'stopped' or 'shlibs-added'
return
(
c
>=
'a'
&&
c
<=
'z'
)
||
c
==
'-'
;
}
#if 0
static void dump(const char *first, const char *middle, const QString & to)
{
...
...
@@ -1575,7 +1494,6 @@ int GdbEngine::currentFrame() const
return
qq
->
stackHandler
()
->
currentIndex
();
}
bool
GdbEngine
::
startDebugger
()
{
debugMessage
(
theDebuggerSettings
()
->
dump
());
...
...
@@ -2743,43 +2661,6 @@ static QString m_toolTipExpression;
static
QPoint
m_toolTipPos
;
static
QMap
<
QString
,
WatchData
>
m_toolTipCache
;
static
bool
hasLetterOrNumber
(
const
QString
&
exp
)
{
for
(
int
i
=
exp
.
size
();
--
i
>=
0
;
)
if
(
exp
[
i
].
isLetterOrNumber
()
||
exp
[
i
]
==
'_'
)
return
true
;
return
false
;
}
static
bool
hasSideEffects
(
const
QString
&
exp
)
{
// FIXME: complete?
return
exp
.
contains
(
"-="
)
||
exp
.
contains
(
"+="
)
||
exp
.
contains
(
"/="
)
||
exp
.
contains
(
"*="
)
||
exp
.
contains
(
"&="
)
||
exp
.
contains
(
"|="
)
||
exp
.
contains
(
"^="
)
||
exp
.
contains
(
"--"
)
||
exp
.
contains
(
"++"
);
}
static
bool
isKeyWord
(
const
QString
&
exp
)
{
// FIXME: incomplete
return
exp
==
QLatin1String
(
"class"
)
||
exp
==
QLatin1String
(
"const"
)
||
exp
==
QLatin1String
(
"do"
)
||
exp
==
QLatin1String
(
"if"
)
||
exp
==
QLatin1String
(
"return"
)
||
exp
==
QLatin1String
(
"struct"
)
||
exp
==
QLatin1String
(
"template"
)
||
exp
==
QLatin1String
(
"void"
)
||
exp
==
QLatin1String
(
"volatile"
)
||
exp
==
QLatin1String
(
"while"
);
}
void
GdbEngine
::
setToolTipExpression
(
const
QPoint
&
pos
,
const
QString
&
exp0
)
{
//qDebug() << "SET TOOLTIP EXP" << pos << exp0;
...
...
@@ -2886,85 +2767,6 @@ void GdbEngine::setToolTipExpression(const QPoint &pos, const QString &exp0)
static
const
QString
strNotInScope
=
QLatin1String
(
"<not in scope>"
);
static
bool
isPointerType
(
const
QString
&
type
)
{
return
type
.
endsWith
(
"*"
)
||
type
.
endsWith
(
"* const"
);
}
static
bool
isAccessSpecifier
(
const
QString
&
str
)
{
static
const
QStringList
items
=
QStringList
()
<<
"private"
<<
"protected"
<<
"public"
;
return
items
.
contains
(
str
);
}
static
bool
startsWithDigit
(
const
QString
&
str
)
{
return
!
str
.
isEmpty
()
&&
str
[
0
]
>=
'0'
&&
str
[
0
]
<=
'9'
;
}
QString
stripPointerType
(
QString
type
)
{
if
(
type
.
endsWith
(
"*"
))
type
.
chop
(
1
);
if
(
type
.
endsWith
(
"* const"
))
type
.
chop
(
7
);
if
(
type
.
endsWith
(
' '
))
type
.
chop
(
1
);
return
type
;
}
static
QString
gdbQuoteTypes
(
const
QString
&
type
)
{
// gdb does not understand sizeof(Core::IFile*).
// "sizeof('Core::IFile*')" is also not acceptable,
// it needs to be "sizeof('Core::IFile'*)"
//
// We never will have a perfect solution here (even if we had a full blown
// C++ parser as we do not have information on what is a type and what is
// a variable name. So "a<b>::c" could either be two comparisons of values
// 'a', 'b' and '::c', or a nested type 'c' in a template 'a<b>'. We
// assume here it is the latter.
//return type;
// (*('myns::QPointer<myns::QObject>*'*)0x684060)" is not acceptable
// (*('myns::QPointer<myns::QObject>'**)0x684060)" is acceptable
if
(
isPointerType
(
type
))
return
gdbQuoteTypes
(
stripPointerType
(
type
))
+
"*"
;
QString
accu
;
QString
result
;
int
templateLevel
=
0
;
for
(
int
i
=
0
;
i
!=
type
.
size
();
++
i
)
{
QChar
c
=
type
.
at
(
i
);
if
(
c
.
isLetterOrNumber
()
||
c
==
'_'
||
c
==
':'
||
c
==
' '
)
{
accu
+=
c
;
}
else
if
(
c
==
'<'
)
{
++
templateLevel
;
accu
+=
c
;
}
else
if
(
c
==
'<'
)
{
--
templateLevel
;
accu
+=
c
;
}
else
if
(
templateLevel
>
0
)
{
accu
+=
c
;
}
else
{
if
(
accu
.
contains
(
':'
)
||
accu
.
contains
(
'<'
))
result
+=
'\''
+
accu
+
'\''
;
else
result
+=
accu
;
accu
.
clear
();
result
+=
c
;
}
}
if
(
accu
.
contains
(
':'
)
||
accu
.
contains
(
'<'
))
result
+=
'\''
+
accu
+
'\''
;
else
result
+=
accu
;
//qDebug() << "GDB_QUOTING" << type << " TO " << result;
return
result
;
}
static
void
setWatchDataValue
(
WatchData
&
data
,
const
GdbMi
&
mi
,
int
encoding
=
0
)
{
...
...
@@ -3048,68 +2850,6 @@ static void setWatchDataSAddress(WatchData &data, const GdbMi &mi)
data
.
saddr
=
mi
.
data
();
}
static
bool
extractTemplate
(
const
QString
&
type
,
QString
*
tmplate
,
QString
*
inner
)
{
// Input "Template<Inner1,Inner2,...>::Foo" will return "Template::Foo" in
// 'tmplate' and "Inner1@Inner2@..." etc in 'inner'. Result indicates
// whether parsing was successful
int
level
=
0
;
bool
skipSpace
=
false
;
for
(
int
i
=
0
;
i
!=
type
.
size
();
++
i
)
{
QChar
c
=
type
[
i
];
if
(
c
==
' '
&&
skipSpace
)
{
skipSpace
=
false
;
}
else
if
(
c
==
'<'
)
{
*
(
level
==
0
?
tmplate
:
inner
)
+=
c
;
++
level
;
}
else
if
(
c
==
'>'
)
{
--
level
;
*
(
level
==
0
?
tmplate
:
inner
)
+=
c
;
}
else
if
(
c
==
','
)
{
*
inner
+=
(
level
==
1
)
?
'@'
:
','
;
skipSpace
=
true
;
}
else
{
*
(
level
==
0
?
tmplate
:
inner
)
+=
c
;
}
}
*
tmplate
=
tmplate
->
trimmed
();
*
tmplate
=
tmplate
->
remove
(
"<>"
);
*
inner
=
inner
->
trimmed
();
//qDebug() << "EXTRACT TEMPLATE: " << *tmplate << *inner << " FROM " << type;
return
!
inner
->
isEmpty
();
}
static
QString
extractTypeFromPTypeOutput
(
const
QString
&
str
)
{
int
pos0
=
str
.
indexOf
(
'='
);
int
pos1
=
str
.
indexOf
(
'{'
);
int
pos2
=
str
.
lastIndexOf
(
'}'
);
QString
res
=
str
;
if
(
pos0
!=
-
1
&&
pos1
!=
-
1
&&
pos2
!=
-
1
)
res
=
str
.
mid
(
pos0
+
2
,
pos1
-
1
-
pos0
)
+
" ... "
+
str
.
right
(
str
.
size
()
-
pos2
);
return
res
.
simplified
();
}
static
bool
isIntOrFloatType
(
const
QString
&
type
)
{
static
const
QStringList
types
=
QStringList
()
<<
"char"
<<
"int"
<<
"short"
<<
"float"
<<
"double"
<<
"long"
<<
"bool"
<<
"signed char"
<<
"unsigned"
<<
"unsigned char"
<<
"unsigned int"
<<
"unsigned long"
<<
"long long"
<<
"unsigned long long"
;
return
types
.
contains
(
type
);
}
static
QString
sizeofTypeExpression
(
const
QString
&
type
)
{
if
(
type
.
endsWith
(
'*'
))
return
"sizeof(void*)"
;
if
(
type
.
endsWith
(
'>'
))
return
"sizeof("
+
type
+
")"
;
return
"sizeof("
+
gdbQuoteTypes
(
type
)
+
")"
;
}
void
GdbEngine
::
setUseDumpers
(
bool
on
)
{
qDebug
()
<<
"SWITCHING ON/OFF DUMPER DEBUGGING:"
<<
on
;
...
...
@@ -4329,4 +4069,3 @@ IDebuggerEngine *createGdbEngine(DebuggerManager *parent)
{
return
new
GdbEngine
(
parent
);
}
src/plugins/debugger/watchutils.cpp
0 → 100644
View file @
ad5a0010
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/
#include "watchutils.h"
#include <QtCore/QDebug>
#include <QtCore/QTime>
#include <QtCore/QStringList>
namespace
Debugger
{
namespace
Internal
{
QString
dotEscape
(
QString
str
)
{
const
QChar
dot
=
QLatin1Char
(
','
);
str
.
replace
(
QLatin1Char
(
' '
),
dot
);
str
.
replace
(
QLatin1Char
(
'\\'
),
dot
);
str
.
replace
(
QLatin1Char
(
'/'
),
dot
);
return
str
;
}
QString
currentTime
()
{
return
QTime
::
currentTime
().
toString
(
QLatin1String
(
"hh:mm:ss.zzz"
));
}
bool
isSkippableFunction
(
const
QString
&
funcName
,
const
QString
&
fileName
)
{
if
(
fileName
.
endsWith
(
QLatin1String
(
"kernel/qobject.cpp"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"kernel/moc_qobject.cpp"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"kernel/qmetaobject.cpp"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
".moc"
)))
return
true
;
if
(
funcName
.
endsWith
(
"::qt_metacall"
))
return
true
;
return
false
;
}
bool
isLeavableFunction
(
const
QString
&
funcName
,
const
QString
&
fileName
)
{
if
(
funcName
.
endsWith
(
QLatin1String
(
"QObjectPrivate::setCurrentSender"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"kernel/qmetaobject.cpp"
))
&&
funcName
.
endsWith
(
QLatin1String
(
"QMetaObject::methodOffset"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"kernel/qobject.h"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"kernel/qobject.cpp"
))
&&
funcName
.
endsWith
(
QLatin1String
(
"QObjectConnectionListVector::at"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"kernel/qobject.cpp"
))
&&
funcName
.
endsWith
(
QLatin1String
(
"~QObject"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"thread/qmutex.cpp"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"thread/qthread.cpp"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"thread/qthread_unix.cpp"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"thread/qmutex.h"
)))
return
true
;
if
(
fileName
.
contains
(
QLatin1String
(
"thread/qbasicatomic"
)))
return
true
;
if
(
fileName
.
contains
(
QLatin1String
(
"thread/qorderedmutexlocker_p"
)))
return
true
;
if
(
fileName
.
contains
(
QLatin1String
(
"arch/qatomic"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"tools/qvector.h"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"tools/qlist.h"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"tools/qhash.h"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"tools/qmap.h"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"tools/qstring.h"
)))
return
true
;
if
(
fileName
.
endsWith
(
QLatin1String
(
"global/qglobal.h"
)))