0

If you ran a go app with Windows DLL dependencies on a slow hdd disk, it sometimes occurs that Windows takes too long to load those dll.

If you put your go app into a windows service you get serious problems.

Especially on slow hdd disks, this leads to windows service timeouts and the service will not start.

Is it somehow possible to link those DLLs statically to the go app?

Once the DLLs are loaded everything is fine, but it takes two attempts to get the service running.

But after the first failure, Windows won't try to start the service again, so I have to manually start the service by myself.

Anyone got some ideas?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Eric
  • 115
  • 1
  • 10
  • 1
    As a workaround can you extend the startup timeout when you register the service? – David Heffernan Aug 15 '18 at 09:01
  • yes this would be a workaround. but this service runs on many customer machines, and i dont know potential side effects of this :/ as i know, you can edit this just globally and not for a specific service – Eric Aug 15 '18 at 09:19
  • Still, it seems a little surprising that you can't load a few DLLs before getting timed out. Is there a way for us to reproduce this? – David Heffernan Aug 15 '18 at 20:23
  • What is the timeframe that we're talking about here? Are you sure that the problem isn't elsewhere (e.g. a glitch in your executable - which is also loaded from disk *BTW*, or when loading a custom *.dll*)? I don't know how you build your executable, but check https://msdn.microsoft.com/en-us/library/yx9zd12s.aspx (that option will only load a *.dll* when 1st needed instead of program startup). – CristiFati Aug 16 '18 at 12:46
  • for reproduce: use https://github.com/shirou/gopsutil within the service wrapper: https://github.com/kardianos/service the service works 100% if i remove this repo from my source. and if you scroll through the gopsutil source you will find many dll imports. – Eric Aug 17 '18 at 13:04

2 Answers2

2

The short answer is "no": "DLL" stands for "Dynamically-Linked Library", and it's impossible to link a DLL statically.

Basically you have two ways to go, I would say:

  • Debug the issue.

    The default timeout for a Windows service startup is 30000 ms; that is a lot, so I'm inclined to think your issue it not loading of DLLs or at least not with locating and linking them in.

    The usual approach is two-pronged:

    • Isolate possible cases. First, turn your service into a simple (say, console) program, and see how it starts up with the cold cache. If the behaviour persists, it will be simpler to debug than the service.

    • Study whether some of your DLLs does silly things like performing network requests in their entry-point function (colloquially known as "DllMain").

      If you're loading the DLLs using LoadLibrary[Ex], their entry point is called upon those calls.

      With that in mind, try adding some tracing to your DLL initialization code.

    If all that fails, try procmon of Sysinternals fame or similar tools.

  • Get / produce static builds of those libraries—you will then be able to link them in statically.

    But note that if the issue is in fact has something to deal with the initialization of those libs, linking them in statically won't buy you anything—they will be slow already linked, that is.


I'd also note that if my shot in the dark was correct, and one or more of yout libs tries to access some networked resource, a simple way to solve the problem might be implementing proper dependencies for your service—so that it starts up only when the services it depends on functioning are up (such as networking, DNS etc).

kostix
  • 51,517
  • 14
  • 93
  • 176
  • Those dlls which i mean are: kernel32.dll, user32.dll etc. Just official windows dlls, nothing more. – Eric Aug 15 '18 at 13:36
  • 1
    If yes, I would bet your problem really lies elsewhere: these DLLs do not cause any problem for everyone else's code. – kostix Aug 15 '18 at 17:07
0

Consider using LazyDll to speed up your code.

gonutz
  • 5,087
  • 3
  • 22
  • 40