Skip to content
GitLab
Menu
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
35bfbec7
Commit
35bfbec7
authored
May 18, 2010
by
hjk
Browse files
debugger: refactor thread related class
parent
53e9c4fa
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/plugins/debugger/breakwindow.cpp
View file @
35bfbec7
...
...
@@ -30,6 +30,7 @@
#include "breakwindow.h"
#include "breakhandler.h"
#include "threadshandler.h"
#include "debuggeractions.h"
#include "debuggermanager.h"
#include "stackhandler.h"
...
...
src/plugins/debugger/debugger.pro
View file @
35bfbec7
...
...
@@ -35,6 +35,7 @@ HEADERS += breakhandler.h \
procinterrupt
.
h
\
registerhandler
.
h
\
registerwindow
.
h
\
stackframe
.
h
\
stackhandler
.
h
\
stackwindow
.
h
\
snapshothandler
.
h
\
...
...
@@ -46,7 +47,8 @@ HEADERS += breakhandler.h \
watchwindow
.
h
\
name_demangler
.
h
\
debuggeruiswitcher
.
h
\
debuggermainwindow
.
h
debuggermainwindow
.
h
\
threadshandler
.
h
SOURCES
+=
breakhandler
.
cpp
\
breakwindow
.
cpp
\
breakwindow
.
h
\
...
...
@@ -77,7 +79,9 @@ SOURCES += breakhandler.cpp \
watchutils
.
cpp
\
name_demangler
.
cpp
\
debuggeruiswitcher
.
cpp
\
debuggermainwindow
.
cpp
debuggermainwindow
.
cpp
\
threadshandler
.
cpp
\
stackframe
.
cpp
FORMS
+=
attachexternaldialog
.
ui
\
attachcoredialog
.
ui
\
...
...
src/plugins/debugger/debuggermanager.cpp
View file @
35bfbec7
...
...
@@ -57,6 +57,7 @@
#include "snapshothandler.h"
#include "stackhandler.h"
#include "stackframe.h"
#include "threadshandler.h"
#include "watchhandler.h"
#include "debuggerdialogs.h"
...
...
src/plugins/debugger/gdb/gdbengine.cpp
View file @
35bfbec7
...
...
@@ -56,6 +56,7 @@
#include "registerhandler.h"
#include "snapshothandler.h"
#include "stackhandler.h"
#include "threadshandler.h"
#include "watchhandler.h"
#include "sourcefileswindow.h"
...
...
src/plugins/debugger/gdb/trkgdbadapter.cpp
View file @
35bfbec7
...
...
@@ -35,7 +35,7 @@
#include "bluetoothlistener_gui.h"
#include "registerhandler.h"
#include "
stack
handler.h"
#include "
threads
handler.h"
#include "debuggeractions.h"
#include "debuggerstringutils.h"
#include "watchutils.h"
...
...
src/plugins/debugger/stackframe.cpp
0 → 100644
View file @
35bfbec7
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#include "stackframe.h"
#include "stackhandler.h"
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QTextStream>
namespace
Debugger
{
namespace
Internal
{
////////////////////////////////////////////////////////////////////////
//
// StackFrame
//
////////////////////////////////////////////////////////////////////////
StackFrame
::
StackFrame
()
:
level
(
0
),
line
(
0
)
{}
void
StackFrame
::
clear
()
{
line
=
level
=
0
;
function
.
clear
();
file
.
clear
();
from
.
clear
();
to
.
clear
();
address
.
clear
();
}
bool
StackFrame
::
isUsable
()
const
{
return
!
file
.
isEmpty
()
&&
QFileInfo
(
file
).
isReadable
();
}
QString
StackFrame
::
toString
()
const
{
QString
res
;
QTextStream
str
(
&
res
);
str
<<
StackHandler
::
tr
(
"Address:"
)
<<
' '
<<
address
<<
' '
<<
StackHandler
::
tr
(
"Function:"
)
<<
' '
<<
function
<<
' '
<<
StackHandler
::
tr
(
"File:"
)
<<
' '
<<
file
<<
' '
<<
StackHandler
::
tr
(
"Line:"
)
<<
' '
<<
line
<<
' '
<<
StackHandler
::
tr
(
"From:"
)
<<
' '
<<
from
<<
' '
<<
StackHandler
::
tr
(
"To:"
)
<<
' '
<<
to
;
return
res
;
}
QString
StackFrame
::
toToolTip
()
const
{
QString
res
;
QTextStream
str
(
&
res
);
str
<<
"<html><body><table>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"Address:"
)
<<
"</td><td>"
<<
address
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"Function:"
)
<<
"</td><td>"
<<
function
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"File:"
)
<<
"</td><td>"
<<
QDir
::
toNativeSeparators
(
file
)
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"Line:"
)
<<
"</td><td>"
<<
line
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"From:"
)
<<
"</td><td>"
<<
from
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"To:"
)
<<
"</td><td>"
<<
to
<<
"</td></tr>"
<<
"</table></body></html>"
;
return
res
;
}
QDebug
operator
<<
(
QDebug
d
,
const
StackFrame
&
f
)
{
QString
res
;
QTextStream
str
(
&
res
);
str
<<
"level="
<<
f
.
level
<<
" address="
<<
f
.
address
;
if
(
!
f
.
function
.
isEmpty
())
str
<<
' '
<<
f
.
function
;
if
(
!
f
.
file
.
isEmpty
())
str
<<
' '
<<
f
.
file
<<
':'
<<
f
.
line
;
if
(
!
f
.
from
.
isEmpty
())
str
<<
" from="
<<
f
.
from
;
if
(
!
f
.
to
.
isEmpty
())
str
<<
" to="
<<
f
.
to
;
d
.
nospace
()
<<
res
;
return
d
;
}
}
// namespace Internal
}
// namespace Debugger
src/plugins/debugger/stackhandler.cpp
View file @
35bfbec7
...
...
@@ -42,69 +42,6 @@
namespace
Debugger
{
namespace
Internal
{
StackFrame
::
StackFrame
()
:
level
(
0
),
line
(
0
)
{}
void
StackFrame
::
clear
()
{
line
=
level
=
0
;
function
.
clear
();
file
.
clear
();
from
.
clear
();
to
.
clear
();
address
.
clear
();
}
bool
StackFrame
::
isUsable
()
const
{
return
!
file
.
isEmpty
()
&&
QFileInfo
(
file
).
isReadable
();
}
QString
StackFrame
::
toString
()
const
{
QString
res
;
QTextStream
str
(
&
res
);
str
<<
StackHandler
::
tr
(
"Address:"
)
<<
' '
<<
address
<<
' '
<<
StackHandler
::
tr
(
"Function:"
)
<<
' '
<<
function
<<
' '
<<
StackHandler
::
tr
(
"File:"
)
<<
' '
<<
file
<<
' '
<<
StackHandler
::
tr
(
"Line:"
)
<<
' '
<<
line
<<
' '
<<
StackHandler
::
tr
(
"From:"
)
<<
' '
<<
from
<<
' '
<<
StackHandler
::
tr
(
"To:"
)
<<
' '
<<
to
;
return
res
;
}
QString
StackFrame
::
toToolTip
()
const
{
QString
res
;
QTextStream
str
(
&
res
);
str
<<
"<html><body><table>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"Address:"
)
<<
"</td><td>"
<<
address
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"Function:"
)
<<
"</td><td>"
<<
function
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"File:"
)
<<
"</td><td>"
<<
QDir
::
toNativeSeparators
(
file
)
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"Line:"
)
<<
"</td><td>"
<<
line
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"From:"
)
<<
"</td><td>"
<<
from
<<
"</td></tr>"
<<
"<tr><td>"
<<
StackHandler
::
tr
(
"To:"
)
<<
"</td><td>"
<<
to
<<
"</td></tr>"
<<
"</table></body></html>"
;
return
res
;
}
QDebug
operator
<<
(
QDebug
d
,
const
StackFrame
&
f
)
{
QString
res
;
QTextStream
str
(
&
res
);
str
<<
"level="
<<
f
.
level
<<
" address="
<<
f
.
address
;
if
(
!
f
.
function
.
isEmpty
())
str
<<
' '
<<
f
.
function
;
if
(
!
f
.
file
.
isEmpty
())
str
<<
' '
<<
f
.
file
<<
':'
<<
f
.
line
;
if
(
!
f
.
from
.
isEmpty
())
str
<<
" from="
<<
f
.
from
;
if
(
!
f
.
to
.
isEmpty
())
str
<<
" to="
<<
f
.
to
;
d
.
nospace
()
<<
res
;
return
d
;
}
////////////////////////////////////////////////////////////////////////
//
...
...
@@ -262,161 +199,5 @@ bool StackHandler::isDebuggingDebuggingHelpers() const
}
////////////////////////////////////////////////////////////////////////
//
// ThreadsHandler
//
////////////////////////////////////////////////////////////////////////
ThreadData
::
ThreadData
(
int
threadId
)
{
notifyRunning
();
id
=
threadId
;
}
void
ThreadData
::
notifyRunning
()
{
address
=
0
;
function
.
clear
();
fileName
.
clear
();
frameLevel
=
-
1
;
state
.
clear
();
lineNumber
=
-
1
;
}
enum
{
IdColumn
,
AddressColumn
,
FunctionColumn
,
FileColumn
,
LineColumn
,
ColumnCount
};
ThreadsHandler
::
ThreadsHandler
(
QObject
*
parent
)
:
QAbstractTableModel
(
parent
),
m_currentIndex
(
0
),
m_positionIcon
(
QLatin1String
(
":/debugger/images/location_16.png"
)),
m_emptyIcon
(
QLatin1String
(
":/debugger/images/debugger_empty_14.png"
))
{
}
int
ThreadsHandler
::
rowCount
(
const
QModelIndex
&
parent
)
const
{
// Since the stack is not a tree, row count is 0 for any valid parent
return
parent
.
isValid
()
?
0
:
m_threads
.
size
();
}
int
ThreadsHandler
::
columnCount
(
const
QModelIndex
&
parent
)
const
{
return
parent
.
isValid
()
?
0
:
int
(
ColumnCount
);
}
QVariant
ThreadsHandler
::
data
(
const
QModelIndex
&
index
,
int
role
)
const
{
if
(
!
index
.
isValid
())
return
QVariant
();
const
int
row
=
index
.
row
();
if
(
row
>=
m_threads
.
size
())
return
QVariant
();
const
ThreadData
&
thread
=
m_threads
.
at
(
row
);
if
(
role
==
Qt
::
DisplayRole
)
{
switch
(
index
.
column
())
{
case
IdColumn
:
return
thread
.
id
;
case
FunctionColumn
:
return
thread
.
function
;
case
FileColumn
:
return
thread
.
fileName
;
case
LineColumn
:
return
thread
.
lineNumber
>=
0
?
QString
::
number
(
thread
.
lineNumber
)
:
QString
();
case
AddressColumn
:
return
thread
.
address
>
0
?
QLatin1String
(
"0x"
)
+
QString
::
number
(
thread
.
address
,
16
)
:
QString
();
}
}
else
if
(
role
==
Qt
::
ToolTipRole
)
{
if
(
thread
.
address
==
0
)
return
tr
(
"Thread: %1"
).
arg
(
thread
.
id
);
// Stopped
if
(
thread
.
fileName
.
isEmpty
())
return
tr
(
"Thread: %1 at %2 (0x%3)"
).
arg
(
thread
.
id
).
arg
(
thread
.
function
).
arg
(
thread
.
address
,
0
,
16
);
return
tr
(
"Thread: %1 at %2, %3:%4 (0x%5)"
).
arg
(
thread
.
id
).
arg
(
thread
.
function
,
thread
.
fileName
).
arg
(
thread
.
lineNumber
).
arg
(
thread
.
address
,
0
,
16
);
}
else
if
(
role
==
Qt
::
DecorationRole
&&
index
.
column
()
==
0
)
{
// Return icon that indicates whether this is the active stack frame
return
(
index
.
row
()
==
m_currentIndex
)
?
m_positionIcon
:
m_emptyIcon
;
}
return
QVariant
();
}
QVariant
ThreadsHandler
::
headerData
(
int
section
,
Qt
::
Orientation
orientation
,
int
role
)
const
{
if
(
orientation
!=
Qt
::
Horizontal
||
role
!=
Qt
::
DisplayRole
)
return
QVariant
();
switch
(
section
)
{
case
IdColumn
:
return
tr
(
"Thread ID"
);
case
FunctionColumn
:
return
tr
(
"Function"
);
case
FileColumn
:
return
tr
(
"File"
);
case
LineColumn
:
return
tr
(
"Line"
);
case
AddressColumn
:
return
tr
(
"Address"
);
}
return
QVariant
();
}
int
ThreadsHandler
::
currentThreadId
()
const
{
if
(
m_currentIndex
<
0
||
m_currentIndex
>=
m_threads
.
size
())
return
-
1
;
return
m_threads
[
m_currentIndex
].
id
;
}
void
ThreadsHandler
::
setCurrentThread
(
int
index
)
{
if
(
index
==
m_currentIndex
)
return
;
// Emit changed for previous frame
QModelIndex
i
=
ThreadsHandler
::
index
(
m_currentIndex
,
0
);
emit
dataChanged
(
i
,
i
);
m_currentIndex
=
index
;
// Emit changed for new frame
i
=
ThreadsHandler
::
index
(
m_currentIndex
,
0
);
emit
dataChanged
(
i
,
i
);
}
void
ThreadsHandler
::
setThreads
(
const
QList
<
ThreadData
>
&
threads
)
{
m_threads
=
threads
;
if
(
m_currentIndex
>=
m_threads
.
size
())
m_currentIndex
=
m_threads
.
size
()
-
1
;
reset
();
}
QList
<
ThreadData
>
ThreadsHandler
::
threads
()
const
{
return
m_threads
;
}
void
ThreadsHandler
::
removeAll
()
{
m_threads
.
clear
();
m_currentIndex
=
0
;
reset
();
}
void
ThreadsHandler
::
notifyRunning
()
{
// Threads stopped (that is, address != 0 showing)?
if
(
m_threads
.
empty
())
return
;
if
(
m_threads
.
front
().
address
==
0
)
return
;
const
QList
<
ThreadData
>::
iterator
end
=
m_threads
.
end
();
for
(
QList
<
ThreadData
>::
iterator
it
=
m_threads
.
begin
();
it
!=
end
;
++
it
)
it
->
notifyRunning
();
emit
dataChanged
(
index
(
0
,
1
),
index
(
m_threads
.
size
()
-
1
,
ColumnCount
-
1
));
}
}
// namespace Internal
}
// namespace Debugger
src/plugins/debugger/stackhandler.h
View file @
35bfbec7
...
...
@@ -40,6 +40,12 @@
namespace
Debugger
{
namespace
Internal
{
////////////////////////////////////////////////////////////////////////
//
// StackModel
//
////////////////////////////////////////////////////////////////////////
struct
StackCookie
{
StackCookie
()
:
isFull
(
true
),
gotoLocation
(
false
)
{}
...
...
@@ -92,64 +98,6 @@ private:
};
////////////////////////////////////////////////////////////////////////
//
// ThreadsHandler
//
////////////////////////////////////////////////////////////////////////
struct
ThreadData
{
ThreadData
(
int
threadId
=
0
);
// Permanent data.
int
id
;
QString
targetId
;
QString
core
;
// State information when stopped
void
notifyRunning
();
// Clear state information
int
frameLevel
;
quint64
address
;
QString
function
;
QString
fileName
;
QString
state
;
int
lineNumber
;
};
/*! A model to represent the running threads in a QTreeView or ComboBox */
class
ThreadsHandler
:
public
QAbstractTableModel
{
Q_OBJECT
public:
ThreadsHandler
(
QObject
*
parent
=
0
);
int
currentThreadId
()
const
;
void
setCurrentThread
(
int
index
);
void
selectThread
(
int
index
);
void
setThreads
(
const
QList
<
ThreadData
>
&
threads
);
void
removeAll
();
QList
<
ThreadData
>
threads
()
const
;
QAbstractItemModel
*
threadsModel
()
{
return
this
;
}
// Clear out all frame information
void
notifyRunning
();
private:
int
rowCount
(
const
QModelIndex
&
parent
=
QModelIndex
())
const
;
int
columnCount
(
const
QModelIndex
&
parent
=
QModelIndex
())
const
;
QVariant
data
(
const
QModelIndex
&
index
,
int
role
=
Qt
::
DisplayRole
)
const
;
QVariant
headerData
(
int
section
,
Qt
::
Orientation
orientation
,
int
role
=
Qt
::
DisplayRole
)
const
;
private:
QList
<
ThreadData
>
m_threads
;
int
m_currentIndex
;
const
QIcon
m_positionIcon
;
const
QIcon
m_emptyIcon
;
};
}
// namespace Internal
}
// namespace Debugger
...
...
src/plugins/debugger/threadshandler.cpp
0 → 100644
View file @
35bfbec7
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#include "threadshandler.h"
namespace
Debugger
{
namespace
Internal
{
////////////////////////////////////////////////////////////////////////
//
// ThreadsHandler
//
///////////////////////////////////////////////////////////////////////
ThreadData
::
ThreadData
(
int
threadId
)
{
notifyRunning
();
id
=
threadId
;
}
void
ThreadData
::
notifyRunning
()
{
address
=
0
;
function
.
clear
();
fileName
.
clear
();
frameLevel
=
-
1
;
state
.
clear
();
lineNumber
=
-
1
;
}
////////////////////////////////////////////////////////////////////////
//
// ThreadsHandler
//
///////////////////////////////////////////////////////////////////////
ThreadsHandler
::
ThreadsHandler
(
QObject
*
parent
)
:
QAbstractTableModel
(
parent
),
m_currentIndex
(
0
),
m_positionIcon
(
QLatin1String
(
":/debugger/images/location_16.png"
)),
m_emptyIcon
(
QLatin1String
(
":/debugger/images/debugger_empty_14.png"
))
{
}
int
ThreadsHandler
::
rowCount
(
const
QModelIndex
&
parent
)
const
{
// Since the stack is not a tree, row count is 0 for any valid parent
return
parent
.
isValid
()
?
0
:
m_threads
.
size
();
}
int
ThreadsHandler
::
columnCount
(
const
QModelIndex
&
parent
)
const
{
return
parent
.
isValid
()
?
0
:
int
(
ThreadData
::
ColumnCount
);
}
QVariant
ThreadsHandler
::
data
(
const
QModelIndex
&
index
,
int
role
)
const
{
if
(
!
index
.
isValid
())
return
QVariant
();
const
int
row
=
index
.
row
();
if
(
row
>=
m_threads
.
size
())
return
QVariant
();
const
ThreadData
&
thread
=
m_threads
.
at
(
row
);
if
(
role
==
Qt
::
DisplayRole
)
{
switch
(
index
.
column
())
{
case
ThreadData
::
IdColumn
:
return
thread
.
id
;
case
ThreadData
::
FunctionColumn
:
return
thread
.
function
;
case
ThreadData
::
FileColumn
:
return
thread
.
fileName
;
case
ThreadData
::
LineColumn
:
return
thread
.
lineNumber
>=
0
?
QString
::
number
(
thread
.
lineNumber
)
:
QString
();
case
ThreadData
::
AddressColumn
:
return
thread
.
address
>
0
?
QLatin1String
(
"0x"
)
+
QString
::
number
(
thread
.
address
,
16
)
:
QString
();
case
ThreadData
::
CoreColumn
:
return
thread
.
core
;
case
ThreadData
::
StateColumn
:
return
thread
.
state
;
}
}
else
if
(
role
==
Qt
::
ToolTipRole
)
{
if
(
thread
.
address
==
0
)
return
tr
(
"Thread: %1"
).
arg
(
thread
.
id
);
// Stopped
if
(
thread
.
fileName
.
isEmpty
())
return
tr
(
"Thread: %1 at %2 (0x%3)"
).
arg
(
thread
.
id
).
arg
(
thread
.
function
).
arg
(
thread
.
address
,
0
,
16
);
return
tr
(
"Thread: %1 at %2, %3:%4 (0x%5)"
).
arg
(
thread
.
id
).
arg
(
thread
.
function
,
thread
.
fileName
).
arg
(
thread
.
lineNumber
).
arg
(
thread
.
address
,
0
,
16
);
}
else
if
(
role
==
Qt
::
DecorationRole
&&
index