Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions api/debuggerapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,14 @@ namespace BinaryNinjaDebuggerAPI {
bool IsFirstConnectToDebugServer();
bool IsFirstAttach();

bool ShouldShowAdapterSettingsForLaunch();
bool ShouldShowAdapterSettingsForAttach();
bool ShouldShowAdapterSettingsForConnect();
bool ShouldShowAdapterSettingsForConnectToDebugServer();

bool ShowAdapterSettingsNextTime();
void SetShowAdapterSettingsNextTime(bool value);

bool IsTTD();

// TTD Memory Analysis Methods
Expand Down
36 changes: 36 additions & 0 deletions api/debuggercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,42 @@ bool DebuggerController::IsFirstAttach()
}


bool DebuggerController::ShouldShowAdapterSettingsForLaunch()
{
return BNDebuggerShouldShowAdapterSettingsForLaunch(m_object);
}


bool DebuggerController::ShouldShowAdapterSettingsForAttach()
{
return BNDebuggerShouldShowAdapterSettingsForAttach(m_object);
}


bool DebuggerController::ShouldShowAdapterSettingsForConnect()
{
return BNDebuggerShouldShowAdapterSettingsForConnect(m_object);
}


bool DebuggerController::ShouldShowAdapterSettingsForConnectToDebugServer()
{
return BNDebuggerShouldShowAdapterSettingsForConnectToDebugServer(m_object);
}


bool DebuggerController::ShowAdapterSettingsNextTime()
{
return BNDebuggerShowAdapterSettingsNextTime(m_object);
}


void DebuggerController::SetShowAdapterSettingsNextTime(bool value)
{
BNDebuggerSetShowAdapterSettingsNextTime(m_object, value);
}


bool DebuggerController::IsTTD()
{
return BNDebuggerIsTTD(m_object);
Expand Down
8 changes: 8 additions & 0 deletions api/ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,14 @@ extern "C"
DEBUGGER_FFI_API bool BNDebuggerIsFirstConnectToDebugServer(BNDebuggerController* controller);
DEBUGGER_FFI_API bool BNDebuggerIsFirstAttach(BNDebuggerController* controller);

DEBUGGER_FFI_API bool BNDebuggerShouldShowAdapterSettingsForLaunch(BNDebuggerController* controller);
DEBUGGER_FFI_API bool BNDebuggerShouldShowAdapterSettingsForAttach(BNDebuggerController* controller);
DEBUGGER_FFI_API bool BNDebuggerShouldShowAdapterSettingsForConnect(BNDebuggerController* controller);
DEBUGGER_FFI_API bool BNDebuggerShouldShowAdapterSettingsForConnectToDebugServer(BNDebuggerController* controller);

DEBUGGER_FFI_API bool BNDebuggerShowAdapterSettingsNextTime(BNDebuggerController* controller);
DEBUGGER_FFI_API void BNDebuggerSetShowAdapterSettingsNextTime(BNDebuggerController* controller, bool value);

DEBUGGER_FFI_API bool BNDebuggerIsTTD(BNDebuggerController* controller);

// TTD Memory Analysis Functions
Expand Down
40 changes: 40 additions & 0 deletions core/debuggercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ DebugStopReason DebuggerController::LaunchAndWaitInternal()
}

m_firstLaunch = false;
m_lastDebugStartOperation = LaunchStartOperation;

DebuggerEvent event;
event.type = LaunchEventType;
Expand Down Expand Up @@ -421,6 +422,7 @@ bool DebuggerController::Attach()
DebugStopReason DebuggerController::AttachAndWaitInternal()
{
m_firstAttach = false;
m_lastDebugStartOperation = AttachStartOperation;

DebuggerEvent event;
event.type = LaunchEventType;
Expand Down Expand Up @@ -473,6 +475,7 @@ bool DebuggerController::Connect()
DebugStopReason DebuggerController::ConnectAndWaitInternal()
{
m_firstConnect = false;
m_lastDebugStartOperation = ConnectStartOperation;

DebuggerEvent event;
event.type = LaunchEventType;
Expand Down Expand Up @@ -1685,6 +1688,7 @@ DebugStopReason DebuggerController::RestartAndWait(std::chrono::milliseconds tim
bool DebuggerController::ConnectToDebugServer()
{
m_firstConnectToDebugServer = false;
m_lastDebugStartOperation = ConnectToDebugServerStartOperation;
if (m_state->IsConnectedToDebugServer())
return true;

Expand Down Expand Up @@ -3789,6 +3793,42 @@ bool DebuggerController::IsFirstAttach()
}


bool DebuggerController::ShouldShowAdapterSettingsForLaunch()
{
return m_lastDebugStartOperation != LaunchStartOperation || m_showAdapterSettingsNextTime;
}


bool DebuggerController::ShouldShowAdapterSettingsForAttach()
{
return m_lastDebugStartOperation != AttachStartOperation || m_showAdapterSettingsNextTime;
}


bool DebuggerController::ShouldShowAdapterSettingsForConnect()
{
return m_lastDebugStartOperation != ConnectStartOperation || m_showAdapterSettingsNextTime;
}


bool DebuggerController::ShouldShowAdapterSettingsForConnectToDebugServer()
{
return m_lastDebugStartOperation != ConnectToDebugServerStartOperation || m_showAdapterSettingsNextTime;
}


bool DebuggerController::ShowAdapterSettingsNextTime()
{
return m_showAdapterSettingsNextTime;
}


void DebuggerController::SetShowAdapterSettingsNextTime(bool value)
{
m_showAdapterSettingsNextTime = value;
}


bool DebuggerController::IsTTD()
{
if(!m_adapter)
Expand Down
23 changes: 23 additions & 0 deletions core/debuggercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,20 @@ namespace BinaryNinjaDebugger {
bool m_firstConnectToDebugServer = true;
bool m_firstAttach = true;

// Whether to show the adapter settings dialog before the next debug session is started. When the user starts a
// session whose kind differs from m_lastDebugStartOperation we always show the dialog regardless of this flag,
// so that switching between e.g. launch and attach never silently reuses stale settings.
enum LastDebugStartOperation
{
NoDebugStartOperation,
LaunchStartOperation,
AttachStartOperation,
ConnectStartOperation,
ConnectToDebugServerStartOperation,
};
bool m_showAdapterSettingsNextTime = true;
LastDebugStartOperation m_lastDebugStartOperation = NoDebugStartOperation;

bool m_shouldAnnotateStackVariable = false;

// Apply the controller's own state mutations for each event type. Called inline
Expand Down Expand Up @@ -644,6 +658,15 @@ namespace BinaryNinjaDebugger {
bool IsFirstConnect();
bool IsFirstConnectToDebugServer();
bool IsFirstAttach();

bool ShouldShowAdapterSettingsForLaunch();
bool ShouldShowAdapterSettingsForAttach();
bool ShouldShowAdapterSettingsForConnect();
bool ShouldShowAdapterSettingsForConnectToDebugServer();

bool ShowAdapterSettingsNextTime();
void SetShowAdapterSettingsNextTime(bool value);

bool IsTTD();

// TTD Memory Analysis Methods
Expand Down
36 changes: 36 additions & 0 deletions core/ffi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,42 @@ bool BNDebuggerIsFirstAttach(BNDebuggerController* controller)
}


bool BNDebuggerShouldShowAdapterSettingsForLaunch(BNDebuggerController* controller)
{
return controller->object->ShouldShowAdapterSettingsForLaunch();
}


bool BNDebuggerShouldShowAdapterSettingsForAttach(BNDebuggerController* controller)
{
return controller->object->ShouldShowAdapterSettingsForAttach();
}


bool BNDebuggerShouldShowAdapterSettingsForConnect(BNDebuggerController* controller)
{
return controller->object->ShouldShowAdapterSettingsForConnect();
}


bool BNDebuggerShouldShowAdapterSettingsForConnectToDebugServer(BNDebuggerController* controller)
{
return controller->object->ShouldShowAdapterSettingsForConnectToDebugServer();
}


bool BNDebuggerShowAdapterSettingsNextTime(BNDebuggerController* controller)
{
return controller->object->ShowAdapterSettingsNextTime();
}


void BNDebuggerSetShowAdapterSettingsNextTime(BNDebuggerController* controller, bool value)
{
controller->object->SetShowAdapterSettingsNextTime(value);
}


bool BNDebuggerIsTTD(BNDebuggerController* controller)
{
return controller->object->IsTTD();
Expand Down
23 changes: 23 additions & 0 deletions ui/adaptersettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ AdapterSettingsDialog::AdapterSettingsDialog(QWidget* parent, DbgRef<DebuggerCon
m_stack->setCurrentWidget(widget);
layout->addWidget(m_stack);

// Reflect the stored preference: checked means "do not show the dialog next time"
m_useSameSettingsCheckbox = new QCheckBox("Use same settings next time");
m_useSameSettingsCheckbox->setChecked(!m_controller->ShowAdapterSettingsNextTime());

if (!highlightGroup.empty())
{
auto adapterSettings = qobject_cast<SettingsView*>(widget);
Expand All @@ -84,6 +88,7 @@ AdapterSettingsDialog::AdapterSettingsDialog(QWidget* parent, DbgRef<DebuggerCon
connect(acceptButton, &QPushButton::clicked, [&]() { apply(); });
acceptButton->setDefault(true);

buttonLayout->addWidget(m_useSameSettingsCheckbox);
buttonLayout->addStretch(1);
buttonLayout->addWidget(cancelButton);
buttonLayout->addSpacing(10);
Expand All @@ -92,6 +97,22 @@ AdapterSettingsDialog::AdapterSettingsDialog(QWidget* parent, DbgRef<DebuggerCon
layout->addSpacing(10);
layout->addLayout(buttonLayout);
}
else
{
// The generic settings dialog (opened from the menu) has no Accept/Cancel button and applies
// settings live, so update the preference immediately whenever the checkbox is toggled. This is
// the entry point for re-enabling the dialog after it has been suppressed for an operation.
connect(m_useSameSettingsCheckbox, &QCheckBox::toggled, this,
[this](bool checked) { m_controller->SetShowAdapterSettingsNextTime(!checked); });

QHBoxLayout* checkboxLayout = new QHBoxLayout;
checkboxLayout->setContentsMargins(0, 0, 0, 0);
checkboxLayout->addWidget(m_useSameSettingsCheckbox);
checkboxLayout->addStretch(1);

layout->addSpacing(10);
layout->addLayout(checkboxLayout);
}

setLayout(layout);
}
Expand Down Expand Up @@ -139,5 +160,7 @@ QWidget* AdapterSettingsDialog::getWidgetForAdapter(const QString& adapter)

void AdapterSettingsDialog::apply()
{
if (m_useSameSettingsCheckbox)
m_controller->SetShowAdapterSettingsNextTime(!m_useSameSettingsCheckbox->isChecked());
accept();
}
1 change: 1 addition & 0 deletions ui/adaptersettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class AdapterSettingsDialog : public QDialog
QStackedWidget* m_stack;
QMap<QString, QWidget*> m_viewMap;
QLabel* m_noSettingsLabel;
QCheckBox* m_useSameSettingsCheckbox = nullptr;

QWidget* getWidgetForAdapter(const QString& adapter);

Expand Down
2 changes: 1 addition & 1 deletion ui/controlswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ void DebugControlsWidget::performLaunch()
return;

bool firstLaunch = m_controller->IsFirstLaunch();
if (firstLaunch)
if (m_controller->ShouldShowAdapterSettingsForLaunch())
{
auto adapterSettings = new AdapterSettingsDialog(this, m_controller, "launch");
if (adapterSettings->exec() != QDialog::Accepted)
Expand Down
8 changes: 4 additions & 4 deletions ui/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ void GlobalDebuggerUI::SetupMenu(UIContext* context)
return;

bool firstLaunch = controller->IsFirstLaunch();
if (firstLaunch)
if (controller->ShouldShowAdapterSettingsForLaunch())
{
auto adapterSettings = new AdapterSettingsDialog(context->mainWindow(), controller, "launch");
if (adapterSettings->exec() != QDialog::Accepted)
Expand Down Expand Up @@ -859,7 +859,7 @@ void GlobalDebuggerUI::SetupMenu(UIContext* context)
if (!controller)
return;

if (controller->IsFirstAttach())
if (controller->ShouldShowAdapterSettingsForAttach())
{
auto adapterSettings = new AdapterSettingsDialog(context->mainWindow(), controller, "attach");
if (adapterSettings->exec() != QDialog::Accepted)
Expand Down Expand Up @@ -1074,7 +1074,7 @@ void GlobalDebuggerUI::SetupMenu(UIContext* context)
if (!controller)
return;

if (controller->IsFirstConnectToDebugServer())
if (controller->ShouldShowAdapterSettingsForConnectToDebugServer())
{
auto adapterSettings = new AdapterSettingsDialog(context->mainWindow(), controller, "debug_server");
if (adapterSettings->exec() != QDialog::Accepted)
Expand Down Expand Up @@ -1129,7 +1129,7 @@ void GlobalDebuggerUI::SetupMenu(UIContext* context)
if (!controller)
return;

if (controller->IsFirstConnect())
if (controller->ShouldShowAdapterSettingsForConnect())
{
auto adapterSettings = new AdapterSettingsDialog(context->mainWindow(), controller, "connect");
if (adapterSettings->exec() != QDialog::Accepted)
Expand Down