test: Increase stack size for "Debug" builds with MSVC #32349

pull hebasto wants to merge 1 commits into bitcoin:master from hebasto:250425-msvc-stack changing 1 files +5 −0
  1. hebasto commented at 12:42 PM on April 25, 2025: member

    This PR accommodates the deep recursion in the FindChallenges() function used in test/miniscript_tests.cpp.

    Fixes #32341 (comment).

    CI log: https://github.com/hebasto/bitcoin/actions/runs/14664806617/job/41156972137

  2. test: Increase stack size for "Debug" builds with MSVC
    This change accommodates the deep recursion in the `FindChallenges()`
    function used in `test/miniscript_tests.cpp`.
    8684dc7f9c
  3. hebasto added the label Windows on Apr 25, 2025
  4. hebasto added the label Tests on Apr 25, 2025
  5. DrahtBot commented at 12:42 PM on April 25, 2025: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32349.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    No conflicts as of last run.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  6. in CMakeLists.txt:295 in 8684dc7f9c
     288 | @@ -289,6 +289,11 @@ if(WIN32)
     289 |        /Zc:__cplusplus
     290 |        /sdl
     291 |      )
     292 | +    target_link_options(core_interface INTERFACE
     293 | +      # Increase stack size to accommodate the deep recursion
     294 | +      # in the FindChallenges() function used in miniscript_tests.
     295 | +      $<$<CONFIG:Debug>:/STACK:2097152>
    


    fanquake commented at 12:54 PM on April 25, 2025:

    Where does this reserve value come from?


    hebasto commented at 1:07 PM on April 25, 2025:

    Determined empirically—this value was found to be sufficient during testing.

  7. l0rinc commented at 1:02 PM on April 25, 2025: contributor

    I'm not against increasing the Windows stack depth, but the underlying problem may be that we're ignoring warnings such as misc-no-recursion, even when the fix is quite simple.

    FindChallenges looks like a simple depth-first search, which should be straightforward to rewrite as an iterative walk:

    diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp
    index f253562a2f..14ac44e2c6 100644
    --- a/src/test/miniscript_tests.cpp
    +++ b/src/test/miniscript_tests.cpp
    @@ -323,6 +323,35 @@ std::set<Challenge> FindChallenges(const NodeRef& ref) {
         return chal;
     }
     
    +std::set<Challenge> FindChallenges_no_recursion(const NodeRef& root)
    +{
    +    std::set<Challenge> chal;
    +    std::vector<const Node*> stack;
    +    stack.push_back(root.get());
    +
    +    while (!stack.empty()) {
    +        const Node* ref{stack.back()};
    +        stack.pop_back();
    +
    +        for (const auto& key : ref->keys) {
    +            chal.emplace(ChallengeType::PK, ChallengeNumber(key));
    +        }
    +        switch (ref->fragment) {
    +        case Fragment::OLDER: chal.emplace(ChallengeType::OLDER, ref->k); break;
    +        case Fragment::AFTER: chal.emplace(ChallengeType::AFTER, ref->k); break;
    +        case Fragment::SHA256: chal.emplace(ChallengeType::SHA256, ChallengeNumber(ref->data)); break;
    +        case Fragment::RIPEMD160: chal.emplace(ChallengeType::RIPEMD160, ChallengeNumber(ref->data)); break;
    +        case Fragment::HASH256: chal.emplace(ChallengeType::HASH256, ChallengeNumber(ref->data)); break;
    +        case Fragment::HASH160: chal.emplace(ChallengeType::HASH160, ChallengeNumber(ref->data)); break;
    +        default: break;
    +        }
    +        for (const auto& sub : ref->subs) {
    +            stack.push_back(sub.get());
    +        }
    +    }
    +    return chal;
    +}
    +
     //! The spk for this script under the given context. If it's a Taproot output also record the spend data.
     CScript ScriptPubKey(miniscript::MiniscriptContext ctx, const CScript& script, TaprootBuilder& builder)
     {
    @@ -348,6 +377,8 @@ struct MiniScriptTest : BasicTestingSetup {
     void TestSatisfy(const KeyConverter& converter, const std::string& testcase, const NodeRef& node) {
         auto script = node->ToScript(converter);
         auto challenges = FindChallenges(node); // Find all challenges in the generated miniscript.
    +    auto challenges_no_recursion = FindChallenges_no_recursion(node); // Find all challenges in the generated miniscript.
    +    BOOST_CHECK(std::vector{challenges} == std::vector{challenges_no_recursion});
         std::vector<Challenge> challist(challenges.begin(), challenges.end());
         for (int iter = 0; iter < 3; ++iter) {
             std::shuffle(challist.begin(), challist.end(), m_rng);
    
  8. hebasto commented at 1:12 PM on April 25, 2025: member

    I'm not against increasing the Windows stack depth, but the underlying problem may be that we're ignoring warnings such as misc-no-recursion, even when the fix is quite simple.

    FindChallenges looks like a simple depth-first search, which should be straightforward to rewrite as an iterative walk:

    diff --git a/src/test/miniscript_tests.cpp b/src/test/miniscript_tests.cpp
    index f253562a2f..14ac44e2c6 100644
    --- a/src/test/miniscript_tests.cpp
    +++ b/src/test/miniscript_tests.cpp
    @@ -323,6 +323,35 @@ std::set<Challenge> FindChallenges(const NodeRef& ref) {
         return chal;
     }
     
    +std::set<Challenge> FindChallenges_no_recursion(const NodeRef& root)
    +{
    +    std::set<Challenge> chal;
    +    std::vector<const Node*> stack;
    +    stack.push_back(root.get());
    +
    +    while (!stack.empty()) {
    +        const Node* ref{stack.back()};
    +        stack.pop_back();
    +
    +        for (const auto& key : ref->keys) {
    +            chal.emplace(ChallengeType::PK, ChallengeNumber(key));
    +        }
    +        switch (ref->fragment) {
    +        case Fragment::OLDER: chal.emplace(ChallengeType::OLDER, ref->k); break;
    +        case Fragment::AFTER: chal.emplace(ChallengeType::AFTER, ref->k); break;
    +        case Fragment::SHA256: chal.emplace(ChallengeType::SHA256, ChallengeNumber(ref->data)); break;
    +        case Fragment::RIPEMD160: chal.emplace(ChallengeType::RIPEMD160, ChallengeNumber(ref->data)); break;
    +        case Fragment::HASH256: chal.emplace(ChallengeType::HASH256, ChallengeNumber(ref->data)); break;
    +        case Fragment::HASH160: chal.emplace(ChallengeType::HASH160, ChallengeNumber(ref->data)); break;
    +        default: break;
    +        }
    +        for (const auto& sub : ref->subs) {
    +            stack.push_back(sub.get());
    +        }
    +    }
    +    return chal;
    +}
    +
     //! The spk for this script under the given context. If it's a Taproot output also record the spend data.
     CScript ScriptPubKey(miniscript::MiniscriptContext ctx, const CScript& script, TaprootBuilder& builder)
     {
    @@ -348,6 +377,8 @@ struct MiniScriptTest : BasicTestingSetup {
     void TestSatisfy(const KeyConverter& converter, const std::string& testcase, const NodeRef& node) {
         auto script = node->ToScript(converter);
         auto challenges = FindChallenges(node); // Find all challenges in the generated miniscript.
    +    auto challenges_no_recursion = FindChallenges_no_recursion(node); // Find all challenges in the generated miniscript.
    +    BOOST_CHECK(std::vector{challenges} == std::vector{challenges_no_recursion});
         std::vector<Challenge> challist(challenges.begin(), challenges.end());
         for (int iter = 0; iter < 3; ++iter) {
             std::shuffle(challist.begin(), challist.end(), m_rng);
    

    cc @sipa @darosior

  9. darosior commented at 1:17 PM on April 25, 2025: member

    That sounds sensible, can you open a PR with this patch and tag me?

  10. l0rinc referenced this in commit bd89f7eff0 on Apr 25, 2025
  11. l0rinc commented at 2:16 PM on April 25, 2025: contributor

    Opened #32351 as an alternative fix, cc: @darosior

  12. hebasto marked this as a draft on Apr 25, 2025
  13. hebasto commented at 9:19 AM on April 27, 2025: member

    Closing in favour of #32351.

  14. hebasto closed this on Apr 27, 2025

  15. l0rinc referenced this in commit 28f7f3f58d on Apr 27, 2025
  16. l0rinc referenced this in commit b80d0bdee4 on Apr 28, 2025
  17. achow101 referenced this in commit 2d5b424414 on Apr 29, 2025
  18. w0xlt referenced this in commit fd6ab9e735 on May 7, 2025
  19. luke-jr referenced this in commit 5da98f931d on Jun 6, 2025
  20. bitcoin locked this on Jul 30, 2026

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: 2026-08-17 03:51 UTC

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