fix: Prevent access violation by moving events, arch, and log objects to top of stack in Windows daemon

This is how we do it in the server/client apps, so it makes sense to mirror the same pattern.
This commit is contained in:
Nick Bolton 2025-02-28 12:46:12 +00:00
parent 383b39636e
commit 0fc5368253
3 changed files with 31 additions and 26 deletions

View file

@ -7,7 +7,13 @@
#include "deskflow/DaemonApp.h"
#include <iostream>
#include "arch/Arch.h"
#include "base/EventQueue.h"
#include "base/Log.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
#endif
#ifdef SYSAPI_UNIX
@ -24,7 +30,18 @@ int main(int argc, char **argv)
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
DaemonApp app;
#if SYSAPI_WIN32
// win32 instance needed for threading, etc.
ArchMiscWindows::setInstanceWin32(GetModuleHandle(nullptr));
#endif
Arch arch;
arch.init();
Log log;
EventQueue events;
DaemonApp app(&events);
return app.run(__argc, __argv);
}

View file

@ -10,7 +10,6 @@
#include "deskflow/DaemonApp.h"
#include "arch/XArch.h"
#include "base/EventQueue.h"
#include "base/Log.h"
#include "base/TMethodEventJob.h"
#include "base/log_outputters.h"
@ -96,7 +95,7 @@ int winMainLoopStatic(int, const char **)
}
#endif
DaemonApp::DaemonApp()
DaemonApp::DaemonApp(IEventQueue *events) : m_events(events)
{
s_instance = this;
}
@ -108,22 +107,11 @@ DaemonApp::~DaemonApp()
int DaemonApp::run(int argc, char **argv)
{
#if SYSAPI_WIN32
// win32 instance needed for threading, etc.
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif
Arch arch;
arch.init();
Log log;
m_events = std::make_unique<EventQueue>();
bool uninstall = false;
try {
// default log level to system setting.
if (string logLevel = arch.setting("LogLevel"); logLevel != "")
log.setFilter(logLevel.c_str());
if (string logLevel = ARCH->setting("LogLevel"); logLevel != "")
CLOG->setFilter(logLevel.c_str());
bool foreground = false;
@ -137,11 +125,11 @@ int DaemonApp::run(int argc, char **argv)
else if (arg == "/install") {
LOG((CLOG_PRINT "installing windows daemon"));
uninstall = true;
arch.installDaemon();
ARCH->installDaemon();
return kExitSuccess;
} else if (arg == "/uninstall") {
LOG((CLOG_PRINT "uninstalling windows daemon"));
arch.uninstallDaemon();
ARCH->uninstallDaemon();
return kExitSuccess;
}
#endif
@ -157,7 +145,7 @@ int DaemonApp::run(int argc, char **argv)
if (!foreground) {
// Only use MS debug outputter when the process is daemonized, since stdout won't be accessible
// in that case, but is accessible when running in the foreground.
log.insert(new MSWindowsDebugOutputter()); // NOSONAR -- Adopted by `Log`
CLOG->insert(new MSWindowsDebugOutputter()); // NOSONAR -- Adopted by `Log`
}
#endif
@ -170,10 +158,10 @@ int DaemonApp::run(int argc, char **argv)
} else {
#if SYSAPI_WIN32
LOG((CLOG_PRINT "daemonizing windows service"));
arch.daemonize(kAppName, winMainLoopStatic);
ARCH->daemonize(kAppName, winMainLoopStatic);
#elif SYSAPI_UNIX
LOG((CLOG_PRINT "daemonizing unix service"));
arch.daemonize(kAppName, unixMainLoopStatic);
ARCH->daemonize(kAppName, unixMainLoopStatic);
#endif
}
@ -214,7 +202,7 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground)
SocketMultiplexer multiplexer;
// uses event queue, must be created here.
m_ipcServer = std::make_unique<IpcServer>(m_events.get(), &multiplexer);
m_ipcServer = std::make_unique<IpcServer>(m_events, &multiplexer);
// send logging to gui via ipc, log system adopts outputter.
m_ipcLogOutputter = std::make_unique<IpcLogOutputter>(*m_ipcServer, IpcClientType::GUI, true);
@ -235,7 +223,7 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground)
#if SYSAPI_WIN32
// install the platform event queue to handle service stop events.
m_events->adoptBuffer(new MSWindowsEventQueueBuffer(m_events.get()));
m_events->adoptBuffer(new MSWindowsEventQueueBuffer(m_events));
std::string command = ARCH->setting("Command");
bool elevate = ARCH->setting("Elevate") == "1";

View file

@ -25,7 +25,7 @@ class DaemonApp
{
public:
DaemonApp();
DaemonApp(IEventQueue *events);
~DaemonApp();
int run(int argc, char **argv);
void mainLoop(bool logToFile, bool foreground = false);
@ -46,6 +46,6 @@ public:
private:
std::unique_ptr<IpcServer> m_ipcServer;
std::unique_ptr<IpcLogOutputter> m_ipcLogOutputter;
std::unique_ptr<IEventQueue> m_events;
IEventQueue *m_events = nullptr;
FileLogOutputter *m_fileLogOutputter = nullptr;
};