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 (str == "") {
        flag = BCLog::ALL;
        return true;
    }
    for (const CLogCategoryDesc& category_desc : LogCategories) {
        if (category_desc.category == str) {
            flag = category_desc.flag;
            return true;
        }
    }
    return false;
}
std::vector<LogCategory> BCLog::Logger::LogCategoriesList()
{
    std::vector<LogCategory> ret;
    for (const CLogCategoryDesc& category_desc : LogCategories) {
        
        if (category_desc.flag != BCLog::NONE && category_desc.flag != BCLog::ALL) {
            LogCategory catActive;
            catActive.category = category_desc.category;
            catActive.active = WillLogCategory(category_desc.flag);
            ret.push_back(catActive);
        }
    }
    return ret;
}
std::string BCLog::Logger::LogTimestampStr(const std::string& str)