Merge bitcoin/bitcoin#32588: util: Abort on failing CHECK_NONFATAL in debug builds

fa37153288 util: Abort on failing CHECK_NONFATAL in debug builds (MarcoFalke)
fa0dc4bdff test: Allow testing of check failures (MarcoFalke)
faeb58fe66 refactor: Set G_ABORT_ON_FAILED_ASSUME when G_FUZZING_BUILD (MarcoFalke)

Pull request description:

  A failing `CHECK_NONFATAL` will throw an exception. This is fine and even desired in production builds, because the program may catch the exception and give the user a way to easily report the bug upstream.

  However, in debug development builds, exceptions for internal bugs are problematic:

  * The exception could accidentally be caught and silently ignored
  * The exception does not include a full stacktrace, possibly making debugging harder

  Fix all issues by turning the exception into an abort in debug builds.

  This can be tested by reverting the hunks to `src/rpc/node.cpp` and `test/functional/rpc_misc.py` and then running the functional or fuzz tests.

ACKs for top commit:
  achow101:
    ACK fa37153288
  ryanofsky:
    Code review ACK fa37153288, just catching subprocess.CalledProcessError in test fixing up a comment since last review
  stickies-v:
    ACK fa37153288

Tree-SHA512: 2d892b838ccef6f9b25a066e7c2f6cd6f5acc94aad1d91fce62308983bd3f5c5d724897a76de4e3cc5c3678ddadc87e2ee8c87362965373526038e598dfb0101
This commit is contained in:
merge-script
2025-10-24 04:41:24 +02:00
8 changed files with 94 additions and 28 deletions

View File

@@ -15,6 +15,9 @@ from test_framework.util import (
from test_framework.authproxy import JSONRPCException
import http
import subprocess
class RpcMiscTest(BitcoinTestFramework):
def set_test_params(self):
@@ -24,11 +27,22 @@ class RpcMiscTest(BitcoinTestFramework):
node = self.nodes[0]
self.log.info("test CHECK_NONFATAL")
assert_raises_rpc_error(
-1,
'Internal bug detected: request.params[9].get_str() != "trigger_internal_bug"',
lambda: node.echo(arg9='trigger_internal_bug'),
)
msg_internal_bug = 'request.params[9].get_str() != "trigger_internal_bug"'
self.restart_node(0) # Required to flush the chainstate
try:
node.echo(arg9="trigger_internal_bug")
assert False # Must hit one of the exceptions below
except (
subprocess.CalledProcessError,
http.client.CannotSendRequest,
http.client.RemoteDisconnected,
):
self.log.info("Restart node after crash")
assert_equal(-6, node.process.wait(timeout=10))
self.start_node(0)
except JSONRPCException as e:
assert_equal(e.error["code"], -1)
assert f"Internal bug detected: {msg_internal_bug}" in e.error["message"]
self.log.info("test max arg size")
ARG_SZ_COMMON = 131071 # Common limit, used previously in the test framework, serves as a regression test