From 0f58f2385364d6de826aeaca45e9d1b1d54487b9 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Thu, 16 Jul 2026 10:53:28 +0800 Subject: [PATCH] Destroy the network-plugin agent before unloading its DLL A network-plugin hot reload unloaded the DLL without destroying the agent handle it created, so the plugin's m_agent was left dangling into freed memory. On reload create_agent() short-circuited on has_agent() and kept the stale handle, and the next call into the new DLL (install_device_cert from the device-refresh timer) dereferenced it and crashed with an access violation. unload() now destroys the agent first, so a reload always gets a fresh handle. --- src/slic3r/Utils/BBLNetworkPlugin.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/slic3r/Utils/BBLNetworkPlugin.cpp b/src/slic3r/Utils/BBLNetworkPlugin.cpp index 8e531eb990..3d44dbcdb4 100644 --- a/src/slic3r/Utils/BBLNetworkPlugin.cpp +++ b/src/slic3r/Utils/BBLNetworkPlugin.cpp @@ -46,8 +46,7 @@ BBLNetworkPlugin::BBLNetworkPlugin() = default; BBLNetworkPlugin::~BBLNetworkPlugin() { - destroy_agent(); - unload(); + unload(); // unload() destroys the agent first (see the note there) } // ============================================================================ @@ -187,6 +186,13 @@ int BBLNetworkPlugin::initialize(bool using_backup, const std::string& version) int BBLNetworkPlugin::unload() { + // Orca: destroy the plugin agent while its creating DLL is still loaded, so the void* handle + // never dangles into freed memory. Skipping this makes a network-plugin hot reload (unload + + // reload) crash: the stale m_agent survives the unload, create_agent() then short-circuits on + // has_agent() and keeps the dangling old-DLL handle, and the next call into the freshly loaded + // DLL (e.g. install_device_cert from the device-refresh timer) dereferences it -> access violation. + destroy_agent(); + UnloadFTModule(); #if defined(_MSC_VER) || defined(_WIN32) @@ -250,6 +256,7 @@ std::string BBLNetworkPlugin::get_version() const void* BBLNetworkPlugin::create_agent(const std::string& log_dir) { if (m_agent) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": reusing existing agent " << m_agent; return m_agent; } @@ -257,6 +264,7 @@ void* BBLNetworkPlugin::create_agent(const std::string& log_dir) m_agent = m_create_agent(log_dir); } + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": created agent " << m_agent; return m_agent; }