I am currently working on a windows service implementation. I have installed my service application manually and when I start it, it crashes. The crash happens when registering the service's main entry point by using the following WINAPI function:
StartServiceCtrlDispatcher(cast[LPSERVICE_TABLE_ENTRY](addr arr[0]))
The crash only occurs when I compile with --threads:on. Omitting --threads:on results in the callback being called by windows' service manager as expected.
I wrote a simple test program which doesn't use any thread stuff. It is not a real service as it is missing some crucial parts, but it shows if the callback serviceMain is called:
import windows
import os
import streams
proc getFullLogFilename(): string =
let (dir, name, ext) = splitFile(getAppFilename())
result = dir / name & ".log"
proc logMe(msg: string) =
var fm = if fileExists(getFullLogFilename()): fmAppend else: fmReadWrite
var fs = newFileStream(getFullLogFilename(), fm)
if fs != nil:
try:
fs.writeln(msg)
fs.flush()
finally:
fs.close()
# callback called by windows
proc serviceMain(para1: DWORD, para2: LPTSTR) {.stdcall.} =
setupForeignThreadGc()
logMe("serviceMain entered")
proc main() =
var
arr: array[0..1, SERVICE_TABLE_ENTRY]
str = newWideCString("SCLogService")
logMe("main entered")
arr[0].lpServiceName = cast[LPTSTR](addr str[0])
arr[0].lpServiceProc = serviceMain
# register the callback procedure serviceMain
if StartServiceCtrlDispatcher(addr arr[0]) == 0:
logMe("StartServiceCtrlDispatcher failed")
when isMainModule:
main()
Does anyone have a clue why the service crashes when compiled with threading support?
flaviu had some good advice on how to use gdb with a windows service and so we managed to get some stacktraces. However, I am not sure if I did everything correct.
Compiled with: nim c --threads:on --lineDir:on --debuginfo pcelogservice.nim
(gdb) step 10 Single stepping until exit from function ntdll!LdrFindResource_U, which has no line number information. Single stepping until exit from function ntdll!RtlQueryTimeZoneInformation, which has no line number information. Single stepping until exit from function ntdll!RtlQueryRegistryValues, which has no line number information. Single stepping until exit from function ntdll!isdigit, which has no line number information. [New Thread 13204.0x3bc0] [New Thread 13204.0x3138] [New Thread 13204.0x3af4] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 13204.0x3af4] 0x0042efe6 in nimFrame () (gdb) bt #0 0x0042efe6 in nimFrame () #1 0x0042f4be in servicemain_190048@8 () #2 0x761375a8 in SECHOST!I_ScIsSecurityProcess () from C:\Windows\SysWOW64\sechost.dll #3 0x00000001 in ?? () #4 0x00ce0328 in ?? () #5 0x7643338a in KERNEL32!BaseCleanupAppcompatCacheSupport () from C:\Windows\syswow64\kernel32.dll #6 0x0198ffd4 in ?? () #7 0x77b39f72 in ntdll!RtlpNtSetValueKey () from C:\Windows\SysWOW64\ntdll.dll #8 0x00ce0318 in ?? () #9 0x77b39f45 in ntdll!RtlpNtSetValueKey () from C:\Windows\SysWOW64\ntdll.dll #10 0x76137587 in SECHOST!I_ScIsSecurityProcess () from C:\Windows\SysWOW64\sechost.dll #11 0x00ce0318 in ?? () #12 0x00000000 in ?? () (gdb)
Compiled with: nim c --threads:on --lineDir:on --debuginfo -d:release pcelogservice.nim
(gdb) step 10 Single stepping until exit from function ntdll!LdrFindResource_U, which has no line number information. Single stepping until exit from function ntdll!RtlQueryTimeZoneInformation, which has no line number information. Single stepping until exit from function ntdll!RtlQueryRegistryValues, which has no line number information. Single stepping until exit from function ntdll!isdigit, which has no line number information. [New Thread 15280.0x3ba0] [New Thread 15280.0x3a60] [New Thread 15280.0x3784] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 15280.0x3784] 0x00403dad in alloc_6001 () (gdb) bt #0 0x00403dad in alloc_6001 () #1 0x00401fe0 in stdlib_strutilsDatInit () #2 0x0040fb97 in PreMainInner () at pcelogservice.nim:6 #3 0x0040fd9d in servicemain_190048@8 () at pcelogservice.nim:22 #4 0x761375a8 in SECHOST!I_ScIsSecurityProcess () from C:\Windows\SysWOW64\sechost.dll #5 0x00000001 in ?? () #6 0x007d9b30 in ?? () #7 0x7643338a in KERNEL32!BaseCleanupAppcompatCacheSupport () from C:\Windows\syswow64\kernel32.dll #8 0x0103ffd4 in ?? () #9 0x77b39f72 in ntdll!RtlpNtSetValueKey () from C:\Windows\SysWOW64\ntdll.dll #10 0x007d9b20 in ?? () #11 0x77b39f45 in ntdll!RtlpNtSetValueKey () from C:\Windows\SysWOW64\ntdll.dll #12 0x76137587 in SECHOST!I_ScIsSecurityProcess () from C:\Windows\SysWOW64\sechost.dll #13 0x007d9b20 in ?? () #14 0x00000000 in ?? () (gdb)