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.
{
    std::string strStamped;
    if (!m_log_timestamps)
        return str;
    if (m_started_new_line) {
        int64_t nTimeMicros = GetTimeMicros();
        strStamped = FormatISO8601DateTime(nTimeMicros/1000000);
        if (m_log_time_micros) {
            strStamped.pop_back();
            strStamped += strprintf(".%06dZ", nTimeMicros%1000000);
        }
        int64_t mocktime = GetMockTime();
        if (mocktime) {
            strStamped += " (mocktime: " + FormatISO8601DateTime(mocktime) + ")";
        }
        strStamped += ' ' + str;
    } else
        strStamped = str;
    return strStamped;
}
namespace BCLog {
    /** Belts and suspenders: make sure outgoing log messages don't contain
     * potentially suspicious characters, such as terminal control codes.
     *
     * This escapes control characters except newline ('\n') in C syntax.
     * It escapes instead of removes them to still allow for troubleshooting
     * issues where they accidentally end up in strings.
     */
    std::string LogEscapeMessage(const std::string& str) {