Since #15233 has been merged, the `lockdata` becomes a static local variable with a well-defined initialization order: https://github.com/bitcoin/bitcoin/blob/36c0abd8f61ba859d53b1e59014720282c97c143/src/sync.cpp#L93-L96

Its destructor `~LockData()` [is called at program exit](https://en.cppreference.com/w/cpp/utility/program/exit).

At the same time, "if a function-local ... static object was destroyed and then that function is called from the destructor..., the _behavior is undefined_."

It seems possible that at program exit the `lockdata` object is destroyed before a global `RecursiveMutex` destructor calls `DeleteLock()`, which in turn calls `GetLockData()` with UB.
#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif
#include <sync.h>
#include <tinyformat.h>
#include <logging.h>
#include <util/strencodings.h>
#include <util/threadnames.h>
#include <map>
#include <set>
#include <system_error>
#ifdef DEBUG_LOCKCONTENTION
#if !defined(HAVE_THREAD_LOCAL)
static_assert(false, "thread_local is not supported");
#endif
void PrintLockContention(const char* pszName, const char* pszFile, int nLine)