aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfurszy <matiasfurszyfer@protonmail.com>2024-02-28 09:47:20 -0300
committerfurszy <matiasfurszyfer@protonmail.com>2024-02-28 17:58:47 -0300
commitf3a612f9016fe1f59c73d6059274bea8025b8940 (patch)
treee633a0fcae1e101b358b17f5779790ab2fba3d88 /src
parentba907f96ad37c09c49c0e1532fad118fcb8dd4a8 (diff)
gui: guard accessing a nullptr 'clientModel'
During shutdown, already queue events dispatched from the backend such 'numConnectionsChanged' and 'networkActiveChanged' could try to access the clientModel object, which might not exist because we manually delete it inside 'BitcoinApplication::requestShutdown()'.
Diffstat (limited to 'src')
-rw-r--r--src/qt/bitcoin.cpp5
-rw-r--r--src/qt/bitcoingui.cpp1
-rw-r--r--src/qt/clientmodel.cpp7
-rw-r--r--src/qt/clientmodel.h2
-rw-r--r--src/qt/rpcconsole.cpp1
5 files changed, 15 insertions, 1 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 33c305f0d4..b1a8461d02 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -372,6 +372,11 @@ void BitcoinApplication::requestShutdown()
// Request node shutdown, which can interrupt long operations, like
// rescanning a wallet.
node().startShutdown();
+ // Prior to unsetting the client model, stop listening backend signals
+ if (clientModel) {
+ clientModel->stop();
+ }
+
// Unsetting the client model can cause the current thread to wait for node
// to complete an operation, like wait for a RPC execution to complete.
window->setClientModel(nullptr);
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index ad80922c8b..5f132b817e 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -989,6 +989,7 @@ void BitcoinGUI::gotoLoadPSBT(bool from_clipboard)
void BitcoinGUI::updateNetworkState()
{
+ if (!clientModel) return;
int count = clientModel->getNumConnections();
QString icon;
switch(count)
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index c31e06e88e..bf4172a8bf 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -70,7 +70,7 @@ ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QO
subscribeToCoreSignals();
}
-ClientModel::~ClientModel()
+void ClientModel::stop()
{
unsubscribeFromCoreSignals();
@@ -78,6 +78,11 @@ ClientModel::~ClientModel()
m_thread->wait();
}
+ClientModel::~ClientModel()
+{
+ stop();
+}
+
int ClientModel::getNumConnections(unsigned int flags) const
{
ConnectionDirection connections = ConnectionDirection::None;
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 493e18a07d..68fb2e6322 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -58,6 +58,8 @@ public:
explicit ClientModel(interfaces::Node& node, OptionsModel *optionsModel, QObject *parent = nullptr);
~ClientModel();
+ void stop();
+
interfaces::Node& node() const { return m_node; }
OptionsModel *getOptionsModel();
PeerTableModel *getPeerTableModel();
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 4ef45490d9..d2b184ebdf 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -966,6 +966,7 @@ void RPCConsole::message(int category, const QString &message, bool html)
void RPCConsole::updateNetworkState()
{
+ if (!clientModel) return;
QString connections = QString::number(clientModel->getNumConnections()) + " (";
connections += tr("In:") + " " + QString::number(clientModel->getNumConnections(CONNECTIONS_IN)) + " / ";
connections += tr("Out:") + " " + QString::number(clientModel->getNumConnections(CONNECTIONS_OUT)) + ")";