On 26.9.2014 09:26, Pritesh Acharya wrote:
Details: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.
OS: Windows Server 2008 SP2
Boost 1.56.0 (shared library)
OpenSSL: Win32OpenSSL-1_0_1i
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 loggingboost::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 serviceStartServiceCtrlDispatcher(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 failedreturn;}// Initialize Service//error = InitService();error = 0;if (error){// Initialization failedServiceStatus.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 initializationint InitService(){int result;result = WriteToLog("Monitoring started.");return(result);}
// Control handler functionvoid 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 statusSetServiceStatus (hStatus, &ServiceStatus);return;}
2. Dump
Dump Summary------------Dump File: with_ssl_56.exe.4208.dmp : C:\Dumps\with_ssl_56.exe.4208.dmpLast Write Time: 9/26/2014 11:59:38 AMProcess Name: with_ssl_56.exe : C:\lpa_c\wix_for_service\build_win\src\with_ssl_56\Debug\with_ssl_56.exeProcess Architecture: x86Exception Code: 0xC0000005Exception 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.6002CLR Version(s):
Modules-------Module Name Module Path Module Version----------- ----------- --------------with_ssl_56.exe C:\lpa_c\wix_for_service\build_win\src\with_ssl_56\Debug\with_ssl_56.exe 0.0.0.0ntdll.dll C:\Windows\System32\ntdll.dll 6.0.6002.18881kernel32.dll C:\Windows\System32\kernel32.dll 6.0.6002.19034advapi32.dll C:\Windows\System32\advapi32.dll 6.0.6002.18005rpcrt4.dll C:\Windows\System32\rpcrt4.dll 6.0.6002.18882boost_log-vc100-mt-gd-1_56.dll C:\boost_1_56_0_dyn\stage\lib\boost_log-vc100-mt-gd-1_56.dll 0.0.0.0boost_date_time-vc100-mt-gd-1_56.dll C:\boost_1_56_0_dyn\stage\lib\boost_date_time-vc100-mt-gd-1_56.dll 0.0.0.0MSVCP100D.dll C:\Windows\System32\MSVCP100D.dll 10.0.30319.1MSVCR100D.dll C:\Windows\System32\MSVCR100D.dll 10.0.30319.1boost_system-vc100-mt-gd-1_56.dll C:\boost_1_56_0_dyn\stage\lib\boost_system-vc100-mt-gd-1_56.dll 0.0.0.0boost_filesystem-vc100-mt-gd-1_56.dll C:\boost_1_56_0_dyn\stage\lib\boost_filesystem-vc100-mt-gd-1_56.dll 0.0.0.0boost_chrono-vc100-mt-gd-1_56.dll C:\boost_1_56_0_dyn\stage\lib\boost_chrono-vc100-mt-gd-1_56.dll 0.0.0.0boost_thread-vc100-mt-gd-1_56.dll C:\boost_1_56_0_dyn\stage\lib\boost_thread-vc100-mt-gd-1_56.dll 0.0.0.0psapi.dll C:\Windows\System32\psapi.dll 6.0.6000.16386ws2_32.dll C:\Windows\System32\ws2_32.dll 6.0.6001.18000msvcrt.dll C:\Windows\System32\msvcrt.dll 7.0.6002.18551nsi.dll C:\Windows\System32\nsi.dll 6.0.6001.18000user32.dll C:\Windows\System32\user32.dll 6.0.6002.18005gdi32.dll C:\Windows\System32\gdi32.dll 6.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 Cboost_log-vc100-mt-gd-1_56.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 284 + 0xf bytes Cboost_log-vc100-mt-gd-1_56.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 506 + 0x11 bytes Cboost_log-vc100-mt-gd-1_56.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 476 + 0x11 bytes Cntdll.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
.
--
VZ