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 "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
|
#ifdef SYSAPI_UNIX
|
||||||
|
|
||||||
|
|
@ -24,7 +30,18 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
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);
|
return app.run(__argc, __argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
#include "deskflow/DaemonApp.h"
|
#include "deskflow/DaemonApp.h"
|
||||||
|
|
||||||
#include "arch/XArch.h"
|
#include "arch/XArch.h"
|
||||||
#include "base/EventQueue.h"
|
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "base/TMethodEventJob.h"
|
#include "base/TMethodEventJob.h"
|
||||||
#include "base/log_outputters.h"
|
#include "base/log_outputters.h"
|
||||||
|
|
@ -96,7 +95,7 @@ int winMainLoopStatic(int, const char **)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DaemonApp::DaemonApp()
|
DaemonApp::DaemonApp(IEventQueue *events) : m_events(events)
|
||||||
{
|
{
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
}
|
}
|
||||||
|
|
@ -108,22 +107,11 @@ DaemonApp::~DaemonApp()
|
||||||
|
|
||||||
int DaemonApp::run(int argc, char **argv)
|
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;
|
bool uninstall = false;
|
||||||
try {
|
try {
|
||||||
// default log level to system setting.
|
// default log level to system setting.
|
||||||
if (string logLevel = arch.setting("LogLevel"); logLevel != "")
|
if (string logLevel = ARCH->setting("LogLevel"); logLevel != "")
|
||||||
log.setFilter(logLevel.c_str());
|
CLOG->setFilter(logLevel.c_str());
|
||||||
|
|
||||||
bool foreground = false;
|
bool foreground = false;
|
||||||
|
|
||||||
|
|
@ -137,11 +125,11 @@ int DaemonApp::run(int argc, char **argv)
|
||||||
else if (arg == "/install") {
|
else if (arg == "/install") {
|
||||||
LOG((CLOG_PRINT "installing windows daemon"));
|
LOG((CLOG_PRINT "installing windows daemon"));
|
||||||
uninstall = true;
|
uninstall = true;
|
||||||
arch.installDaemon();
|
ARCH->installDaemon();
|
||||||
return kExitSuccess;
|
return kExitSuccess;
|
||||||
} else if (arg == "/uninstall") {
|
} else if (arg == "/uninstall") {
|
||||||
LOG((CLOG_PRINT "uninstalling windows daemon"));
|
LOG((CLOG_PRINT "uninstalling windows daemon"));
|
||||||
arch.uninstallDaemon();
|
ARCH->uninstallDaemon();
|
||||||
return kExitSuccess;
|
return kExitSuccess;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -157,7 +145,7 @@ int DaemonApp::run(int argc, char **argv)
|
||||||
if (!foreground) {
|
if (!foreground) {
|
||||||
// Only use MS debug outputter when the process is daemonized, since stdout won't be accessible
|
// 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.
|
// 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
|
#endif
|
||||||
|
|
||||||
|
|
@ -170,10 +158,10 @@ int DaemonApp::run(int argc, char **argv)
|
||||||
} else {
|
} else {
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
LOG((CLOG_PRINT "daemonizing windows service"));
|
LOG((CLOG_PRINT "daemonizing windows service"));
|
||||||
arch.daemonize(kAppName, winMainLoopStatic);
|
ARCH->daemonize(kAppName, winMainLoopStatic);
|
||||||
#elif SYSAPI_UNIX
|
#elif SYSAPI_UNIX
|
||||||
LOG((CLOG_PRINT "daemonizing unix service"));
|
LOG((CLOG_PRINT "daemonizing unix service"));
|
||||||
arch.daemonize(kAppName, unixMainLoopStatic);
|
ARCH->daemonize(kAppName, unixMainLoopStatic);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,7 +202,7 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground)
|
||||||
SocketMultiplexer multiplexer;
|
SocketMultiplexer multiplexer;
|
||||||
|
|
||||||
// uses event queue, must be created here.
|
// 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.
|
// send logging to gui via ipc, log system adopts outputter.
|
||||||
m_ipcLogOutputter = std::make_unique<IpcLogOutputter>(*m_ipcServer, IpcClientType::GUI, true);
|
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
|
#if SYSAPI_WIN32
|
||||||
|
|
||||||
// install the platform event queue to handle service stop events.
|
// 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");
|
std::string command = ARCH->setting("Command");
|
||||||
bool elevate = ARCH->setting("Elevate") == "1";
|
bool elevate = ARCH->setting("Elevate") == "1";
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class DaemonApp
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DaemonApp();
|
DaemonApp(IEventQueue *events);
|
||||||
~DaemonApp();
|
~DaemonApp();
|
||||||
int run(int argc, char **argv);
|
int run(int argc, char **argv);
|
||||||
void mainLoop(bool logToFile, bool foreground = false);
|
void mainLoop(bool logToFile, bool foreground = false);
|
||||||
|
|
@ -46,6 +46,6 @@ public:
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IpcServer> m_ipcServer;
|
std::unique_ptr<IpcServer> m_ipcServer;
|
||||||
std::unique_ptr<IpcLogOutputter> m_ipcLogOutputter;
|
std::unique_ptr<IpcLogOutputter> m_ipcLogOutputter;
|
||||||
std::unique_ptr<IEventQueue> m_events;
|
IEventQueue *m_events = nullptr;
|
||||||
FileLogOutputter *m_fileLogOutputter = nullptr;
|
FileLogOutputter *m_fileLogOutputter = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue