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:
parent
383b39636e
commit
0fc5368253
3 changed files with 31 additions and 26 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue