Startup crash on macOS with GCC 15.2: std::source_location::file_name() is nullptr #33964

issue l0rinc openend this issue on November 27, 2025
  1. l0rinc commented at 7:44 pm on November 27, 2025: contributor

    Summary

    bitcoind crashes on startup when built with Homebrew GCC 15.2.0 on macOS (arm64). The crash occurs inside SourceLocationHasher::operator() when constructing a std::basic_string_view from std::source_location::file_name().

    The same commit runs successfully when built with the default AppleClang toolchain.

    Versions

    • Bitcoin Core: master at 808f1d972be35f4c66bdc30ab0f4060dab0c43c0
    • Platform: macOS 26.1 (25B78), Apple M4 Pro (arm64)
    • CMake: cmake version 4.2.0
    • GCC: gcc (Homebrew GCC 15.2.0) 15.2.0
    • AppleClang: AppleClang 17.0.0.17000404

    Build configuration (GCC 15.2, Debug)

    0git checkout 808f1d972be35f4c66bdc30ab0f4060dab0c43c0
    1rm -rfd build && cmake -B build -DENABLE_IPC=OFF -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ && cmake --build build -j$(nproc)             
    2lldb ./build/bin/bitcoind -- -datadir="$HOME/Library/Application Support/Bitcoin" -stopatheight=21129 -dbcache=1000 -printtoconsole=1
    

    Crash session

     0(lldb) run
     1Process 4126 launched: '/Users/lorinc/IdeaProjects/bitcoin/build/bin/bitcoind' (arm64)
     22025-11-27T19:01:48Z Bitcoin Core version v30.99.0-b3e2ae7aaee5 (debug build)
     32025-11-27T19:01:48Z Using the 'arm_shani(1way;2way)' SHA256 implementation
     42025-11-27T19:01:48Z Default data directory /Users/lorinc/Library/Application Support/Bitcoin
     52025-11-27T19:01:48Z Using data directory /Users/lorinc/Library/Application Support/Bitcoin
     62025-11-27T19:01:48Z Config file: /Users/lorinc/Library/Application Support/Bitcoin/bitcoin.conf (not found, skipping)
     72025-11-27T19:01:48Z Command-line arg: datadir="/Users/lorinc/Library/Application Support/Bitcoin"
     82025-11-27T19:01:48Z Command-line arg: dbcache="1000"
     92025-11-27T19:01:48Z Command-line arg: printtoconsole="1"
    102025-11-27T19:01:48Z Command-line arg: stopatheight="21129"
    112025-11-27T19:01:48Z Using at most 125 automatic connections (1024 file descriptors available)
    122025-11-27T19:01:48Z scheduler thread start
    132025-11-27T19:01:48Z Binding RPC on address ::1 port 8332
    142025-11-27T19:01:48Z Binding RPC on address 127.0.0.1 port 8332
    152025-11-27T19:01:48Z Generated RPC authentication cookie /Users/lorinc/Library/Application Support/Bitcoin/.cookie
    162025-11-27T19:01:48Z Permissions used for cookie: rw-------
    172025-11-27T19:01:48Z Using random cookie authentication.
    182025-11-27T19:01:48Z Starting HTTP server with 16 worker threads
    19Process 4126 stopped
    20* thread [#1](/bitcoin-bitcoin/1/), queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    21    frame [#0](/bitcoin-bitcoin/0/): 0x000000019fb3ca84 libsystem_platform.dylib`_platform_strlen + 4
    22libsystem_platform.dylib`_platform_strlen:
    23->  0x19fb3ca84 <+4>:  ldr    q0, [x1]
    24    0x19fb3ca88 <+8>:  adr    x3, 0x19fb3c9c0 ; ___lldb_unnamed_symbol_1804e09c0
    25    0x19fb3ca8c <+12>: ldr    q2, [x3], [#0](/bitcoin-bitcoin/0/)x10
    26    0x19fb3ca90 <+16>: and    x2, x0, [#0](/bitcoin-bitcoin/0/)xf
    27(lldb) bt
    28error: libbitcoin_util.a(logging.cpp.o) 0x4000ec000000034a: DW_TAG_member '_M_local_buf' refers to type 0x00000000000fed84 which extends beyond the bounds of 0x4000ec0000000340
    29* thread [#1](/bitcoin-bitcoin/1/), queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    30  * frame [#0](/bitcoin-bitcoin/0/): 0x000000019fb3ca84 libsystem_platform.dylib`_platform_strlen + 4
    31    frame [#1](/bitcoin-bitcoin/1/): 0x0000000100002600 bitcoind`std::char_traits<char>::length(__s=0x0000000000000000) at char_traits.h:393:25
    32    frame [#2](/bitcoin-bitcoin/2/): 0x00000001000086d0 bitcoind`std::basic_string_view<char, std::char_traits<char>>::basic_string_view(this=0x000000016fdfa1b8, __str=0x0000000000000000) at string_view:145:35
    33    frame [#3](/bitcoin-bitcoin/3/): 0x0000000100f43634 bitcoind`SourceLocationHasher::operator()(this=0x000000081286d8a0, s=0x000000016fdfa820) const at logging.h:52:74
    34    frame [#4](/bitcoin-bitcoin/4/): 0x0000000100f554c0 bitcoind`std::__detail::_Hash_code_base<std::source_location, std::pair<std::source_location const, BCLog::LogRateLimiter::Stats>, std::__detail::_Select1st, SourceLocationHasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(this=0x000000081286d8a0, __k=0x000000016fdfa820) const at hashtable_policy.h:1071:23
    35    frame [#5](/bitcoin-bitcoin/5/): 0x0000000100f50a08 bitcoind`std::_Hashtable<std::source_location, std::pair<std::source_location const, BCLog::LogRateLimiter::Stats>, std::allocator<std::pair<std::source_location const, BCLog::LogRateLimiter::Stats>>, std::__detail::_Select1st, SourceLocationEqual, SourceLocationHasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true>>::_M_locate(this=0x000000081286d8a0, __k=0x000000016fdfa820) const at hashtable.h:2279:46
    36    frame [#6](/bitcoin-bitcoin/6/): 0x0000000100f4d3ec bitcoind`std::pair<std::__detail::_Node_iterator<std::pair<std::source_location const, BCLog::LogRateLimiter::Stats>, false, false>, bool> std::_Hashtable<std::source_location, std::pair<std::source_location const, BCLog::LogRateLimiter::Stats>, std::allocator<std::pair<std::source_location const, BCLog::LogRateLimiter::Stats>>, std::__detail::_Select1st, SourceLocationEqual, SourceLocationHasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true>>::try_emplace<std::source_location const&, unsigned long long const&>(this=0x000000081286d8a0, (null)=std::_Hashtable<std::source_location, std::pair<const std::source_location, BCLog::LogRateLimiter::Stats>, std::allocator<std::pair<const std::source_location, BCLog::LogRateLimiter::Stats> >, std::__detail::_Select1st, SourceLocationEqual, SourceLocationHasher, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::const_iterator @ 0x000000016fdfa2a0, __k=0x000000016fdfa820, (null)=0x000000081286d8e0) at hashtable.h:1088:30
    37    frame [#7](/bitcoin-bitcoin/7/): 0x0000000100f4ac1c bitcoind`std::pair<std::__detail::_Node_iterator<std::pair<std::source_location const, BCLog::LogRateLimiter::Stats>, false, false>, bool> std::unordered_map<std::source_location, BCLog::LogRateLimiter::Stats, SourceLocationHasher, SourceLocationEqual, std::allocator<std::pair<std::source_location const, BCLog::LogRateLimiter::Stats>>>::try_emplace<unsigned long long const&>(this=size=0, __k=0x000000016fdfa820, (null)=0x000000081286d8e0) at unordered_map.h:527:27
    38    frame [#8](/bitcoin-bitcoin/8/): 0x0000000100f47510 bitcoind`BCLog::LogRateLimiter::Consume(this=0x000000081286d860, source_loc=0x000000016fdfa820, str="2025-11-27T19:01:48Z Using wallet directory /Users/lorinc/Library/Application Support/Bitcoin/wallets\n") at logging.cpp:395:47
    39    frame [#9](/bitcoin-bitcoin/9/): 0x0000000100f47e20 bitcoind`BCLog::Logger::LogPrintStr_(this=0x0000000812820c80, str=(_M_len = 80, _M_str = "Using wallet directory /Users/lorinc/Library/Application Support/Bitcoin/wallets"), source_loc=0x000000016fdfa820, category=ALL, level=Info, should_ratelimit=true) at logging.cpp:465:39
    40    frame [#10](/bitcoin-bitcoin/10/): 0x0000000100f47a24 bitcoind`BCLog::Logger::LogPrintStr(this=0x0000000812820c80, str=(_M_len = 80, _M_str = "Using wallet directory /Users/lorinc/Library/Application Support/Bitcoin/wallets"), source_loc=0x000000016fdfa820, category=ALL, level=Info, should_ratelimit=true) at logging.cpp:426:24
    41    frame [#11](/bitcoin-bitcoin/11/): 0x000000010001daec bitcoind`void LogPrintFormatInternal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(source_loc=0x000000016fdfa820, flag=ALL, level=Info, should_ratelimit=true, fmt=(fmt = "Using wallet directory %s"), (null)="/Users/lorinc/Library/Application Support/Bitcoin/wallets") at logging.h:358:34
    42    frame [#12](/bitcoin-bitcoin/12/): 0x000000010098b85c bitcoind`wallet::VerifyWallets(context=0x00000008130101c8) at load.cpp:53:5
    43    frame [#13](/bitcoin-bitcoin/13/): 0x0000000100931d4c bitcoind`wallet::(anonymous namespace)::WalletLoaderImpl::verify(this=0x00000008130101c0) const at interfaces.cpp:558:50
    44    frame [#14](/bitcoin-bitcoin/14/): 0x0000000100173c10 bitcoind`AppInitMain(node=0x000000016fdfea08, tip_info=0x0000000000000000) at init.cpp:1523:28
    45    frame [#15](/bitcoin-bitcoin/15/): 0x0000000100009820 bitcoind`AppInit(node=0x000000016fdfea08) at bitcoind.cpp:242:54
    46    frame [#16](/bitcoin-bitcoin/16/): 0x0000000100009c54 bitcoind`main(argc=5, argv=0x000000016fdff1c0) at bitcoind.cpp:283:17
    47    frame [#17](/bitcoin-bitcoin/17/): 0x000000019f76dd54 dyld`start + 7184
    

    On this toolchain, file_name() returns a null pointer, so std::basic_string_view calls std::char_traits<char>::length(__s = 0x0)strlen(nullptr), which triggers EXC_BAD_ACCESS.


    According to cppreference for std::source_location::file_name, the function is specified to:

    Return the name of the current source file represented by this object, represented as a null-terminated byte string.

  2. maflcko commented at 8:33 pm on November 27, 2025: member
    Your toolchain clearly violates the C++ standard (https://eel.is/c++draft/support.srcloc#class.general-2), so you’ll have to report this upstream via a minimal reproducer.
  3. maflcko added the label macOS on Nov 27, 2025
  4. maflcko added the label Upstream on Nov 27, 2025
  5. maflcko added the label Questions and Help on Nov 27, 2025
  6. l0rinc commented at 11:53 am on November 30, 2025: contributor

    Tried getting to the bottom of it, something’s really off here, two consecutive calls to std::source_location::current() return very different and suspicious values:

    What does BTC file name and sat function name refer to and why do we have millions of lines :/?

    They seem to come from (modifying these strings updates the file and method names): https://github.com/bitcoin/bitcoin/blob/966666de9a6211b8748f43d682490c924e132e58/src/policy/feerate.h#L18-L19

     0diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
     1index 37cacb2a7e..19a9523322 100644
     2--- a/src/bitcoind.cpp
     3+++ b/src/bitcoind.cpp
     4@@ -239,6 +239,10 @@ static bool AppInit(NodeContext& node)
     5             // If locking a directory failed, exit immediately
     6             return false;
     7         }
     8+
     9+        auto x = std::source_location::current();
    10+        std::cout << "AppInit called from " << x.file_name() << ":" << x.line() << "\n";
    11+
    12         fRet = AppInitInterfaces(node) && AppInitMain(node);
    13     }
    14     catch (const std::exception& e) {
    15@@ -279,6 +283,9 @@ MAIN_FUNCTION
    16     // Process early info return commands such as -help or -version
    17     if (ProcessInitCommands(*init, args)) return EXIT_SUCCESS;
    18 
    19+    auto x = std::source_location::current();
    20+    std::cout << "main called from " << x.file_name() << ":" << x.line() << "\n";
    21+
    22     // Start application
    23     if (!AppInit(node) || !Assert(node.shutdown_signal)->wait()) {
    24         node.exit_status = EXIT_FAILURE;
    25diff --git a/src/init.cpp b/src/init.cpp
    26index d1c6a5cad0..2c446785b0 100644
    27--- a/src/init.cpp
    28+++ b/src/init.cpp
    29@@ -1518,6 +1518,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    30             return InitError(_("Unable to start HTTP server. See debug log for details."));
    31     }
    32 
    33+    auto x = std::source_location::current();
    34+    std::cout << "AppInitMain called from " << x.file_name() << ":" << x.line() << "\n";
    35+
    36+
    37     // ********************************************************* Step 5: verify wallet database integrity
    38     for (const auto& client : node.chain_clients) {
    39         if (!client->verify()) {
    40diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
    41index 2cda1ba299..b353b51f28 100644
    42--- a/src/wallet/interfaces.cpp
    43+++ b/src/wallet/interfaces.cpp
    44@@ -555,7 +555,13 @@ public:
    45             m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
    46         }
    47     }
    48-    bool verify() override { return VerifyWallets(m_context); }
    49+    bool verify() override
    50+    {
    51+        auto x = std::source_location::current();
    52+        std::cout << "verify called from " << x.file_name() << ":" << x.line() << "\n";
    53+
    54+        return VerifyWallets(m_context);
    55+    }
    56     bool load() override { return LoadWallets(m_context); }
    57     void start(CScheduler& scheduler) override
    58     {
    59diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
    60index f362064473..8a6a237d1d 100644
    61--- a/src/wallet/load.cpp
    62+++ b/src/wallet/load.cpp
    63@@ -26,6 +26,12 @@ using util::Join;
    64 namespace wallet {
    65 bool VerifyWallets(WalletContext& context)
    66 {
    67+    auto x1 = std::source_location::current();
    68+    std::cout << "VerifyWallets1 called from " << x1.file_name() << ":" << x1.line() << "\n";
    69+
    70+    auto x = std::source_location::current();
    71+    std::cout << "VerifyWallets called from " << x.file_name() << ":" << x.line() << "\n";
    72+
    73     interfaces::Chain& chain = *context.chain;
    74     ArgsManager& args = *Assert(context.args);
    

    The stack parents seem to be evaluated correctly, but VerifyWallets starts returning weird values from the start:

    0main called from ./bitcoind.cpp:286
    1AppInit called from ./bitcoind.cpp:243
    2AppInitMain called from ./init.cpp:1521
    3verify called from ./wallet/interfaces.cpp:560
    4VerifyWallets1 called from BTC:4412482
    

    Doing the same with default AppleClang works correctly:


    I’m not sure how to create a reproducer for this…

  7. maflcko commented at 8:35 am on December 1, 2025: member

    I’m not sure how to create a reproducer for this…

    For toolchain bugs, it helps to create a minimal reproducer. Often, this is easy to create in one shot, looking at the code that mis-compiled.

    Sometimes, it is not so easy and you’ll have to manually remove chunks from the full software, until you end up with something minimal. This may be tedious, when done manually. You can also use creduce, but this may not work in contexts where one can define a unique bug signature (https://github.com/bitcoin/bitcoin/issues/32276#issuecomment-2812024548).

    In theory, it should be possible to move the runtime bug to a compile time bug with a static_assert(std::string_view{__FILE__}== std::string_view{std::source_location::current().file_name()});, so that it can be fed into creduce, but I have a feeling that the bug disappears at compile time. In that case, I don’t see an easier way to reduce it.

  8. maflcko commented at 8:35 am on December 1, 2025: member
    Unrelated, you can also try different version of your gcc package, to see if this was introduced recently.
  9. l0rinc commented at 9:53 am on December 1, 2025: contributor
    Not sure how to create a reliable reproducer for this, closing for now
  10. l0rinc closed this on Dec 1, 2025


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-12-01 21:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me