I have a Windows service that is written in C++. I recently became aware of the Microsoft Application Verifier Tool that can be used to catch not so obvious memory leaks and other such problems.
I've discovered that if I turn on all the checks in Application Verifier, my service will always crash. After a bunch of debugging, I figured out it's specifically the logging framework that is causing the crashes.
I came up with a simple reproducible example which is not a service, but just a simple application using the POCO logging framework. I also did one with Boost, just to compare.
POCO:
#include <Poco/Logger.h>
#include <Poco/ConsoleChannel.h>
#include <Poco/AutoPtr.h>
#include <Poco/FormattingChannel.h>
#include <Poco/PatternFormatter.h>
int main(int argc, char* argv[])
{
using namespace Poco;
// Create a formatter that shows timestamp, priority and message
AutoPtr<PatternFormatter> formatter = new PatternFormatter;
formatter->setProperty("pattern", "%Y-%m-%d %H:%M:%S [%p] %t");
// Wrap the console channel in a formatting channel
AutoPtr<FormattingChannel> formattingChannel = new FormattingChannel(formatter, new ConsoleChannel);
formattingChannel->open();
// Create and configure the logger
Logger& logger = Logger::get("MainLogger");
logger.setChannel(formattingChannel);
logger.setLevel(Message::PRIO_INFORMATION);
for (;;)
{
// Log some messages
logger.information("This is an informational message.");
logger.warning("This is a warning message.");
logger.error("This is an error message.");
Sleep(1000);
}
return 0;
}
Boost:
#include <iostream>
#include <boost/log/trivial.hpp>
int main(int argc, char* argv[])
{
for (;;)
{
BOOST_LOG_TRIVIAL(info) << "This is an informational severity message";
Sleep(1000);
}
return 0;
}
I've discovered that neither of them will run successfully with all the App Verifier tests turned on. For the POCO example, I only have to turn off the Low Resource Simulation, but for the boost example, I have to turn off both the Low Resource Simulation and Networking before it'll run reliably.
I'm not sure what this means. Should I avoid logging frameworks in order to keep my service reliable, or is this to be expected?
I've discovered that if I turn on all the checks in Application Verifier, my service will always crash. After a bunch of debugging, I figured out it's specifically the logging framework that is causing the crashes.
Going by your Boost reproducer¹, and taking "if I turn on all the checks in Application Verifier" literally, I think you're seeing the obvious result of emulating low-memory conditions:
Indeed, you will note that if you use "Enable All Tests" menu item it will NOT enable this test, because it will lead to errors. In this case, Log frameworks are throwing
std::bad_alloc
exceptions because Heap allocations are "failing". Because you asked AppVerifier to.
¹ Boost 1.86.0, MSVC (VS 17.7)