Windows service not working (win 11)
It used to work a while back, can't say if something changed in Windows or code. Starting as service will throw error, since it will be checking for sphere.ini in C:\Windows\System32 instead of actual sphere directory. I guess the part with changing directory in WinMain doesn't work.
Tested on Windows 11 [Version 10.0.26100.3775]
I've traced the issue here: https://github.com/Sphereserver/Source-X/commit/b9cf3e39194b5d9ad407573e5d89c613d9296bdc
And its not the directory change. I guess it has to be something with the linker forgetting to link stuff.
Do you have an output error, an exit code or anything to further investigating it?
Not yet, hopefully I can get something more usefull tomorrow. Its kinda hard to debug windows service. I was able to build before and after that commit, to check where it stopped working. From sphere I get "starting service (null) and thats it. Dispatching to service control seems ok.
During service installation SphereSvrX64_nightly.exe -k install I get error:
AppName SphereSvrX64_nightly.exe
AppVersion 1.1.0.4032
AppTimeStamp 681ee876
ModuleName ntdll.dll
ModuleVersion 10.0.26100.3912
ModuleTimeStamp bae89f93
ExceptionCode c0000005
FaultingOffset 0000000000062673
ProcessId 0xe974
ProcessCreationTime 0x1dbc3d000654aae
AppPath C:\sphereX\SphereSvrX64_nightly.exe
ModulePath C:\WINDOWS\SYSTEM32\ntdll.dll
IntegratorReportId 7dfcc54f-8123-498f-9add-ee00f8bc5908
PackageFullName
PackageRelativeAppId
Which I think is related to #1403, but service gets intalled. Log file contains:
08:26:Installing Service. (null)
08:26:Install OK Test (Sphere X)
When the service is started, it immediately shuts down with errors: A timeout was reached (30000 milliseconds) while waiting for the SphereServer - Test (Sphere X) service to connect. (Event ID 7009)
and second error from log (Event ID 7000):
The SphereServer - Test (Sphere X service failed to start due to the following error:
The service did not respond to the start or control request in a timely fashion.
The log file gets created in C:\Windows\System32\sphere2025-05-13.log with content:
Log date: 2025/05/13 08:30:43
08:30:ERROR:Can't find file 'sphere.ini' in any of the expected paths!.
If I modify the exe path with -I=path/to/ini argument in the service (for example with sc command: sc config "SphereServer - Test (Sphere X)" binPath= "C:\sphereX\SphereSvrX64_nightly -I=\"C:\sphereX\\""
Starting service doesn't die immediately, seems like it started loading. The ini file is loaded and the logfile gets created in proper directory, but service dies also.
Sphere log contains:
08:43:Starting Service. (null)
08:44:Starting Service. (null)
08:44:Starting Service. (null)
Windows event log = this is probably the culprit (Event ID 1000):
EventData
AppName SphereSvrX64_nightly.exe
AppVersion 1.1.0.4032
AppTimeStamp 681ee876
ModuleName ucrtbase.dll
ModuleVersion 10.0.26100.3912
ModuleTimeStamp bd96a17b
ExceptionCode c0000409
FaultingOffset 00000000000a4ace
ProcessId 0x1e08
ProcessCreationTime 0x1dbc3d264826d1e
AppPath C:\sphereX\SphereSvrX64_nightly.exe
ModulePath C:\WINDOWS\System32\ucrtbase.dll
IntegratorReportId 496daacd-2703-4071-a318-bce59456ed6e
PackageFullName
PackageRelativeAppId
And then log with Event ID 7031: The SphereServer - Test (Sphere X) service terminated unexpectedly. It has done this 1 time(s). The following corrective action will be taken in 10000 milliseconds: Restart the service.
By chance, any news on that?
I did some debugging:
Using latest dev nightly or debug:
15:30:Starting Service. (null)
15:30:CmdMainStart before service_table_entry (null) - logging test, ntservice.cpp#438
15:30:CmdMainStart after service_table_entry (null) - logging test, after SERVICE_TABLE_ENTRY dispatchTable[]
The service goes here: https://github.com/Sphereserver/Source-X/blob/758bfe78426ecf6d847e592535588f79c9532976/src/sphere/ntservice.cpp#L551 but does not leave the method, since I tried to log something after that and it didn't show in log.
It seems like it doesn't call CNTService::service_main, because I tried to log something there too, but it didnt show up anywhere.
I've been checking changes in https://github.com/Sphereserver/Source-X/issues/1399#issuecomment-2872963790, since this is the commit after which it stopped working, but I cannot figure it out.
Update: it goes all the way to main entry point https://github.com/Sphereserver/Source-X/blob/758bfe78426ecf6d847e592535588f79c9532976/src/sphere/ntservice.cpp#L222
So it seems there isnt really any issue in service file, but somewhere in Sphere_MainEntryPoint
Follow up: the first issue is this line: https://github.com/Sphereserver/Source-X/blob/7efe1722a51635f6694122d79b9284f9520c3b06/src/game/CServer.cpp#L443 If I remove it, it can move forward and next fail is here: https://github.com/Sphereserver/Source-X/blob/7efe1722a51635f6694122d79b9284f9520c3b06/src/game/CServerConfig.cpp#L5235
So it looks like the ADDTOCALLSTACK macro is the reason.
If I change the macro to #define ADDTOCALLSTACK(_function_) (void)0 it goes a lot more, but dies anyway on https://github.com/Sphereserver/Source-X/blob/7efe1722a51635f6694122d79b9284f9520c3b06/src/sphere/threads.cpp#L152
I think i got it, from memory. Addtocallstack adds the data in a struct attached to the abstractspherethread class. That thread class is added to threadholder when the thread context + entry point/first function call is created from sphere utilities. At that point in the code, no thread data exists. A solution would be to ditch all the addtocallstack for the service, otherwise we'll have to preallocate the context data even sooner
Or, re reading your comment, maybe the service is skipping that part (that should happen in the Windows entry point, the "winmain" function)
I'll update and post debug log I'm using, so it will show which steps it takes and where it dies
Logs:
this is first bug in ntservice.cpp - if (0 == _chdir(szPath)). The condition should be negated: sphere_condition.txt
this is log when running service file with -I parameter sc config "SphereServer - Test (Sphere X)" binPath= "C:\sphereX\SphereSvrX64_nightly -I=\"C:\sphereX\\"": sphere_service.txt
this is log when running service file without -I parameter sc config "SphereServer - Test (Sphere X)" binPath= "C:\sphereX\SphereSvrX64_nightly": sphere_noparam.txt
With or without param are mostly the same, only without param it searches for config. The logs might not be written in order, since I've just coppied logging function, but it should give you insight how it goes.