[SERVER-58097] preload psapi.dll to avoid lockup when writing minidump file Created: 25/Jun/21  Updated: 12/Dec/23

Status: Open
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Billy Donahue Assignee: Backlog - Service Architecture
Resolution: Unresolved Votes: 0
Labels: sa-remove-fv-backlog-22
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Related
Assigned Teams:
Service Arch
Operating System: ALL
Steps To Reproduce:

See BF-17180

Sprint: Service Arch Prioritized List
Participants:
Linked BF Score: 6

 Description   

(Windows)

Writing a minidump file involves attaching psapi.dll to the process.
This is a problem if the process is elsewhere holding the ntdll lock.

The lock ntdll!LdrpInvertedFunctionTableSRWLock protects DLL import tables.
This is being held by a thread while we are loading the psapi.dll library to create the minidump.

Workarounds:

Attach psapi.dll at startup.

Generate the minidump with a separate process (which won't have its ntdll import table mutexes held).



 Comments   
Comment by Jason Chan [ 11/Dec/23 ]

Putting this into Needs Scheduling to re-evaluate if we think this is still a low-effort win to reduce windows BF noise.

Comment by Mark Benvenuto [ 29/Sep/21 ]

billy.donahue, no the scons command does not count as linking in my opinion. The Windows linker only adds a load time dependency if you use a function in psapi.dll. If you never use a function from a dll, the linker ignores the dll. This is the opposite of Linux's ld.

 Here is a list of dependencies for mongod.exe on my local development machine for a debug build. These are the dll mongod.exe directly depends on (not transitive and not runtime).

> dumpbin /imports .\mongod.exe |rg -i dll | sort -u
                         2C2 _seh_filter_dll
    ADVAPI32.dll
    bcrypt.dll
    CRYPT32.dll
    dbghelp.dll
    DNSAPI.dll
    IPHLPAPI.DLL
    KERNEL32.dll
    libsasl.dll
    MSVCP140D.dll
    MSWSOCK.dll
    netsnmp.dll
    pdh.dll
    Secur32.dll
    ucrtbased.dll
    USER32.dll
    VCRUNTIME140_1D.dll
    VCRUNTIME140D.dll
    VERSION.dll
    WINHTTP.dll
    WINMM.dll
    WLDAP32.dll
    WS2_32.dll
 

Comment by Billy Donahue [ 28/Sep/21 ]

https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getprocessmemoryinfo#remarks

If PSAPI_VERSION is 2 or greater, this function is defined as K32GetProcessMemoryInfo in Psapi.h and exported in Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetProcessMemoryInfo in Psapi.h and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetProcessMemoryInfo.

Maybe we're just using an obsolete API and should get with the times. This is very old code we're talking about.

Comment by Billy Donahue [ 28/Sep/21 ]

A simpler approach could be to have Psapi be in the TARGETLIBS of servers on Windows.
I think that would just be a Scons change and then psapi.dll would be available at startup.

Per:

https://docs.microsoft.com/en-us/windows/win32/psapi/enumerating-all-modules-for-a-process

// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1

Scons already includes Psapi in the windows deps. We don't need a LoadLibrary call. We probably just need to call some function in the psapi dll at startup to force windows to resolve its dynamic symbols early.

mark.benvenuto can you clarify this for us?

https://jira.mongodb.org/browse/BF-17180?focusedCommentId=3093960&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-3093960

"Thread 79 is trying load psapi.dll which we do not link against."

Psapi.lib has been on this list for at least 6 years. Is this considered linking against it?
https://github.com/mongodb/mongo/blob/cc143172ecff4d0c4ea707c6da1673b25580393c/SConstruct#L2287

Comment by Blake Oler [ 28/Sep/21 ]

Talking to billy.donahue about this, could take as little as a few hours to fix this if it's as simple as adding a LoadLibrary call in WinMain. If it's more complicated, or we want loading the DLL to be conditional, it could take longer.

Generated at Thu Feb 08 05:43:34 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.