diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3a66392..67d4683 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -308,10 +308,20 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE
# Handle default gdb binary name and location.
# -DCONFIG_SEER_GDB_NAME=/app/bin/gdb
if(NOT DEFINED CONFIG_SEER_GDB_NAME)
- set(CONFIG_SEER_GDB_NAME"/usr/bin/gdb")
+ set(CONFIG_SEER_GDB_NAME "/usr/bin/gdb")
endif()
target_compile_definitions(${PROJECT_NAME} PRIVATE
SEER_GDB_NAME=${CONFIG_SEER_GDB_NAME}
)
+# Handle default gdb binary launcher (for flatpak, et al)
+# -DCONFIG_SEER_GDB_LAUNCHER="flatpak-spawn --host"
+if(NOT DEFINED CONFIG_SEER_GDB_LAUNCHER)
+ set(CONFIG_SEER_GDB_LAUNCHER "")
+endif()
+
+target_compile_definitions(${PROJECT_NAME} PRIVATE
+ SEER_GDB_LAUNCHER=${CONFIG_SEER_GDB_LAUNCHER}
+)
+
diff --git a/src/SeerConfigDialog.cpp b/src/SeerConfigDialog.cpp
index 8fed484..8422134 100644
--- a/src/SeerConfigDialog.cpp
+++ b/src/SeerConfigDialog.cpp
@@ -164,6 +164,12 @@ bool SeerConfigDialog::seerClearManualCommandHistory () const {
return _seerConfigPage->clearManualCommandHistory();
}
+void SeerConfigDialog::setProgramLauncher (const QString& launcher) {
+
+ _gdbConfigPage->setGdbProgramLauncher(launcher);
+ _rrConfigPage->setRRProgramLauncher(launcher);
+}
+
void SeerConfigDialog::setGdbProgram (const QString& program) {
_gdbConfigPage->setGdbProgram(program);
diff --git a/src/SeerConfigDialog.h b/src/SeerConfigDialog.h
index f80d064..9c74cf8 100644
--- a/src/SeerConfigDialog.h
+++ b/src/SeerConfigDialog.h
@@ -43,6 +43,9 @@ class SeerConfigDialog : public QDialog, protected Ui::SeerConfigDialogForm {
void setSeerClearManualCommandHistory (bool flag);
bool seerClearManualCommandHistory () const;
+ // Program to launch gdb, rr, etc. Can be blank. Needed by flatpak.
+ void setProgramLauncher (const QString& launcher);
+
// Gdb settings.
void setGdbProgram (const QString& program);
QString gdbProgram () const;
diff --git a/src/SeerGdbConfigPage.cpp b/src/SeerGdbConfigPage.cpp
index be630c2..24848a2 100644
--- a/src/SeerGdbConfigPage.cpp
+++ b/src/SeerGdbConfigPage.cpp
@@ -77,6 +77,11 @@ void SeerGdbConfigPage::setGdbProgram (const QString& program) {
gdbProgramLineEdit->setText(program);
}
+void SeerGdbConfigPage::setGdbProgramLauncher (const QString& launcher) {
+
+ return gdbLauncherLineEdit->setText(launcher);
+}
+
void SeerGdbConfigPage::setGdbArguments (const QString& arguments) {
gdbArgumentsLineEdit->setText(arguments);
@@ -124,6 +129,7 @@ void SeerGdbConfigPage::reset () {
#else
setGdbProgram("/usr/bin/gdb";
#endif
+ setGdbProgramLauncher("");
setGdbArguments("--interpreter=mi");
setGdbAsyncMode(true);
setGdbNonStopMode(false);
diff --git a/src/SeerGdbConfigPage.h b/src/SeerGdbConfigPage.h
index 24d4dbe..7a3656d 100644
--- a/src/SeerGdbConfigPage.h
+++ b/src/SeerGdbConfigPage.h
@@ -28,6 +28,7 @@ class SeerGdbConfigPage : public QWidget, protected Ui::SeerGdbConfigPage {
void setGdbProgram (const QString& program);
+ void setGdbProgramLauncher (const QString& launcher);
void setGdbArguments (const QString& arguments);
void setGdbAsyncMode (bool flag);
void setGdbNonStopMode (bool flag);
diff --git a/src/SeerGdbConfigPage.ui b/src/SeerGdbConfigPage.ui
index 2b2eebe..968edae 100644
--- a/src/SeerGdbConfigPage.ui
+++ b/src/SeerGdbConfigPage.ui
@@ -7,7 +7,7 @@
0
0
788
- 714
+ 881
@@ -68,134 +68,160 @@
- -
-
-
-
-
-
- Turn gdb 'async' mode on or off.
-
-
- Async mode
-
-
-
- -
-
-
- Allow other threads to continue if any thread reaches a breakpoint.
-
-
- Non-stop mode
-
-
-
- -
-
-
- Randomize the process start address.
-
-
- Randomize start address
-
-
-
- -
-
-
- Handle terminating exceptions when calling functions.
-
-
- Handle terminating-exception
-
-
-
- -
-
-
- Show variables with gdb's 'pretty-printing' system.
-
-
- Enable pretty-printing
-
-
-
-
+ -
+
+
+ GDB launcher
+
+
- -
-
-
-
-
-
- Remote target type
-
-
-
- -
-
-
- Select the type of remote target connection.
-
-
-
-
- remote
-
-
- -
-
- extended-remote
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 385
- 20
-
-
-
-
- -
-
-
- Architecture type
-
-
-
- -
-
-
- Executable architecture type.
-
-
- true
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 385
- 20
-
-
-
-
-
+ -
+
+
+ The program, if needed, to launch the gdb binary.
+
+
+
+
+
+ true
+
+
+ No launcher is needed.
+
+
+ true
+
+
+ -
+
+
-
+
+
+ Turn gdb 'async' mode on or off.
+
+
+ Async mode
+
+
+
+ -
+
+
+ Allow other threads to continue if any thread reaches a breakpoint.
+
+
+ Non-stop mode
+
+
+
+ -
+
+
+ Randomize the process start address.
+
+
+ Randomize start address
+
+
+
+ -
+
+
+ Handle terminating exceptions when calling functions.
+
+
+ Handle terminating-exception
+
+
+
+ -
+
+
+ Show variables with gdb's 'pretty-printing' system.
+
+
+ Enable pretty-printing
+
+
+
+
+
+ -
+
+
-
+
+
+ Remote target type
+
+
+
+ -
+
+
+ Select the type of remote target connection.
+
+
-
+
+ remote
+
+
+ -
+
+ extended-remote
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 385
+ 20
+
+
+
+
+ -
+
+
+ Architecture type
+
+
+
+ -
+
+
+ Executable architecture type.
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 385
+ 20
+
+
+
+
+
+
-
@@ -212,6 +238,8 @@ li.checked::marker { content: "\2612"; }
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Note, Seer relies on the "mi" interpreter that is built into gdb. If a different debugger is used, it must provide that. So, usually, the "--interpreter=mi" argument is a must.</p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sometimes, gdb needs to be launched by another program. For example, under flatpak, gdb needs to be launched by flatpak-spawn. This is defined when compiling Seer. See the CMakefile.txt file. Normally, this does not need to be set.</p>
+<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Async mode allows all gdb actions to happen in the background. This allows interrupting of a running program possible. Note, this is disabled for 'connect' mode as background commands may overwhelm the gdbserver.</p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Non-stop mode, when turned on, will allow other threads to continue to run while another thread reaches a breakpoint.</p>
diff --git a/src/SeerGdbWidget.cpp b/src/SeerGdbWidget.cpp
index 9404bca..e5d7444 100644
--- a/src/SeerGdbWidget.cpp
+++ b/src/SeerGdbWidget.cpp
@@ -630,6 +630,17 @@ QString SeerGdbWidget::gdbProgram () const {
return _gdbProgram;
}
+QString SeerGdbWidget::gdbProgramLauncher () const {
+
+ QString gdbLauncher = "";
+
+#ifdef SEER_GDB_LAUNCHER
+ gdbLauncher = STRINGIFY(SEER_GDB_LAUNCHER);
+#endif
+
+ return gdbLauncher;
+}
+
void SeerGdbWidget::setGdbArguments (const QString& arguments) {
_gdbArguments = arguments;
@@ -1034,15 +1045,17 @@ void SeerGdbWidget::handleManualCommandExecute () {
handleGdbCommand(command);
}
-void SeerGdbWidget::handleGdbCommand (const QString& command) {
+void SeerGdbWidget::handleGdbCommand (const QString& command, bool ignoreErrors) {
qCDebug(LC) << "Command=" << command;
if (_gdbProcess->state() == QProcess::NotRunning) {
- QMessageBox::warning(this, "Seer",
- QString("The executable has not been started yet or has already exited.\n\n") +
- "(" + command + ")",
- QMessageBox::Ok);
+ if (ignoreErrors == false) {
+ QMessageBox::warning(this, "Seer",
+ QString("The executable has not been started yet or has already exited.\n\n") +
+ "(" + command + ")",
+ QMessageBox::Ok);
+ }
return;
}
@@ -1679,12 +1692,12 @@ void SeerGdbWidget::handleGdbTerminateExecutable (bool confirm) {
}
}
- handleGdbCommand(QString("save breakpoints /tmp/breakpoints.seer.%1").arg(QCoreApplication::applicationPid()));
+ handleGdbCommand(QString("save breakpoints /tmp/breakpoints.seer.%1").arg(QCoreApplication::applicationPid()), true);
delay(2);
// Give the gdb and 'exit' command.
// This should handle detaching from an attached pid.
- handleGdbCommand("-exec-kill");
+ handleGdbCommand("-exec-kill", true);
// Kill the gdb.
killGdb();
@@ -3640,53 +3653,51 @@ bool SeerGdbWidget::startGdb () {
return false;
}
- // Set the gdb program name to use.
- bool ok;
+ // Build the raw command to launch the gdb program.
+ // Later the raw command will be broken into individual strings (via ' ')
+ // that the QProcess object expects.
+ QString rawcommand;
- QString rawcommand = gdbProgramOverride();
-
- if (rawcommand == "") {
- rawcommand = gdbProgram();
+ // Is a 'launcher' being used? Like 'flatpak-spawn'.
+ if (gdbProgramLauncher() != "") {
+ rawcommand += gdbProgramLauncher() + " ";
}
+ // Set the gdb program name to use.
+ if (gdbProgramOverride() != "") {
+ rawcommand += gdbProgramOverride() + " ";
+ }else{
+ rawcommand += gdbProgram() + " ";
+ }
+
+ // Build the gdb argument list.
+ if (gdbArgumentsOverride() != "") {
+ rawcommand += gdbArgumentsOverride() + " ";
+ }else{
+ rawcommand += gdbArguments() + " ";
+ }
+
+ // Now expand any $VAR environment variables.
+ bool ok;
QString expandedcommand = Seer::expandEnv(rawcommand, &ok);
//qDebug() << "Raw command : " << rawcommand;
//qDebug() << "Expanded command: " << expandedcommand;
if (ok == false) {
-
QMessageBox::critical(this, "Error", QString("Can't resolve all environment variables in command to launch gdb:\n'%1'").arg(rawcommand));
-
- return false;
- }
-
- // Build the gdb argument list.
- QString rawarguments = gdbArgumentsOverride();
-
- if (rawarguments == "") {
- rawarguments = gdbArguments();
- }
-
- QString expandedarguments = Seer::expandEnv(rawarguments, &ok);
-
- //qDebug() << "Raw arguments : " << rawarguments;
- //qDebug() << "Expanded arguments: " << expandedarguments;
-
- if (ok == false) {
-
- QMessageBox::critical(this, "Error", QString("Can't resolve all environment variables in arguments to launch gdb:\n'%1'").arg(rawarguments));
-
return false;
}
// Split string into words, handling "double quoted" words.
- QStringList args = Seer::split(expandedarguments);
+ QStringList args = Seer::split(expandedcommand);
- //qDebug() << args;
+ // Extract the program name and create a list of arguments.
+ QString program = args.front();
+ args.pop_front();
// Give the gdb process the program and the argument list.
- _gdbProcess->setProgram(expandedcommand);
+ _gdbProcess->setProgram(program);
_gdbProcess->setArguments(args);
// We need to set the C language, otherwise the MI interface is translated and our message
@@ -3719,22 +3730,46 @@ bool SeerGdbWidget::startGdbRR () {
return false;
}
- // Set the gdb program name to use.
- QString command = rrProgram();
- QString arguments = rrArguments() + " --tty " + _consoleWidget->terminalDeviceName() + " " + executableRRTraceDirectory();
+ // Build the raw command to launch the RR program.
+ // Later the raw command will be broken into individual strings (via ' ')
+ // that the QProcess object expects.
+ QString rawcommand;
+ // Is a 'launcher' being used? Like 'flatpak-spawn'.
+ if (gdbProgramLauncher() != "") {
+ rawcommand += gdbProgramLauncher() + " ";
+ }
+
+ // Set the RR program name to use.
+ rawcommand += rrProgram() + " ";
+ rawcommand += rrArguments() + " --tty " + _consoleWidget->terminalDeviceName() + " " + executableRRTraceDirectory() + " ";
+
+ // Set any extra gdb arguments that RR may want.
if (rrGdbArguments() != "") {
- arguments += " -- " + rrGdbArguments();
+ rawcommand += "-- " + rrGdbArguments() + " ";
+ }
+
+ // Now expand any $VAR environment variables.
+ bool ok;
+ QString expandedcommand = Seer::expandEnv(rawcommand, &ok);
+
+ //qDebug() << "Raw command : " << rawcommand;
+ //qDebug() << "Expanded command: " << expandedcommand;
+
+ if (ok == false) {
+ QMessageBox::critical(this, "Error", QString("Can't resolve all environment variables in command to launch RR:\n'%1'").arg(rawcommand));
+ return false;
}
// Split string into words, handling "double quoted" words.
- QStringList args = Seer::split(arguments);
+ QStringList args = Seer::split(expandedcommand);
- //qDebug() << "Expanded command: " << command;
- //qDebug() << "Expanded arguments: " << arguments;
+ // Extract the program name and create a list of arguments.
+ QString program = args.front();
+ args.pop_front();
// Give the gdb process the program and the argument list.
- _gdbProcess->setProgram(command);
+ _gdbProcess->setProgram(program);
_gdbProcess->setArguments(args);
// We need to set the C language, otherwise the MI interface is translated and our message
diff --git a/src/SeerGdbWidget.h b/src/SeerGdbWidget.h
index 4eb3e6b..e597144 100644
--- a/src/SeerGdbWidget.h
+++ b/src/SeerGdbWidget.h
@@ -79,6 +79,8 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm {
const QString& executableBreakMode () const;
// Gdb settings.
+ QString gdbProgramLauncher () const;
+
void setGdbProgram (const QString& program);
QString gdbProgram () const;
@@ -228,7 +230,7 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm {
void handleText (const QString& text);
void handleManualCommandExecute ();
- void handleGdbCommand (const QString& command);
+ void handleGdbCommand (const QString& command, bool ignoreErrors=false);
void handleGdbExit ();
void handleGdbRunExecutable (const QString& breakMode, bool loadSessionBreakpoints);
void handleGdbAttachExecutable (bool loadSessionBreakpoints);
diff --git a/src/SeerMainWindow.cpp b/src/SeerMainWindow.cpp
index e986f8d..49a07f6 100644
--- a/src/SeerMainWindow.cpp
+++ b/src/SeerMainWindow.cpp
@@ -768,6 +768,9 @@ void SeerMainWindow::handleSettingsConfiguration () {
dlg.setRRArguments(gdbWidget->rrArguments());
dlg.setRRGdbArguments(gdbWidget->rrGdbArguments());
+ // Launcher is a read-only thing. Just need to show it.
+ dlg.setProgramLauncher(gdbWidget->gdbProgramLauncher());
+
int ret = dlg.exec();
if (ret == 0) {
diff --git a/src/SeerRRConfigPage.cpp b/src/SeerRRConfigPage.cpp
index f720f03..d0ef378 100644
--- a/src/SeerRRConfigPage.cpp
+++ b/src/SeerRRConfigPage.cpp
@@ -42,6 +42,11 @@ void SeerRRConfigPage::setRRProgram (const QString& program) {
rrProgramLineEdit->setText(program);
}
+void SeerRRConfigPage::setRRProgramLauncher (const QString& launcher) {
+
+ return rrLauncherLineEdit->setText(launcher);
+}
+
void SeerRRConfigPage::setRRArguments (const QString& arguments) {
rrArgumentsLineEdit->setText(arguments);
@@ -55,6 +60,7 @@ void SeerRRConfigPage::setGdbArguments (const QString& arguments) {
void SeerRRConfigPage::reset () {
setRRProgram("/usr/bin/rr");
+ setRRProgramLauncher("");
setRRArguments("replay --interpreter=mi");
setGdbArguments("");
}
diff --git a/src/SeerRRConfigPage.h b/src/SeerRRConfigPage.h
index e0322a8..5212e5c 100644
--- a/src/SeerRRConfigPage.h
+++ b/src/SeerRRConfigPage.h
@@ -20,6 +20,7 @@ class SeerRRConfigPage : public QWidget, protected Ui::SeerRRConfigPage {
QString gdbArguments () const;
void setRRProgram (const QString& program);
+ void setRRProgramLauncher (const QString& launcher);
void setRRArguments (const QString& arguments);
void setGdbArguments (const QString& arguments);
diff --git a/src/SeerRRConfigPage.ui b/src/SeerRRConfigPage.ui
index 641fca6..aa32381 100644
--- a/src/SeerRRConfigPage.ui
+++ b/src/SeerRRConfigPage.ui
@@ -13,40 +13,8 @@
SeerRRConfigPage
-
-
- 0
-
-
- 0
-
-
-
-
-
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
-<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
-p, li { white-space: pre-wrap; }
-hr { height: 1px; border-width: 0; }
-li.unchecked::marker { content: "\2610"; }
-li.checked::marker { content: "\2612"; }
-</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Noto Sans'; font-size:10pt; font-weight:600;">Specify the RR program and location, as well as the RR arguments. </span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Noto Sans'; font-size:10pt; font-weight:600;">Changing many of these require saving the new configuration and restarting Seer to take effect</span><span style=" font-family:'Noto Sans'; font-size:10pt;">.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"><br />"RR program" points to the path and name of the RR program.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">"RR arguments" specifies the arguments to pass to RR. It must minimally have 'replay --interpreter=mi'. And other arguments you may need for RR.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">"GDB arguments" specified the arguments to pass on to gdb. Usually not needed.</span></p>
-<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Between these input fields, Seer forms the command:</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"> $ /usr/bin/rr replay --interpreter=mi [RR-arguments] [trace-directory] [--tty /dev/pts] [-- gdb-arguments] </span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"><br /></span><span style=" font-family:'Noto Sans'; font-size:10pt;">Note, Seer relies on the "mi" interpreter that is built into gdb. So, the "--interpreter=mi" argument is a must. This is specified in the "RR arguments" field.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"><br />The "trace-directory" argument is given when you run Seer in the RR mode.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">The "--tty" device is handled automatically by Seer.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"><br />Here's the RR Wiki page for more info on arguments.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">https://github.com/rr-debugger/rr/wiki/Usage<br /><br /></span></p></body></html>
-
-
-
- -
+
+
-
RR Settings
@@ -90,7 +58,7 @@ li.checked::marker { content: "\2612"; }
- -
+
-
Arguments to pass to the RR debugger.
@@ -100,7 +68,33 @@ li.checked::marker { content: "\2612"; }
- -
+
-
+
+
+ RR launcher
+
+
+
+ -
+
+
+ The program, if needed, to launch the RR binary.
+
+
+
+
+
+ true
+
+
+ No launcher is needed.
+
+
+ true
+
+
+
+ -
GDB arguments
@@ -120,6 +114,33 @@ li.checked::marker { content: "\2612"; }
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+hr { height: 1px; border-width: 0; }
+li.unchecked::marker { content: "\2610"; }
+li.checked::marker { content: "\2612"; }
+</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Specify the RR program and location, as well as the RR arguments. </span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Changing many of these require saving the new configuration and restarting Seer to take effect</span>.</p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"><br />"RR program" points to the path and name of the RR program.</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">"RR arguments" specifies the arguments to pass to RR. It must minimally have 'replay --interpreter=mi'. And other arguments you may need for RR.</span></p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sometimes, RR needs to be launched by another program. For example, under flatpak, RR needs to be launched by flatpak-spawn. This is defined when compiling Seer. See the CMakefile.txt file. Normally, this does not need to be set.</p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">"GDB arguments" specified the arguments to pass on to gdb. Usually not needed.</span></p>
+<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Between these input fields, Seer forms the command:</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"> $ /usr/bin/rr replay --interpreter=mi [RR-arguments] [trace-directory] [--tty /dev/pts] [-- gdb-arguments] </span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"><br /></span>Note, Seer relies on the "mi" interpreter that is built into gdb. So, the "--interpreter=mi" argument is a must. This is specified in the "RR arguments" field.</p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"><br />The "trace-directory" argument is given when you run Seer in the RR mode.</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">The "--tty" device is handled automatically by Seer.</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';"><br />Here's the RR Wiki page for more info on arguments.</span></p>
+<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">https://github.com/rr-debugger/rr/wiki/Usage<br /><br /></span></p></body></html>
+
+
+
rrGroupBox
textBrowser