Boost logo

Boost Users :

Subject: Re: [Boost-users] [Log] [ASIO with ssl] windows service crash on windows server 2008
From: Václav Zeman (vhaisman_at_[hidden])
Date: 2014-09-27 18:55:34


On 26.9.2014 09:26, Pritesh Acharya wrote:

> Details:
> OS: Windows Server 2008 SP2
> Boost 1.56.0 (shared library)
> OpenSSL: Win32OpenSSL-1_0_1i
>
> I have a windows service application written in C++. As a minimal test
> case, I have created a small demo code to show the problem. The
> service just log some information to a file and does nothing.
> The same code has no problem in my Development machine(windows7) and
> window Server 2003.
> Also on Windows Server 2008, when the service is run as LocalSystem
> privilege, it crashes, but when run as Administrator it works.
>
> Additionally, when I remove the asio ssl header from the code, it works.
> or when I remove the log header, it works. The problem seems to be
> related to when ASIO ssl and LOG are used together.
>
> Below I've included
> 1. Code
> 2. User Mode Crash dump
> 3. Call Stack obtained from running Crash Dump
>
> *1. Code:*
>
>
> /#include <boost/log/trivial.hpp>/
> /#include <boost/log/sources/severity_logger.hpp>/
> /#include <boost/asio/ssl.hpp>/
> /#include <windows.h>/
> /#include <stdio.h>/
> /
> /
> /#define SLEEP_TIME 5000/
> /#define LOGFILE "C:\\AASSLInstaller_D_56\\memstatus.txt"/
> /
> /
> /SERVICE_STATUS ServiceStatus; /
> /SERVICE_STATUS_HANDLE hStatus; /
> / /
> /void ServiceMain(int argc, char** argv); /
> /void ControlHandler(DWORD request); /
> /int InitService();/
> /
> /
> /int WriteToLog(char* str)/
> /{/
> / FILE* log;/
> / log = fopen(LOGFILE, "a+");/
> / if (log == NULL)/
> / return -1;/
> / fprintf(log, "%s\n", str);/
> / fclose(log);/
> / return 0;/
> /}/
> /
> /
> ///void ThreadFunction()/
> ///{/
> /// WriteToLog("at ThreadFunction");/
> /// //std::cout << "hello World " << std::endl;/
> /// //getchar();/
> ///}/
> /
> /
> /int main() /
> /{ /
> / using namespace boost::log::trivial; //for logging/
> / boost::log::sources::severity_logger_mt<
> boost::log::trivial::severity_level > lg;/
> / //WriteToLog("at main");/
> / //return 1;/
> / SERVICE_TABLE_ENTRY ServiceTable[2];/
> / ServiceTable[0].lpServiceName = "MemoryStatus";/
> / ServiceTable[0].lpServiceProc =
> (LPSERVICE_MAIN_FUNCTION)ServiceMain;/
> /
> /
> / ServiceTable[1].lpServiceName = NULL;/
> / ServiceTable[1].lpServiceProc = NULL;/
> / // Start the control dispatcher thread for our service/
> / StartServiceCtrlDispatcher(ServiceTable); /
> / return 0;/
> /}/
> /
> /
> /
> /
> /void ServiceMain(int argc, char** argv) /
> /{ /
> / int error; /
> / /
> / ServiceStatus.dwServiceType = SERVICE_WIN32; /
> / ServiceStatus.dwCurrentState = SERVICE_START_PENDING; /
> / ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
> SERVICE_ACCEPT_SHUTDOWN;/
> / ServiceStatus.dwWin32ExitCode = 0; /
> / ServiceStatus.dwServiceSpecificExitCode = 0; /
> / ServiceStatus.dwCheckPoint = 0; /
> / ServiceStatus.dwWaitHint = 0; /
> / /
> / hStatus = RegisterServiceCtrlHandler(/
> / "MemoryStatus", /
> / (LPHANDLER_FUNCTION)ControlHandler); /
> / if (hStatus == (SERVICE_STATUS_HANDLE)0) /
> / { /
> / // Registering Control Handler failed/
> / return; /
> / } /
> / // Initialize Service /
> / //error = InitService(); /
> / error = 0;/
> / if (error) /
> / {/
> / // Initialization failed/
> / ServiceStatus.dwCurrentState = SERVICE_STOPPED; /
> / ServiceStatus.dwWin32ExitCode = -1; /
> / SetServiceStatus(hStatus, &ServiceStatus); /
> / return; /
> / } /
> / // We report the running status to SCM. /
> / ServiceStatus.dwCurrentState = SERVICE_RUNNING; /
> / SetServiceStatus (hStatus, &ServiceStatus);/
> / /
> / MEMORYSTATUS memory;/
> / // The worker loop of a service/
> / //boost::thread t(&ThreadFunction);/
> / while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)/
> / {/
> / char buffer[16];/
> / GlobalMemoryStatus(&memory);/
> / sprintf(buffer, "%d", memory.dwAvailPhys);/
> / int result = WriteToLog(buffer);/
> / if (result)/
> / {/
> / ServiceStatus.dwCurrentState = SERVICE_STOPPED; /
> / ServiceStatus.dwWin32ExitCode = -1; /
> / SetServiceStatus(hStatus, &ServiceStatus);/
> / return;/
> / }/
> /
> /
> / Sleep(SLEEP_TIME);/
> / }/
> / return; /
> /}/
> / /
> /// Service initialization/
> /int InitService() /
> /{ /
> / int result;/
> / result = WriteToLog("Monitoring started.");/
> / return(result); /
> /} /
> /
> /
> /// Control handler function/
> /void ControlHandler(DWORD request) /
> /{ /
> / switch(request) /
> / { /
> / case SERVICE_CONTROL_STOP: /
> / WriteToLog("Monitoring stopped.");/
> /
> /
> / ServiceStatus.dwWin32ExitCode = 0; /
> / ServiceStatus.dwCurrentState = SERVICE_STOPPED; /
> / SetServiceStatus (hStatus, &ServiceStatus);/
> / return; /
> / /
> / case SERVICE_CONTROL_SHUTDOWN: /
> / WriteToLog("Monitoring stopped.");/
> /
> /
> / ServiceStatus.dwWin32ExitCode = 0; /
> / ServiceStatus.dwCurrentState = SERVICE_STOPPED; /
> / SetServiceStatus (hStatus, &ServiceStatus);/
> / return; /
> / /
> / default:/
> / break;/
> / } /
> / /
> / // Report current status/
> / SetServiceStatus (hStatus, &ServiceStatus);/
> / /
> / return; /
> /} /
> /
> /
> *2. Dump*
>
>
> /Dump Summary/
> /------------/
> /Dump File:with_ssl_56.exe.4208.dmp : C:\Dumps\with_ssl_56.exe.4208.dmp/
> /Last Write Time:9/26/2014 11:59:38 AM/
> /Process Name:with_ssl_56.exe :
> C:\lpa_c\wix_for_service\build_win\src\with_ssl_56\Debug\with_ssl_56.exe/
> /Process Architecture:x86/
> /Exception Code:0xC0000005/
> /Exception Information:The thread tried to read from or write to a
> virtual address for which it does not have the appropriate access./
> /Heap Information:Not Present/
> /
> /
> /System Information/
> /------------------/
> /OS Version:6.0.6002/
> /CLR Version(s):/
> /
> /
> /Modules/
> /-------/
> /Module NameModule PathModule Version/
> /------------------------------------/
> /with_ssl_56.exeC:\lpa_c\wix_for_service\build_win\src\with_ssl_56\Debug\with_ssl_56.exe0.0.0.0/
> /ntdll.dllC:\Windows\System32\ntdll.dll6.0.6002.18881/
> /kernel32.dllC:\Windows\System32\kernel32.dll6.0.6002.19034/
> /advapi32.dllC:\Windows\System32\advapi32.dll6.0.6002.18005/
> /rpcrt4.dllC:\Windows\System32\rpcrt4.dll6.0.6002.18882/
> /boost_log-vc100-mt-gd-1_56.dllC:\boost_1_56_0_dyn\stage\lib\boost_log-vc100-mt-gd-1_56.dll0.0.0.0/
> /boost_date_time-vc100-mt-gd-1_56.dllC:\boost_1_56_0_dyn\stage\lib\boost_date_time-vc100-mt-gd-1_56.dll0.0.0.0/
> /MSVCP100D.dllC:\Windows\System32\MSVCP100D.dll10.0.30319.1/
> /MSVCR100D.dllC:\Windows\System32\MSVCR100D.dll10.0.30319.1/
> /boost_system-vc100-mt-gd-1_56.dllC:\boost_1_56_0_dyn\stage\lib\boost_system-vc100-mt-gd-1_56.dll0.0.0.0/
> /boost_filesystem-vc100-mt-gd-1_56.dllC:\boost_1_56_0_dyn\stage\lib\boost_filesystem-vc100-mt-gd-1_56.dll0.0.0.0/
> /boost_chrono-vc100-mt-gd-1_56.dllC:\boost_1_56_0_dyn\stage\lib\boost_chrono-vc100-mt-gd-1_56.dll0.0.0.0/
> /boost_thread-vc100-mt-gd-1_56.dllC:\boost_1_56_0_dyn\stage\lib\boost_thread-vc100-mt-gd-1_56.dll0.0.0.0/
> /psapi.dllC:\Windows\System32\psapi.dll6.0.6000.16386/
> /ws2_32.dllC:\Windows\System32\ws2_32.dll6.0.6001.18000/
> /msvcrt.dllC:\Windows\System32\msvcrt.dll7.0.6002.18551/
> /nsi.dllC:\Windows\System32\nsi.dll6.0.6001.18000/
> /user32.dllC:\Windows\System32\user32.dll6.0.6002.18005/
> /gdi32.dllC:\Windows\System32\gdi32.dll6.0.6002.19171/
>
> *3. Call Stack*
> / 00000000() /
> / user32.dll!76659ce4() /
> / [Frames below may be incorrect and/or missing, no symbols loaded
> for user32.dll] /
> / advapi32.dll!77b84158() /
> / advapi32.dll!77b840f6() /
> / advapi32.dll!77b8430d() /
> / ws2_32.dll!7670ab6d() /
> / ws2_32.dll!7670aa95() /
> / ws2_32.dll!7670a3b2() /
> / ws2_32.dll!7670ae3f() /
> / ws2_32.dll!7670ad7a() /
> / ws2_32.dll!7670acc3() /
> / ws2_32.dll!7670ac2b() /
> /
> boost_log-vc100-mt-gd-1_56.dll!boost::asio::detail::winsock_init_base::startup(boost::asio::detail::winsock_init_base::data
> & d, unsigned char major, unsigned char minor) Line 39 + 0x2d bytes C++/
> /
> boost_log-vc100-mt-gd-1_56.dll!boost::asio::detail::winsock_init<2,0>::winsock_init<2,0>(bool
> allow_throw) Line 57 + 0xe bytes C++/
> /> boost_log-vc100-mt-gd-1_56.dll!boost::asio::detail::`dynamic
> initializer for 'winsock_init_instance''() Line 116 + 0x1c bytes C++/
> / MSVCR100D.dll!_initterm(void (void)* * pfbegin, void (void)* *
> pfend) Line 873 C/
> / boost_log-vc100-mt-gd-1_56.dll!_CRT_INIT(void * hDllHandle,
> unsigned long dwReason, void * lpreserved) Line 284 + 0xf bytes C/
> / boost_log-vc100-mt-gd-1_56.dll!__DllMainCRTStartup(void *
> hDllHandle, unsigned long dwReason, void * lpreserved) Line 506 +
> 0x11 bytes C/
> / boost_log-vc100-mt-gd-1_56.dll!_DllMainCRTStartup(void *
> hDllHandle, unsigned long dwReason, void * lpreserved) Line 476 +
> 0x11 bytes C/
> / ntdll.dll!77a112f4() /
> / ntdll.dll!779f906b() /
> / ntdll.dll!77a016d2() /
> / ntdll.dll!779fbf5a() /
>
It seems wrong to initialize WinSock from |DllMain()| context. This is
WAG, but try using the manual initialization of ASIO/WinSock in
|ServiceMain()|. See the comment above |class manual|
<http://www.boost.org/doc/libs/1_56_0/boost/asio/detail/winsock_init.hpp>.

-- 
VZ
​





Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net