mirror of
https://github.com/epasveer/seer.git
synced 2026-08-29 16:40:42 +08:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a24d6ae99 | |||
| fb27702881 | |||
| 60ef4db52d | |||
| be3593d9e4 | |||
| 7222a04130 | |||
| d5aa8f9089 | |||
| 1735dc7f8a | |||
| b8c9572e23 | |||
| 697bba1d4c | |||
| a4290ffa8f |
@@ -1,6 +1,11 @@
|
||||
|
||||
# Seer Change Log
|
||||
|
||||
## [1.17] - 2023-04-23
|
||||
* Add support for the RR debugger.
|
||||
https://github.com/epasveer/seer/wiki/RR-and-Seer
|
||||
* Add a dialog when a breakpoint is reached.
|
||||
|
||||
## [1.16] - 2023-04-07
|
||||
* Add pid to main window and console title bars.
|
||||
* The Pending flag is automatically supplied to the breakpoint function in
|
||||
|
||||
Vendored
+2
-2
@@ -1,6 +1,6 @@
|
||||
seergdb (1.16) UNRELEASED; urgency=medium
|
||||
seergdb (1.17) UNRELEASED; urgency=medium
|
||||
|
||||
* Updated release.
|
||||
|
||||
-- Ernie Pasveer <epasveer@att.net> Fri, 07 Apr 2023 22:18:38 +0200
|
||||
-- Ernie Pasveer <epasveer@att.net> Sun, 23 Apr 2023 22:18:38 +0200
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
-info-ada-exceptions
|
||||
|
||||
^done,ada-exceptions={
|
||||
nr_rows="16",
|
||||
nr_cols="2",
|
||||
hdr=[
|
||||
{
|
||||
width="1",alignment="-1",col_name="name",colhdr="Name"
|
||||
},
|
||||
{
|
||||
width="1",alignment="-1",col_name="address",colhdr="Address"
|
||||
}
|
||||
],
|
||||
body=[
|
||||
{
|
||||
name="constraint_error",address="0x000000000042c9a0"
|
||||
},
|
||||
{
|
||||
name="program_error",address="0x000000000042c920"
|
||||
},
|
||||
{
|
||||
name="storage_error",address="0x000000000042c8e0"
|
||||
},
|
||||
{
|
||||
name="tasking_error",address="0x000000000042c8a0"
|
||||
},
|
||||
{
|
||||
name="<_abort_signal>",address="0x000000000042c860"
|
||||
},
|
||||
{
|
||||
name="ada.io_exceptions.data_error",address="0x000000000042c3e0"
|
||||
},
|
||||
{
|
||||
name="ada.io_exceptions.device_error",address="0x000000000042c460"
|
||||
},
|
||||
{
|
||||
name="ada.io_exceptions.end_error",address="0x000000000042c420"
|
||||
},
|
||||
{
|
||||
name="ada.io_exceptions.layout_error",address="0x000000000042c3a0"
|
||||
},
|
||||
{
|
||||
name="ada.io_exceptions.mode_error",address="0x000000000042c520"
|
||||
},
|
||||
{
|
||||
name="ada.io_exceptions.name_error",address="0x000000000042c4e0"
|
||||
},
|
||||
{
|
||||
name="ada.io_exceptions.status_error",address="0x000000000042c560"
|
||||
},
|
||||
{
|
||||
name="ada.io_exceptions.use_error",address="0x000000000042c4a0"
|
||||
},
|
||||
{
|
||||
name="ada.tags.tag_error",address="0x000000000042c5c0"
|
||||
},
|
||||
{
|
||||
name="interfaces.c.terminator_error",address="0x000000000042c660"
|
||||
},
|
||||
{
|
||||
name="system.exceptions.foreign_exception",address="0x000000000042c6a0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -21,3 +21,24 @@ Notes:
|
||||
o Execuable name is useless.
|
||||
o Symbol name is optional.
|
||||
|
||||
Notes (2);
|
||||
|
||||
This will automatically stop in _start. Setting a breakpoint in 'main' from the gdb entry field
|
||||
will not refresh the breakpoint list. However, this message is sent. So maybe it can be refreshed.
|
||||
|
||||
=breakpoint-created,bkpt={
|
||||
number="1",
|
||||
type="breakpoint",
|
||||
disp="keep",
|
||||
enabled="y",
|
||||
addr="0x0000000000400c12",
|
||||
func="main(int, char**)",
|
||||
file="hellosegv.cpp",
|
||||
fullname="/nas/erniep/Development/seer/tests/hellosegv/hellosegv.cpp",
|
||||
line="7",
|
||||
thread-groups=["i1"],
|
||||
times="0",
|
||||
original-location="main"
|
||||
}
|
||||
^done
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
Notes for using RR with Seer.
|
||||
|
||||
Record a RR session.
|
||||
|
||||
https://github.com/rr-debugger/rr/wiki/Usage
|
||||
|
||||
$ rr record -n hellosegv one two three
|
||||
|
||||
Replay the RR session in gdb.
|
||||
|
||||
$ rr replay
|
||||
|
||||
Using RR in a gui debugger. Basically, attach to the rr server port.
|
||||
|
||||
https://github.com/rr-debugger/rr/wiki/Using-rr-in-an-IDE
|
||||
|
||||
$ rr replay -s 50505 -k
|
||||
|
||||
$ rr replay -s 50505 -k
|
||||
Launch gdb with
|
||||
gdb '-l' '10000' '-ex' 'set sysroot /' '-ex' 'target extended-remote 127.0.0.1:50505' /nas/erniep/Development/seer/tests/hellosegv/hellosegv
|
||||
|
||||
|
||||
Then use "Connect" method in Debug dialog and connect to "127.0.0.1:50505".
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.1.0)
|
||||
|
||||
project(seergdb VERSION 1.16 LANGUAGES CXX)
|
||||
project(seergdb VERSION 1.17 LANGUAGES CXX)
|
||||
|
||||
set(PROJECT_NAME seergdb)
|
||||
|
||||
|
||||
+56
-2
@@ -34,6 +34,7 @@ SeerDebugDialog::SeerDebugDialog (QWidget* parent) : QDialog(parent) {
|
||||
setNonStopMode(false);
|
||||
setAttachPid(0);
|
||||
setConnectHostPort("");
|
||||
setRRHostPort("");
|
||||
setCoreFilename("");
|
||||
setProjectFilename("");
|
||||
|
||||
@@ -72,6 +73,7 @@ SeerDebugDialog::SeerDebugDialog (QWidget* parent) : QDialog(parent) {
|
||||
QObject::connect(helpRunToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleHelpRunToolButtonClicked);
|
||||
QObject::connect(helpAttachToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleHelpAttachToolButtonClicked);
|
||||
QObject::connect(helpConnectToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleHelpConnectToolButtonClicked);
|
||||
QObject::connect(helpRRToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleHelpRRToolButtonClicked);
|
||||
QObject::connect(helpCorefileToolButton, &QToolButton::clicked, this, &SeerDebugDialog::handleHelpCorefileToolButtonClicked);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||
@@ -251,6 +253,14 @@ QString SeerDebugDialog::connectHostPort () const {
|
||||
return connectProgramHostPortLineEdit->text();
|
||||
}
|
||||
|
||||
void SeerDebugDialog::setRRHostPort (const QString& rrHostPort) {
|
||||
rrHostPortLineEdit->setText(rrHostPort);
|
||||
}
|
||||
|
||||
QString SeerDebugDialog::rrHostPort () const {
|
||||
return rrHostPortLineEdit->text();
|
||||
}
|
||||
|
||||
void SeerDebugDialog::setLaunchMode (const QString& mode) {
|
||||
|
||||
if (mode == "start") {
|
||||
@@ -273,10 +283,14 @@ void SeerDebugDialog::setLaunchMode (const QString& mode) {
|
||||
|
||||
runModeTabWidget->setCurrentIndex(2);
|
||||
|
||||
}else if (mode == "corefile") {
|
||||
}else if (mode == "rr") {
|
||||
|
||||
runModeTabWidget->setCurrentIndex(3);
|
||||
|
||||
}else if (mode == "corefile") {
|
||||
|
||||
runModeTabWidget->setCurrentIndex(4);
|
||||
|
||||
}else if (mode == "") {
|
||||
|
||||
runModeTabWidget->setCurrentIndex(0);
|
||||
@@ -313,6 +327,10 @@ QString SeerDebugDialog::launchMode () const {
|
||||
|
||||
}else if (runModeTabWidget->currentIndex() == 3) {
|
||||
|
||||
return "rr";
|
||||
|
||||
}else if (runModeTabWidget->currentIndex() == 4) {
|
||||
|
||||
return "corefile";
|
||||
}
|
||||
|
||||
@@ -438,6 +456,7 @@ void SeerDebugDialog::loadProject (const QString& filename, bool notify) {
|
||||
QJsonObject startModeJson;
|
||||
QJsonObject attachModeJson;
|
||||
QJsonObject connectModeJson;
|
||||
QJsonObject rrModeJson;
|
||||
QJsonObject corefileModeJson;
|
||||
QJsonArray preConnectCommands;
|
||||
QJsonArray postConnectCommands;
|
||||
@@ -453,6 +472,7 @@ void SeerDebugDialog::loadProject (const QString& filename, bool notify) {
|
||||
startModeJson = seerProjectJson.value("startmode").toObject();
|
||||
attachModeJson = seerProjectJson.value("attachmode").toObject();
|
||||
connectModeJson = seerProjectJson.value("connectmode").toObject();
|
||||
rrModeJson = seerProjectJson.value("rrmode").toObject();
|
||||
corefileModeJson = seerProjectJson.value("corefilemode").toObject();
|
||||
preConnectCommands = seerProjectJson.value("pregdbcommands").toArray();
|
||||
postConnectCommands = seerProjectJson.value("postgdbcommands").toArray();
|
||||
@@ -554,6 +574,14 @@ void SeerDebugDialog::loadProject (const QString& filename, bool notify) {
|
||||
setLaunchMode("connect");
|
||||
}
|
||||
|
||||
// Load RR project.
|
||||
if (rrModeJson.isEmpty() == false) {
|
||||
|
||||
connectProgramHostPortLineEdit->setText(rrModeJson["rrserver"].toString());
|
||||
|
||||
setLaunchMode("rr");
|
||||
}
|
||||
|
||||
// Load COREFILE project.
|
||||
if (corefileModeJson.isEmpty() == false) {
|
||||
|
||||
@@ -657,6 +685,16 @@ void SeerDebugDialog::handleSaveProjectToolButton () {
|
||||
seerProjectJson["connectmode"] = modeJson;
|
||||
}
|
||||
|
||||
// Save RR project.
|
||||
if (launchMode() == "rr") {
|
||||
|
||||
QJsonObject modeJson;
|
||||
|
||||
modeJson["rrserver"] = rrHostPortLineEdit->text();
|
||||
|
||||
seerProjectJson["rrmode"] = modeJson;
|
||||
}
|
||||
|
||||
// Save COREFILE project.
|
||||
if (launchMode() == "corefile") {
|
||||
|
||||
@@ -734,8 +772,16 @@ void SeerDebugDialog::handleRunModeChanged (int id) {
|
||||
postCommandsPlainTextEdit->setPlaceholderText("gdb commands after \"connect\"");
|
||||
}
|
||||
|
||||
// ID == 3 COREFILE
|
||||
// ID == 3 RR
|
||||
if (id == 3) {
|
||||
executableSymbolNameLineEdit->setEnabled(true);
|
||||
executableSymbolNameToolButton->setEnabled(true);
|
||||
preCommandsPlainTextEdit->setPlaceholderText("gdb commands before \"RR connect\"");
|
||||
postCommandsPlainTextEdit->setPlaceholderText("gdb commands after \"RR connect\"");
|
||||
}
|
||||
|
||||
// ID == 4 COREFILE
|
||||
if (id == 4) {
|
||||
executableNameLineEdit->setEnabled(true);
|
||||
executableNameToolButton->setEnabled(true);
|
||||
executableSymbolNameLineEdit->setEnabled(true);
|
||||
@@ -777,6 +823,14 @@ void SeerDebugDialog::handleHelpConnectToolButtonClicked () {
|
||||
help->raise();
|
||||
}
|
||||
|
||||
void SeerDebugDialog::handleHelpRRToolButtonClicked () {
|
||||
|
||||
SeerHelpPageDialog* help = new SeerHelpPageDialog(this);
|
||||
help->loadFile(":/seer/resources/help/RRDebugMode.md");
|
||||
help->show();
|
||||
help->raise();
|
||||
}
|
||||
|
||||
void SeerDebugDialog::handleHelpCorefileToolButtonClicked () {
|
||||
|
||||
SeerHelpPageDialog* help = new SeerHelpPageDialog(this);
|
||||
|
||||
@@ -53,6 +53,10 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm {
|
||||
void setConnectHostPort (const QString& connectHostPort);
|
||||
QString connectHostPort () const;
|
||||
|
||||
// Connectect to a RR server. "rr".
|
||||
void setRRHostPort (const QString& rrHostPort);
|
||||
QString rrHostPort () const;
|
||||
|
||||
// Load a core file. "corefile".
|
||||
void setCoreFilename (const QString& coreFilename);
|
||||
QString coreFilename () const;
|
||||
@@ -83,6 +87,7 @@ class SeerDebugDialog : public QDialog, protected Ui::SeerDebugDialogForm {
|
||||
void handleHelpRunToolButtonClicked ();
|
||||
void handleHelpAttachToolButtonClicked ();
|
||||
void handleHelpConnectToolButtonClicked ();
|
||||
void handleHelpRRToolButtonClicked ();
|
||||
void handleHelpCorefileToolButtonClicked ();
|
||||
|
||||
protected:
|
||||
|
||||
+162
-67
@@ -6,15 +6,61 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>588</width>
|
||||
<height>801</height>
|
||||
<width>806</width>
|
||||
<height>1040</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Select Executable to Debug</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="executableWorkingDirectoryGroupBox">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Working Directory</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="executableWorkingDirectoryLineEdit">
|
||||
<property name="toolTip">
|
||||
<string>The working directory path to tell GDB. Default current directory.</string>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>The working directory path to tell GDB. Default current directory.</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="executableWorkingDirectoryToolButton">
|
||||
<property name="toolTip">
|
||||
<string>Open a dialog to select a path.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resource.qrc">
|
||||
<normaloff>:/seer/resources/RelaxLightIcons/document-open.svg</normaloff>:/seer/resources/RelaxLightIcons/document-open.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="executableNameGroupBox">
|
||||
<property name="title">
|
||||
<string>Executable Name</string>
|
||||
@@ -72,7 +118,17 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="executableSymbolNameGroupBox">
|
||||
<property name="title">
|
||||
<string>Symbol File Name</string>
|
||||
@@ -130,53 +186,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="executableWorkingDirectoryGroupBox">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Working Directory</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="executableWorkingDirectoryLineEdit">
|
||||
<property name="toolTip">
|
||||
<string>The working directory path to tell GDB. Default current directory.</string>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>The working directory path to tell GDB. Default current directory.</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="executableWorkingDirectoryToolButton">
|
||||
<property name="toolTip">
|
||||
<string>Open a dialog to select a path.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resource.qrc">
|
||||
<normaloff>:/seer/resources/RelaxLightIcons/document-open.svg</normaloff>:/seer/resources/RelaxLightIcons/document-open.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="launchMethodGroupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
@@ -197,7 +207,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="runTab">
|
||||
<property name="sizePolicy">
|
||||
@@ -578,7 +588,20 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="connectProgramHostPortLabel">
|
||||
@@ -596,7 +619,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>How to access the remote gdbserver.</string>
|
||||
<string>How to access the gdbserver.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -611,8 +634,90 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="rrTab">
|
||||
<attribute name="title">
|
||||
<string>RR</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Connect to a RR replay session.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>248</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="helpRRToolButton">
|
||||
<property name="toolTip">
|
||||
<string>Help for RR launch method.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resource.qrc">
|
||||
<normaloff>:/seer/resources/RelaxLightIcons/help-about.svg</normaloff>:/seer/resources/RelaxLightIcons/help-about.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<widget class="QLabel" name="rrHostPortLabel">
|
||||
<property name="text">
|
||||
<string>RR replay session</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="rrHostPortLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>100</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>How to access the RR session.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>host:port</string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@@ -758,16 +863,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>executableNameGroupBox</zorder>
|
||||
<zorder>buttonBox</zorder>
|
||||
|
||||
+109
-22
@@ -36,7 +36,8 @@ SeerGdbWidget::SeerGdbWidget (QWidget* parent) : QWidget(parent) {
|
||||
_executableWorkingDirectory = "";
|
||||
_executableBreakpointsFilename = "";
|
||||
_executableBreakpointFunctionName = "";
|
||||
_executableHostPort = "";
|
||||
_executableConnectHostPort = "";
|
||||
_executableRRHostPort = "";
|
||||
_executableCoreFilename = "";
|
||||
_executablePid = 0;
|
||||
|
||||
@@ -57,7 +58,7 @@ SeerGdbWidget::SeerGdbWidget (QWidget* parent) : QWidget(parent) {
|
||||
_gdbHandleTerminatingException = true;
|
||||
_gdbRandomizeStartAddress = false;
|
||||
_gdbEnablePrettyPrinting = true;
|
||||
_gdbRecordMode = "stop";
|
||||
_gdbRecordMode = "";
|
||||
_gdbRecordDirection = "";
|
||||
_consoleMode = "";
|
||||
_consoleScrollLines = 1000;
|
||||
@@ -424,12 +425,20 @@ int SeerGdbWidget::executablePid () const {
|
||||
return _executablePid;
|
||||
}
|
||||
|
||||
void SeerGdbWidget::setExecutableHostPort (const QString& hostPort) {
|
||||
_executableHostPort = hostPort;
|
||||
void SeerGdbWidget::setExecutableConnectHostPort (const QString& connectHostPort) {
|
||||
_executableConnectHostPort = connectHostPort;
|
||||
}
|
||||
|
||||
const QString& SeerGdbWidget::executableHostPort () const {
|
||||
return _executableHostPort;
|
||||
const QString& SeerGdbWidget::executableConnectHostPort () const {
|
||||
return _executableConnectHostPort;
|
||||
}
|
||||
|
||||
void SeerGdbWidget::setExecutableRRHostPort (const QString& rrHostPort) {
|
||||
_executableRRHostPort = rrHostPort;
|
||||
}
|
||||
|
||||
const QString& SeerGdbWidget::executableRRHostPort () const {
|
||||
return _executableRRHostPort;
|
||||
}
|
||||
|
||||
void SeerGdbWidget::setExecutableCoreFilename (const QString& coreFilename) {
|
||||
@@ -542,7 +551,9 @@ void SeerGdbWidget::setGdbRecordMode(const QString& mode) {
|
||||
|
||||
_gdbRecordMode = mode;
|
||||
|
||||
handleGdbCommand("record " + gdbRecordMode());
|
||||
if (mode != "rr" && mode != "") {
|
||||
handleGdbCommand("record " + gdbRecordMode());
|
||||
}
|
||||
|
||||
emit recordSettingsChanged();
|
||||
}
|
||||
@@ -853,6 +864,7 @@ void SeerGdbWidget::handleGdbRunExecutable (const QString& breakMode) {
|
||||
connectConsole();
|
||||
|
||||
setExecutableLaunchMode("run");
|
||||
setGdbRecordMode("");
|
||||
setExecutablePid(0);
|
||||
|
||||
// Load ithe executable, if needed.
|
||||
@@ -969,6 +981,7 @@ void SeerGdbWidget::handleGdbAttachExecutable () {
|
||||
|
||||
// No console for 'attach' mode.
|
||||
setExecutableLaunchMode("attach");
|
||||
setGdbRecordMode("");
|
||||
|
||||
// Load ithe executable, if needed.
|
||||
if (newExecutableFlag() == true) {
|
||||
@@ -1024,20 +1037,12 @@ void SeerGdbWidget::handleGdbConnectExecutable () {
|
||||
deleteConsole();
|
||||
}
|
||||
|
||||
//qDebug() << "Starting GdbConnect.";
|
||||
|
||||
// If gdb isn't running, start it.
|
||||
if (isGdbRuning() == false) {
|
||||
|
||||
emit changeWindowTitle(QString("%1 (pid=%2)").arg(executableHostPort()).arg(QGuiApplication::applicationPid()));
|
||||
emit changeWindowTitle(QString("%1 (pid=%2)").arg(executableConnectHostPort()).arg(QGuiApplication::applicationPid()));
|
||||
|
||||
startGdb();
|
||||
|
||||
/* Do not use for 'connect' mode. Possible too quick for a gdbserver/vdbg.
|
||||
if (gdbAsyncMode()) {
|
||||
handleGdbCommand("-gdb-set mi-async on"); // Turn on async mode so the 'interrupt' can happen.
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Set dprint parameters.
|
||||
@@ -1045,10 +1050,11 @@ void SeerGdbWidget::handleGdbConnectExecutable () {
|
||||
|
||||
// No console for 'connect' mode.
|
||||
setExecutableLaunchMode("connect");
|
||||
setGdbRecordMode("");
|
||||
setExecutablePid(0);
|
||||
|
||||
// Connect to the remote gdbserver.
|
||||
handleGdbCommand(QString("-target-select extended-remote %1").arg(executableHostPort()));
|
||||
handleGdbCommand(QString("-target-select extended-remote %1").arg(executableConnectHostPort()));
|
||||
|
||||
// Load ithe executable, if needed.
|
||||
if (newExecutableFlag() == true) {
|
||||
@@ -1079,12 +1085,76 @@ void SeerGdbWidget::handleGdbConnectExecutable () {
|
||||
handleGdbExecutablePostCommands();
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
//qDebug() << "Finishing GdbConnect.";
|
||||
void SeerGdbWidget::handleGdbRRExecutable () {
|
||||
|
||||
// "-file-symbol-file %s"
|
||||
// "-file-exec-file %s"
|
||||
// "-target-download"
|
||||
// Has a executable name been provided?
|
||||
if (executableName() != "") {
|
||||
|
||||
QMessageBox::warning(this, "Seer",
|
||||
QString("The executable name can't be provided for 'rr' mode."),
|
||||
QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
QApplication::setOverrideCursor(Qt::BusyCursor);
|
||||
|
||||
// Delete the old gdb and console if there is a new executable
|
||||
if (newExecutableFlag() == true) {
|
||||
killGdb();
|
||||
disconnectConsole();
|
||||
deleteConsole();
|
||||
}
|
||||
|
||||
// If gdb isn't running, start it.
|
||||
if (isGdbRuning() == false) {
|
||||
|
||||
emit changeWindowTitle(QString("%1 (pid=%2)").arg(executableRRHostPort()).arg(QGuiApplication::applicationPid()));
|
||||
|
||||
startGdb();
|
||||
}
|
||||
|
||||
// Set dprint parameters.
|
||||
resetDprintf();
|
||||
|
||||
// No console for 'connect' mode.
|
||||
setExecutableLaunchMode("rr");
|
||||
setGdbRecordMode("rr");
|
||||
setExecutablePid(0);
|
||||
|
||||
// Connect to the remote gdbserver.
|
||||
handleGdbCommand(QString("-target-select extended-remote %1").arg(executableRRHostPort()));
|
||||
|
||||
// Load ithe executable, if needed.
|
||||
if (newExecutableFlag() == true) {
|
||||
handleGdbExecutablePreCommands(); // Run any 'pre' commands before program is loaded.
|
||||
handleGdbExecutableName(); // Load the program into the gdb process.
|
||||
handleGdbExecutableSources(); // Load the program source files.
|
||||
handleGdbExecutableLoadBreakpoints(); // Set the program's breakpoints (if any) before running.
|
||||
|
||||
setNewExecutableFlag(false);
|
||||
}
|
||||
|
||||
// Set or reset some things.
|
||||
handleGdbExecutableWorkingDirectory(); // Set the program's working directory before running.
|
||||
handleGdbAssemblyDisassemblyFlavor(); // Set the disassembly flavor to use.
|
||||
handleGdbAssemblySymbolDemangling(); // Set the symbol demangling.
|
||||
|
||||
if (assemblyShowAssemblyTabOnStartup()) {
|
||||
editorManager()->showAssembly();
|
||||
}
|
||||
|
||||
if (gdbHandleTerminatingException()) {
|
||||
handleGdbCommand("-gdb-set unwind-on-terminating-exception on"); // Turn on terminating exceptions when gdb calls the program's functions.
|
||||
}else{
|
||||
handleGdbCommand("-gdb-set unwind-on-terminating-exception off");
|
||||
}
|
||||
|
||||
// Run any 'post' commands after program is loaded.
|
||||
handleGdbExecutablePostCommands();
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void SeerGdbWidget::handleGdbCoreFileExecutable () {
|
||||
@@ -1136,6 +1206,7 @@ void SeerGdbWidget::handleGdbCoreFileExecutable () {
|
||||
|
||||
// No console for 'core' mode.
|
||||
setExecutableLaunchMode("corefile");
|
||||
setGdbRecordMode("");
|
||||
setExecutablePid(0);
|
||||
|
||||
if (newExecutableFlag() == true) {
|
||||
@@ -1172,6 +1243,7 @@ void SeerGdbWidget::handleGdbShutdown () {
|
||||
|
||||
// We are in no mode now.
|
||||
setExecutableLaunchMode("");
|
||||
setGdbRecordMode("");
|
||||
|
||||
// Give the gdb and 'exit' command.
|
||||
// This should handle detaching from an attached pid.
|
||||
@@ -1263,6 +1335,11 @@ void SeerGdbWidget::handleGdbRecordStart () {
|
||||
return;
|
||||
}
|
||||
|
||||
if (executableLaunchMode() == "rr") {
|
||||
QMessageBox::warning(this, "Seer", QString("Record 'Start' not available in RR mode."), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
setGdbRecordMode("full");
|
||||
setGdbRecordDirection("");
|
||||
}
|
||||
@@ -1273,6 +1350,11 @@ void SeerGdbWidget::handleGdbRecordStop () {
|
||||
return;
|
||||
}
|
||||
|
||||
if (executableLaunchMode() == "rr") {
|
||||
QMessageBox::warning(this, "Seer", QString("Record 'Stop' not available in RR mode."), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
setGdbRecordMode("stop");
|
||||
setGdbRecordDirection("");
|
||||
}
|
||||
@@ -1289,7 +1371,7 @@ void SeerGdbWidget::handleGdbRecordReverse () {
|
||||
|
||||
void SeerGdbWidget::handleGdbRecordStartStopToggle () {
|
||||
|
||||
if (gdbRecordMode() == "stop") {
|
||||
if (gdbRecordMode() == "stop" || gdbRecordMode() == "") {
|
||||
|
||||
setGdbRecordMode("full");
|
||||
setGdbRecordDirection("");
|
||||
@@ -1299,6 +1381,10 @@ void SeerGdbWidget::handleGdbRecordStartStopToggle () {
|
||||
setGdbRecordMode("stop");
|
||||
setGdbRecordDirection("");
|
||||
|
||||
}else if (gdbRecordMode() == "rr") {
|
||||
|
||||
// Don't do anthing.
|
||||
|
||||
}else{
|
||||
|
||||
setGdbRecordMode("stop");
|
||||
@@ -2766,6 +2852,7 @@ void SeerGdbWidget::killGdb () {
|
||||
|
||||
// Clear the launch mode.
|
||||
setExecutableLaunchMode("");
|
||||
setGdbRecordMode("");
|
||||
|
||||
// Kill the process.
|
||||
_gdbProcess->kill();
|
||||
|
||||
+8
-3
@@ -50,8 +50,11 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm {
|
||||
void setExecutablePid (int pid);
|
||||
int executablePid () const;
|
||||
|
||||
void setExecutableHostPort (const QString& hostPort);
|
||||
const QString& executableHostPort () const;
|
||||
void setExecutableConnectHostPort (const QString& connectHostPort);
|
||||
const QString& executableConnectHostPort () const;
|
||||
|
||||
void setExecutableRRHostPort (const QString& rrHostPort);
|
||||
const QString& executableRRHostPort () const;
|
||||
|
||||
void setExecutableCoreFilename (const QString& coreFilename);
|
||||
const QString& executableCoreFilename () const;
|
||||
@@ -190,6 +193,7 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm {
|
||||
void handleGdbRunExecutable (const QString& breakMode);
|
||||
void handleGdbAttachExecutable ();
|
||||
void handleGdbConnectExecutable ();
|
||||
void handleGdbRRExecutable ();
|
||||
void handleGdbCoreFileExecutable ();
|
||||
void handleGdbShutdown ();
|
||||
void handleGdbRunToLine (QString fullname, int lineno);
|
||||
@@ -356,7 +360,8 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm {
|
||||
QString _executableBreakpointsFilename;
|
||||
QString _executableBreakpointFunctionName;
|
||||
int _executablePid;
|
||||
QString _executableHostPort;
|
||||
QString _executableConnectHostPort;
|
||||
QString _executableRRHostPort;
|
||||
QString _executableCoreFilename;
|
||||
QString _executableLaunchMode;
|
||||
QString _executableBreakMode;
|
||||
|
||||
+76
-7
@@ -315,12 +315,20 @@ int SeerMainWindow::executablePid () const {
|
||||
return gdbWidget->executablePid();
|
||||
}
|
||||
|
||||
void SeerMainWindow::setExecutableHostPort (const QString& executableHostPort) {
|
||||
gdbWidget->setExecutableHostPort(executableHostPort);
|
||||
void SeerMainWindow::setExecutableConnectHostPort (const QString& executableConnectHostPort) {
|
||||
gdbWidget->setExecutableConnectHostPort(executableConnectHostPort);
|
||||
}
|
||||
|
||||
const QString& SeerMainWindow::executableHostPort () const {
|
||||
return gdbWidget->executableHostPort();
|
||||
const QString& SeerMainWindow::executableConnectHostPort () const {
|
||||
return gdbWidget->executableConnectHostPort();
|
||||
}
|
||||
|
||||
void SeerMainWindow::setExecutableRRHostPort (const QString& executableRRHostPort) {
|
||||
gdbWidget->setExecutableRRHostPort(executableRRHostPort);
|
||||
}
|
||||
|
||||
const QString& SeerMainWindow::executableRRHostPort () const {
|
||||
return gdbWidget->executableRRHostPort();
|
||||
}
|
||||
|
||||
void SeerMainWindow::setExecutableCoreFilename (const QString& executableCoreFilename) {
|
||||
@@ -388,6 +396,13 @@ void SeerMainWindow::launchExecutable (const QString& launchMode, const QString&
|
||||
|
||||
gdbWidget->handleGdbConnectExecutable();
|
||||
|
||||
}else if (launchMode == "rr") {
|
||||
|
||||
actionGdbRun->setVisible(false);
|
||||
actionGdbStart->setVisible(false);
|
||||
|
||||
gdbWidget->handleGdbRRExecutable();
|
||||
|
||||
}else if (launchMode == "corefile") {
|
||||
|
||||
actionGdbRun->setVisible(false);
|
||||
@@ -443,7 +458,8 @@ void SeerMainWindow::handleFileDebug () {
|
||||
dlg.setRandomizeStartAddress(executableRandomizeStartAddress());
|
||||
dlg.setNonStopMode(executableNonStopMode());
|
||||
dlg.setAttachPid(executablePid());
|
||||
dlg.setConnectHostPort(executableHostPort());
|
||||
dlg.setConnectHostPort(executableConnectHostPort());
|
||||
dlg.setRRHostPort(executableRRHostPort());
|
||||
dlg.setCoreFilename(executableCoreFilename());
|
||||
dlg.setLaunchMode(executableLaunchMode());
|
||||
dlg.setBreakpointMode(executableBreakMode());
|
||||
@@ -476,7 +492,8 @@ void SeerMainWindow::handleFileDebug () {
|
||||
setExecutableRandomizeStartAddress(dlg.randomizeStartAddress());
|
||||
setExecutableNonStopMode(dlg.nonStopMode());
|
||||
setExecutablePid(dlg.attachPid());
|
||||
setExecutableHostPort(dlg.connectHostPort());
|
||||
setExecutableConnectHostPort(dlg.connectHostPort());
|
||||
setExecutableRRHostPort(dlg.rrHostPort());
|
||||
setExecutableCoreFilename(dlg.coreFilename());
|
||||
setExecutablePreGdbCommands(dlg.preGdbCommands());
|
||||
setExecutablePostGdbCommands(dlg.postGdbCommands());
|
||||
@@ -742,6 +759,10 @@ void SeerMainWindow::handleText (const QString& text) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newtext == "^error,msg=\"The current thread has terminated\"") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Display the error message.
|
||||
QString msg_text = Seer::parseFirst(text, "msg=", false);
|
||||
|
||||
@@ -839,6 +860,9 @@ void SeerMainWindow::handleText (const QString& text) {
|
||||
}else if (text.startsWith("^done,asm_insns=[")) {
|
||||
return;
|
||||
|
||||
}else if (text.startsWith("^done,ada-exceptions={") && text.endsWith("}")) {
|
||||
return;
|
||||
|
||||
}else if (text.contains(QRegExp("^([0-9]+)\\^done"))) {
|
||||
return;
|
||||
|
||||
@@ -884,6 +908,17 @@ void SeerMainWindow::handleText (const QString& text) {
|
||||
|
||||
QMessageBox::warning(this, "Warning.", "Program encountered a '" + signalname_text + "' signal.");
|
||||
|
||||
}else if (reason_text == "breakpoint-hit") {
|
||||
|
||||
QString bkptno_text = Seer::parseFirst(text, "bkptno=", '"', '"', false);
|
||||
QString disp_text = Seer::parseFirst(text, "disp=", '"', '"', false);
|
||||
|
||||
if (disp_text == "del") {
|
||||
QMessageBox::information(this, "Note.", "Program reached temporary breakpoint '" + bkptno_text + "'.");
|
||||
}else{
|
||||
QMessageBox::information(this, "Note.", "Program reached breakpoint '" + bkptno_text + "'.");
|
||||
}
|
||||
|
||||
}else if (reason_text == "watchpoint-trigger") {
|
||||
//*stopped,reason="watchpoint-trigger",wpt={number="3",exp="i"},value={old="32767",new="42"},frame={addr="0x0000000000400d79",func="function1",args=[{name="text",value="\"Hello, World!\""}],file="function1.cpp",fullname="/home/erniep/Development/Peak/src/Seer/helloworld/function1.cpp",line="9",arch="i386:x86-64"},thread-id="1",stopped-threads="all",core="0"
|
||||
|
||||
@@ -979,7 +1014,7 @@ void SeerMainWindow::handleRunStatusChanged (SeerRunStatusIndicator::RunStatus s
|
||||
|
||||
void SeerMainWindow::handleRecordSettingsChanged () {
|
||||
|
||||
if (gdbWidget->gdbRecordMode() == "stop") {
|
||||
if (gdbWidget->gdbRecordMode() == "stop" || gdbWidget->gdbRecordMode() == "") {
|
||||
|
||||
// Menu Control
|
||||
actionControlRecordStart->setEnabled(true);
|
||||
@@ -991,6 +1026,7 @@ void SeerMainWindow::handleRecordSettingsChanged () {
|
||||
|
||||
// Toolbar
|
||||
actionRecordProcess->setText("Record");
|
||||
actionRecordProcess->setEnabled(true);
|
||||
actionRecordDirection->setEnabled(false);
|
||||
actionRecordDirection->setIcon(QIcon(":/seer/resources/RelaxLightIcons/go-next.svg"));
|
||||
|
||||
@@ -1023,6 +1059,39 @@ void SeerMainWindow::handleRecordSettingsChanged () {
|
||||
|
||||
// Toolbar
|
||||
actionRecordProcess->setText("Recording");
|
||||
actionRecordProcess->setEnabled(true);
|
||||
actionRecordDirection->setEnabled(true);
|
||||
|
||||
}else if (gdbWidget->gdbRecordMode() == "rr") {
|
||||
|
||||
// Menu Control
|
||||
actionControlRecordStart->setEnabled(false);
|
||||
actionControlRecordStop->setEnabled(false);
|
||||
actionControlRecordForward->setEnabled(true);
|
||||
actionControlRecordReverse->setEnabled(true);
|
||||
|
||||
if (gdbWidget->gdbRecordDirection() == "") {
|
||||
|
||||
actionControlRecordForward->setChecked(true);
|
||||
actionRecordDirection->setIcon(QIcon(":/seer/resources/RelaxLightIcons/go-next.svg"));
|
||||
|
||||
}else if (gdbWidget->gdbRecordDirection() == "--reverse") {
|
||||
|
||||
actionControlRecordReverse->setChecked(true);
|
||||
actionRecordDirection->setIcon(QIcon(":/seer/resources/RelaxLightIcons/go-previous.svg"));
|
||||
|
||||
}else{
|
||||
|
||||
actionControlRecordForward->setChecked(false);
|
||||
actionControlRecordReverse->setChecked(false);
|
||||
actionRecordDirection->setIcon(QIcon(":/seer/resources/RelaxLightIcons/go-next.svg"));
|
||||
|
||||
qDebug() << "Bad record direction of '" << gdbWidget->gdbRecordDirection() << "'";
|
||||
}
|
||||
|
||||
// Toolbar
|
||||
actionRecordProcess->setText("RR");
|
||||
actionRecordProcess->setEnabled(true);
|
||||
actionRecordDirection->setEnabled(true);
|
||||
|
||||
}else{
|
||||
|
||||
@@ -41,8 +41,10 @@ class SeerMainWindow : public QMainWindow, protected Ui::SeerMainWindowForm {
|
||||
bool executableNonStopMode () const;
|
||||
void setExecutablePid (int pid);
|
||||
int executablePid () const;
|
||||
void setExecutableHostPort (const QString& executableHostPort);
|
||||
const QString& executableHostPort () const;
|
||||
void setExecutableConnectHostPort (const QString& executableConnectHostPort);
|
||||
const QString& executableConnectHostPort () const;
|
||||
void setExecutableRRHostPort (const QString& executableRRHostPort);
|
||||
const QString& executableRRHostPort () const;
|
||||
void setExecutableCoreFilename (const QString& executableCoreFilename);
|
||||
const QString& executableCoreFilename () const;
|
||||
void setExecutablePreGdbCommands (const QStringList& preGdbCommands);
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
// Increment this with every release on GitHub.
|
||||
// See scripts/change_versionnumber
|
||||
//
|
||||
#define SEER_VERSION "1.16"
|
||||
#define SEER_VERSION "1.17"
|
||||
|
||||
namespace Seer {
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<file>resources/RelaxLightIcons/help-whatsthis.svg</file>
|
||||
<file>resources/RelaxLightIcons/tools-media-optical-burn-image.svg</file>
|
||||
<file>resources/help/ThreadProcessInfoBrowser.md</file>
|
||||
<file>resources/help/seergdb.hlp</file>
|
||||
<file>resources/help/StructVisualizer.md</file>
|
||||
<file>resources/help/BasicStructVisualizer.md</file>
|
||||
<file>resources/help/MemoryVisualizer.md</file>
|
||||
@@ -66,6 +67,7 @@
|
||||
<file>resources/help/RunDebugMode.md</file>
|
||||
<file>resources/help/AttachDebugMode.md</file>
|
||||
<file>resources/help/ConnectDebugMode.md</file>
|
||||
<file>resources/help/RRDebugMode.md</file>
|
||||
<file>resources/help/CorefileDebugMode.md</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -6,6 +6,7 @@ Seer supports most debugging modes that gdb provides. These are:
|
||||
* Starting and running a program
|
||||
* Attaching to a local process on the system
|
||||
* Connecting to a gdbserver
|
||||
* Connecting to a RR replay session
|
||||
* Loading a corefile leftover from a program that crashed
|
||||
|
||||
### What can you do?
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
## RR debug mode
|
||||
|
||||
### Introduction
|
||||
|
||||
This mode allows Seer to debug a local or remote RR replay session.
|
||||
|
||||
RR allows time-travel debugging. In that, you can step forward or backwards in the execution of program
|
||||
being debugged.
|
||||
|
||||
gdb has its own notion of time-travel debugging. However, it differs from RR's method. With gdb, the
|
||||
record of instructions is recorded as you are debugging the program. With RR, the record of instructions
|
||||
are made once when you run the program with 'rr record'. Seer/gdb can then connect to the recordings
|
||||
via the 'rr replay -s' command.
|
||||
|
||||
Further information on RR is listed below in the references.
|
||||
|
||||
|
||||
### Requirements
|
||||
In this mode, Seer needs:
|
||||
|
||||
* Optional symbol file if the executable doesn't have debug information
|
||||
* How to look for the RR replay session (machine and port)
|
||||
* Optional gdb commands to execute before and after Seer connects to the RR replay session
|
||||
|
||||
### What can you do?
|
||||
In this mode, Seer will connect to the RR replay session via its host:port. The program will be stopped befor 'main'.
|
||||
At this point you can set breakpoints and tell Seer to 'continue' or any typical debugging command.
|
||||
|
||||
Seer will show a 'Direction' arrow on the toolbar. This will set the debugging direction to forward or reverse. And
|
||||
affects all commands like: 'step', 'next', 'finish', etc.
|
||||
|
||||
A typical debugging sequence would look like:
|
||||
|
||||
```
|
||||
# Use RR to record all instructions for a program.
|
||||
$ rr record -n hellosegv one two three
|
||||
|
||||
# Use RR to start a replay session on the previously create instructions. Pick a free port.
|
||||
$ rr replay -s 50505 -k
|
||||
Launch gdb with
|
||||
gdb '-l' '10000' '-ex' 'set sysroot /' '-ex' 'target extended-remote 127.0.0.1:50505' /nas/erniep/Development/seer/tests/hellosegv/hellosegv
|
||||
|
||||
# In a separate terminal, use Seer to connect to that replay session port.
|
||||
$ seergdb --rr localhost:50505
|
||||
```
|
||||
|
||||
Now use Seer as you normally would. Use the Direction arrow in the main toolbar to change debugging directions.
|
||||
|
||||
### References
|
||||
|
||||
Check references for RR and gdb.
|
||||
|
||||
* [RR website](https://rr-project.org)
|
||||
* [RR github](https://github.com/rr-debugger/rr/wiki/Usage)
|
||||
* [gdb's record mode](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Process-Record-and-Replay.html#index-record-mode)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
Usage: seergdb [LAUNCHOPTIONS] [MISCOPTIONS] executable [arguments ...]
|
||||
|
||||
Seer - A gui frontend for gdb.
|
||||
|
||||
-h, --help Displays help on commandline options.
|
||||
-v, --version Displays version information.
|
||||
|
||||
|
||||
Launch Options (pick one):
|
||||
|
||||
-r, --run <executable> <arguments> Load the executable and run it.
|
||||
|
||||
-s, --start <executable> <arguments> Load the executable, break in "main", and run it.
|
||||
|
||||
--attach <pid> <executable> Attach to a locally running process.
|
||||
|
||||
--connect <medium> [--sym <symbolfile>] Connect to an already running gdbserver (local or remote).
|
||||
Possible connection mediums are:
|
||||
|
||||
host:port
|
||||
/dev/<serialdev>
|
||||
|
||||
'sym' is optional if the debugging info is in a separate file.
|
||||
|
||||
--rr <host:port> Connect to an already running 'rr replay -s <port> -k' session.
|
||||
|
||||
--core <corefile> <executable> Load a corefile.
|
||||
|
||||
--project <project> Launch using a Seer project.
|
||||
|
||||
--config Launch with Seer's config dialog.
|
||||
Save settings with: 'Settings->Save Configuration'
|
||||
|
||||
Misc Options:
|
||||
|
||||
--sym, --symbol-file <symbolfilename> Load symbols from a separate file than the executable.
|
||||
--bl, --break-load <filename> Load a previously saved breakpoints file. For 'run' or 'start'.
|
||||
--bf, --break-function <function> Set a breakpoint in a function/address. For 'run' or 'start'.
|
||||
--sat, --show-assembly-tab <yes|no> Show the Assembly Tab on Seer startup. For 'run' or 'start'.
|
||||
--sar, --start-address-randomize <yes|no> Randomize the program's starting address. For 'run' or 'start'.
|
||||
--nsm, --non-stop-mode <yes|no> Continue to run other threads at breakpoints. For 'run' or 'start'.
|
||||
--xxx Turn on internal Seer debugging messages.
|
||||
|
||||
|
||||
Arguments:
|
||||
|
||||
executable The executable to debug. Needed for 'run', 'start', 'attach', and
|
||||
'core' run modes.
|
||||
arguments Arguments for the executable. Needed for 'run' and 'start'.
|
||||
|
||||
+81
-33
@@ -6,7 +6,30 @@
|
||||
#include <QtCore/QCommandLineOption>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QDebug>
|
||||
#include <iostream>
|
||||
|
||||
static void seerhelp() {
|
||||
|
||||
QString text;
|
||||
QString fileName(":/seer/resources/help/seergdb.hlp");
|
||||
|
||||
QFile file(fileName);
|
||||
|
||||
if (file.open(QIODevice::ReadOnly) == false) {
|
||||
text = "seer: no help available.\n";
|
||||
}else{
|
||||
text = file.readAll();
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
QTextStream(stdout) << text;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
|
||||
@@ -27,7 +50,7 @@ int main (int argc, char* argv[]) {
|
||||
|
||||
QCoreApplication::setApplicationName("seergdb");
|
||||
QCoreApplication::setOrganizationName("seergdb");
|
||||
QCoreApplication::setApplicationVersion(Seer::version() + " - Ernie Pasveer (c)2021");
|
||||
QCoreApplication::setApplicationVersion(Seer::version() + " - Ernie Pasveer (c)2021 - 2023");
|
||||
|
||||
//
|
||||
// Parse arguments.
|
||||
@@ -36,61 +59,69 @@ int main (int argc, char* argv[]) {
|
||||
parser.setApplicationDescription("\nSeer - A gui frontend for gdb.");
|
||||
parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments); // Treat all arguments after the executable name as positional arguments too.
|
||||
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); // Treat all arguments long options.
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
|
||||
// Run or start options.
|
||||
QCommandLineOption runOption(QStringList()<<"r"<<"run", QCoreApplication::translate("main", "Load the executable and run it."));
|
||||
QCommandLineOption runOption(QStringList() << "r" << "run");
|
||||
parser.addOption(runOption);
|
||||
|
||||
QCommandLineOption startOption(QStringList()<<"s"<<"start", QCoreApplication::translate("main", "Load the executable, break in \"main\", and run it."));
|
||||
QCommandLineOption startOption(QStringList() << "s" << "start");
|
||||
parser.addOption(startOption);
|
||||
|
||||
QCommandLineOption symbolfileOption(QStringList()<<"sym"<<"symbol-file", QCoreApplication::translate("main", "Load symbols from a separate file than the executable."), "symbolfilename");
|
||||
parser.addOption(symbolfileOption);
|
||||
|
||||
QCommandLineOption breakfileOption(QStringList()<<"bl"<<"break-load", QCoreApplication::translate("main", "Load a previously saved breakpoints file. For --run or --start"), "filename");
|
||||
parser.addOption(breakfileOption);
|
||||
|
||||
QCommandLineOption breakfunctionOption(QStringList()<<"bf"<<"break-function", QCoreApplication::translate("main", "Set a breakpoint in a function/address. For --run or --start"), "function");
|
||||
parser.addOption(breakfunctionOption);
|
||||
|
||||
QCommandLineOption showAssemblyTabOption(QStringList()<<"sat"<<"show-assembly-tab", QCoreApplication::translate("main", "Show the Assembly Tab on Seer startup. For --run or --start"), "yes|no");
|
||||
parser.addOption(showAssemblyTabOption);
|
||||
|
||||
QCommandLineOption startAddressRandomizeOption(QStringList()<<"sar"<<"start-address-randomize", QCoreApplication::translate("main", "Randomize the program's starting address. For --run or --start"), "yes|no");
|
||||
parser.addOption(startAddressRandomizeOption);
|
||||
|
||||
QCommandLineOption nonStopModeOption(QStringList()<<"nsm"<<"non-stop-mode", QCoreApplication::translate("main", "Continue to run other threads at breakpoints. For --run or --start"), "yes|no");
|
||||
parser.addOption(nonStopModeOption);
|
||||
|
||||
QCommandLineOption attachOption(QStringList()<<"attach", QCoreApplication::translate("main", "Attach to a locally running process."), "pid");
|
||||
QCommandLineOption attachOption(QStringList() << "attach", "", "pid");
|
||||
parser.addOption(attachOption);
|
||||
|
||||
QCommandLineOption connectOption(QStringList()<<"connect", QCoreApplication::translate("main", "Connect to a running process with gdbserver (local or remote). Manually start gdbserver first.\nPossible connection mediums are:\n host:port\n /dev/<serialdev>"), "medium");
|
||||
QCommandLineOption connectOption(QStringList() << "connect", "", "medium");
|
||||
parser.addOption(connectOption);
|
||||
|
||||
QCommandLineOption corefileOption(QStringList()<<"core", QCoreApplication::translate("main", "Load a corefile."), "corefile");
|
||||
QCommandLineOption rrOption(QStringList() << "rr", "", "hostport");
|
||||
parser.addOption(rrOption);
|
||||
|
||||
QCommandLineOption corefileOption(QStringList() << "core", "", "corefile");
|
||||
parser.addOption(corefileOption);
|
||||
|
||||
QCommandLineOption projectOption(QStringList()<<"project", QCoreApplication::translate("main", "Load a Seer project."), "project");
|
||||
QCommandLineOption projectOption(QStringList() << "project", "", "project");
|
||||
parser.addOption(projectOption);
|
||||
|
||||
QCommandLineOption configOption(QStringList()<<"config", QCoreApplication::translate("main", "Launch with config dialog.\nSave settings with:\n 'Settings->Save Configuration'"));
|
||||
QCommandLineOption configOption(QStringList() << "config");
|
||||
parser.addOption(configOption);
|
||||
|
||||
QCommandLineOption xxdebugOption(QStringList()<<"xxx", QCoreApplication::translate("main", "Turn on internal Seer debugging messages."));
|
||||
QCommandLineOption symbolfileOption(QStringList() << "sym" << "symbol-file", "", "symbolfile");
|
||||
parser.addOption(symbolfileOption);
|
||||
|
||||
QCommandLineOption breakfileOption(QStringList() << "bl" << "break-load", "", "breakpointfile");
|
||||
parser.addOption(breakfileOption);
|
||||
|
||||
QCommandLineOption breakfunctionOption(QStringList() << "bf" << "break-function", "", "breakpointfunction");
|
||||
parser.addOption(breakfunctionOption);
|
||||
|
||||
QCommandLineOption showAssemblyTabOption(QStringList() << "sat" << "show-assembly-tab");
|
||||
parser.addOption(showAssemblyTabOption);
|
||||
|
||||
QCommandLineOption startAddressRandomizeOption(QStringList() << "sar" << "start-address-randomize");
|
||||
parser.addOption(startAddressRandomizeOption);
|
||||
|
||||
QCommandLineOption nonStopModeOption(QStringList() << "nsm" << "non-stop-mode");
|
||||
parser.addOption(nonStopModeOption);
|
||||
|
||||
QCommandLineOption xxdebugOption(QStringList() << "xxx");
|
||||
parser.addOption(xxdebugOption);
|
||||
|
||||
QCommandLineOption helpOption(QStringList() << "h" << "help");
|
||||
parser.addOption(helpOption);
|
||||
|
||||
// A positional argument for executable name.
|
||||
// All other arguments after that are treated as positional arguments for the executable.
|
||||
parser.addPositionalArgument("executable", QCoreApplication::translate("main", "The executable to debug. Needed for all run modes."));
|
||||
parser.addPositionalArgument("arguments", QCoreApplication::translate("main", "Arguments for the executable. Needed for --run and --start."), "[arguments ...]");
|
||||
parser.addPositionalArgument("executableandarguments", "");
|
||||
|
||||
// Process the arguments.
|
||||
parser.process(app);
|
||||
|
||||
if (parser.isSet(helpOption)) {
|
||||
//parser.showHelp();
|
||||
seerhelp();
|
||||
}
|
||||
|
||||
if (parser.isSet(xxdebugOption)) {
|
||||
QLoggingCategory::setFilterRules("*.debug=false\n"
|
||||
"*.info=false\n"
|
||||
@@ -113,7 +144,8 @@ int main (int argc, char* argv[]) {
|
||||
QString launchMode = "none";
|
||||
QString breakMode = "none";
|
||||
int executablePid = -1;
|
||||
QString executableHostPort;
|
||||
QString executableConnectHostPort;
|
||||
QString executableRRHostPort;
|
||||
QString executableSymbolFilename;
|
||||
QString executableBreakpointsFilename;
|
||||
QString executableBreakpointFunctionName;
|
||||
@@ -169,7 +201,13 @@ int main (int argc, char* argv[]) {
|
||||
if (parser.isSet(connectOption)) {
|
||||
launchMode = "connect";
|
||||
|
||||
executableHostPort = parser.value(connectOption);
|
||||
executableConnectHostPort = parser.value(connectOption);
|
||||
}
|
||||
|
||||
if (parser.isSet(rrOption)) {
|
||||
launchMode = "rr";
|
||||
|
||||
executableRRHostPort = parser.value(rrOption);
|
||||
}
|
||||
|
||||
if (parser.isSet(corefileOption)) {
|
||||
@@ -246,8 +284,18 @@ int main (int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "EXECUTABLENAME" << executableName;
|
||||
qDebug() << "SYMBOLNAME" << executableSymbolFilename;
|
||||
qDebug() << "PID" << executablePid;
|
||||
qDebug() << "CONNECTHOST" << executableConnectHostPort;
|
||||
qDebug() << "RRHOSTPORT" << executableRRHostPort;
|
||||
qDebug() << "COREFILENAME" << executableCoreFilename;
|
||||
qDebug() << "PROJECTFILE" << projectFilename;
|
||||
qDebug() << "ARGUMENTS" << positionalArguments;
|
||||
|
||||
seer.setExecutablePid(executablePid);
|
||||
seer.setExecutableHostPort(executableHostPort);
|
||||
seer.setExecutableConnectHostPort(executableConnectHostPort);
|
||||
seer.setExecutableRRHostPort(executableRRHostPort);
|
||||
seer.setExecutableCoreFilename(executableCoreFilename);
|
||||
seer.setProjectFilename(projectFilename);
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
helloexceptions
|
||||
*.seer
|
||||
@@ -0,0 +1,11 @@
|
||||
.PHONY: all
|
||||
|
||||
all: helloexceptions
|
||||
|
||||
helloexceptions: helloexceptions.cpp
|
||||
g++ -g -o helloexceptions helloexceptions.cpp
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f helloexceptions helloexceptions.o
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
int AddPositiveIntegers (int a, int b) {
|
||||
|
||||
if (a < 0 || b < 0) {
|
||||
throw std::invalid_argument("AddPositiveIntegers arguments must be positive");
|
||||
}
|
||||
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
try {
|
||||
|
||||
std::cout << AddPositiveIntegers(-1, 2); //exception
|
||||
|
||||
} catch (std::invalid_argument& e) {
|
||||
|
||||
std::cerr << e.what() << std::endl;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
Record a RR session.
|
||||
|
||||
https://github.com/rr-debugger/rr/wiki/Usage
|
||||
|
||||
$ rr record -n hellosegv one two three
|
||||
|
||||
Replay the RR session in gdb.
|
||||
|
||||
$ rr replay
|
||||
|
||||
Using RR in a gui debugger. Basically, attach to the rr server port.
|
||||
|
||||
https://github.com/rr-debugger/rr/wiki/Using-rr-in-an-IDE
|
||||
|
||||
$ rr replay -s 50505 -k
|
||||
|
||||
$ rr replay -s 50505 -k
|
||||
Launch gdb with
|
||||
gdb '-l' '10000' '-ex' 'set sysroot /' '-ex' 'target extended-remote 127.0.0.1:50505' /nas/erniep/Development/seer/tests/hellosegv/hellosegv
|
||||
|
||||
In a different terminal, use "Connect" method in Debug dialog and connect to "127.0.0.1:50505".
|
||||
|
||||
$ seergdb --connect localhost:50505
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"seerproject": {
|
||||
"corefilemode": {
|
||||
"corefile": "/nas/erniep/Development/seer/tests/hellosegv/core.hellosegv.26364"
|
||||
"corefile": "/nas/erniep/Development/seer/tests/hellosegv/core.hellosegv.18539"
|
||||
},
|
||||
"executable": "/nas/erniep/Development/seer/tests/hellosegv/hellosegv",
|
||||
"postgdbcommands": [
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
https://github.com/epasveer/seer/wiki/Valgrind-and-Seer.
|
||||
|
||||
In one terminal, run:
|
||||
|
||||
$ valgrind -q --vgdb-error=0 ./hellovalgrind
|
||||
==12596== (action at startup) vgdb me ...
|
||||
==12596==
|
||||
==12596== TO DEBUG THIS PROCESS USING GDB: start GDB like this
|
||||
==12596== /path/to/gdb ./hellovalgrind
|
||||
==12596== and then give GDB the following command
|
||||
==12596== target remote | /usr/lib/valgrind/../../bin/vgdb --pid=12596
|
||||
==12596== --pid is optional if only one valgrind process is running
|
||||
==12596==
|
||||
|
||||
In another terminal, start Seer.
|
||||
|
||||
$ seergdb --connect '| vgdb' --sym hellovalgrind
|
||||
|
||||
|
||||
Reference in New Issue
Block a user