Compare commits

..

10 Commits

Author SHA1 Message Date
Ernie Pasveer 2a24d6ae99 Hello RR. Release version 1.17 that supports RR. 2023-04-23 12:42:05 -05:00
Ernie Pasveer fb27702881 Suppress annoying popup about threads terminating. 2023-04-20 19:01:14 -05:00
Ernie Pasveer 60ef4db52d Fix bad bug parsing Seer command line arguments. (SORRY!) 2023-04-20 13:27:52 -05:00
Ernie Pasveer be3593d9e4 help: improved the help from -h and --help 2023-04-17 17:53:28 -05:00
Ernie Pasveer 7222a04130 rr: added support for RR. 2023-04-16 13:26:12 -05:00
Ernie Pasveer d5aa8f9089 rr: first attempt at adding RR support to Seer. 2023-04-15 12:36:28 -05:00
Ernie Pasveer 1735dc7f8a Notes for using RR and Seer.
It seems possible!  Probably need a new Debug tab called "RR" so that
I have a way to set the direction arrow (   <-- or -->  )  and hide
the "record" button. Because RR is just replaying the prevously recorded
session.  So "forward" and "back" buttons make sense. And no "record"
button make sense.
2023-04-12 18:50:03 -05:00
Ernie Pasveer b8c9572e23 Add 'breakpoint reached' dialog for all encountered breakpoints. 2023-04-10 11:51:03 -05:00
Ernie Pasveer 697bba1d4c Prepare for the v1.17 release cycle. 2023-04-09 12:01:10 -05:00
Ernie Pasveer a4290ffa8f Add notest file for ada exceptions. 2023-04-09 11:28:55 -05:00
25 changed files with 820 additions and 141 deletions
+5
View File
@@ -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
+2 -2
View File
@@ -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
+66
View File
@@ -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
View File
@@ -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
+25
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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{
+4 -2
View File
@@ -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
View File
@@ -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 {
+2
View File
@@ -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>
+1
View File
@@ -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?
+56
View File
@@ -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)
+51
View File
@@ -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
View File
@@ -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);
+2
View File
@@ -0,0 +1,2 @@
helloexceptions
*.seer
+11
View File
@@ -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
+28
View File
@@ -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;
}
+26
View File
@@ -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 -1
View File
@@ -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": [
+20
View File
@@ -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