The position of chronik::Stop() makes it so the indexer might still process freed memory. Moving it after GetMainSignals().FlushBackgroundCallbacks() fixes this.
Details
- Reviewers
Fabien PiRK - Group Reviewers
Restricted Project - Commits
- rABC27dd0b084c8c: [Chronik] Fix: "Segmentation fault" during shutdown
The functional test should fail if the chronik::Stop() is not moved as in this diff, and should pass if chronik::Stop() is moved as in this diff.
Alternatively, this should also reproduce the bug:
- ninja
- IBD for a few minutes
- Stop the node: Segmentation fault
Diff Detail
- Repository
- rABC Bitcoin ABC
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
@bot build-linux32 build-linux64 build-linux-aarch64 build-linux-arm build-osx build-win64
Failed tests logs:
====== Bitcoin ABC functional tests: chronik_shutdown.py ======
------- Stdout: -------
2023-05-26T16:05:52.073000Z TestFramework (INFO): Initializing test directory /work/abc-ci-builds/build-linux-aarch64/test/tmp/test_runner_₿₵_ _20230526_155653/chronik_shutdown_233
2023-05-26T16:07:01.321000Z TestFramework.p2p (WARNING): Connection lost to 127.0.0.1:20108 due to [Errno 32] Broken pipe
2023-05-26T16:08:02.895000Z TestFramework (INFO): Stopping nodes
[node 0] Cleaning up leftover process
------- Stderr: -------
Traceback (most recent call last):
File "/work/test/functional/chronik_shutdown.py", line 76, in <module>
ChronikShutdown().main()
File "/work/test/functional/test_framework/test_framework.py", line 165, in main
exit_code = self.shutdown()
File "/work/test/functional/test_framework/test_framework.py", line 391, in shutdown
self.stop_nodes()
File "/work/test/functional/test_framework/test_framework.py", line 640, in stop_nodes
node.wait_until_stopped()
File "/work/test/functional/test_framework/test_node.py", line 548, in wait_until_stopped
wait_until_helper(
File "/work/test/functional/test_framework/util.py", line 285, in wait_until_helper
if predicate():
File "/work/test/functional/test_framework/test_node.py", line 537, in is_node_stopped
assert return_code == 0, self._node_msg(
AssertionError: [node 0] Node returned non-zero exit code (-11) when stoppingEach failure log is accessible here:
Bitcoin ABC functional tests: chronik_shutdown.py
Failed tests logs:
====== Bitcoin ABC functional tests: chronik_shutdown.py ======
------- Stdout: -------
2023-05-26T16:09:13.284000Z TestFramework (INFO): Initializing test directory /work/abc-ci-builds/build-linux-arm/test/tmp/test_runner_₿₵_ _20230526_155924/chronik_shutdown_233
2023-05-26T16:11:19.719000Z TestFramework.utils (ERROR): wait_until() failed. Predicate: ''''
lambda: rpc.getmempoolinfo()["loaded"],
'''
2023-05-26T16:11:19.720000Z TestFramework (ERROR): Assertion failed
Traceback (most recent call last):
File "/work/test/functional/test_framework/test_framework.py", line 142, in main
self.run_test()
File "/work/test/functional/chronik_shutdown.py", line 72, in run_test
self.restart_node(0, ["-chronik", "-reindex"])
File "/work/test/functional/test_framework/test_framework.py", line 645, in restart_node
self.start_node(i, extra_args)
File "/work/test/functional/test_framework/test_framework.py", line 603, in start_node
node.wait_for_rpc_connection()
File "/work/test/functional/test_framework/test_node.py", line 366, in wait_for_rpc_connection
wait_until_helper(
File "/work/test/functional/test_framework/util.py", line 298, in wait_until_helper
raise AssertionError(
AssertionError: Predicate ''''
lambda: rpc.getmempoolinfo()["loaded"],
''' not true after 60.0 seconds
2023-05-26T16:11:19.773000Z TestFramework (INFO): Stopping nodes
[node 0] Cleaning up leftover process
------- Stderr: -------
Traceback (most recent call last):
File "/work/test/functional/chronik_shutdown.py", line 76, in <module>
ChronikShutdown().main()
File "/work/test/functional/test_framework/test_framework.py", line 165, in main
exit_code = self.shutdown()
File "/work/test/functional/test_framework/test_framework.py", line 391, in shutdown
self.stop_nodes()
File "/work/test/functional/test_framework/test_framework.py", line 636, in stop_nodes
node.stop_node(wait=wait, wait_until_stopped=False)
File "/work/test/functional/test_framework/test_node.py", line 503, in stop_node
self.stop(wait=wait)
File "/work/test/functional/test_framework/test_node.py", line 279, in __getattr__
assert self.rpc is not None, self._node_msg("Error: RPC not initialized")
AssertionError: [node 0] Error: RPC not initializedEach failure log is accessible here:
Bitcoin ABC functional tests: chronik_shutdown.py
use stop_nodes instead of restart_node, same segfault but restart doesn't time out on ARM
@bot build-linux32 build-linux64 build-linux-aarch64 build-linux-arm build-osx build-win64
Failed tests logs:
====== Bitcoin ABC functional tests: chronik_shutdown.py ======
------- Stdout: -------
2023-05-27T09:33:24.051000Z TestFramework (INFO): Initializing test directory /work/abc-ci-builds/build-linux64/test/tmp/test_runner_₿₵_ _20230527_092900/chronik_shutdown_233
2023-05-27T09:34:28.441000Z TestFramework (ERROR): Assertion failed
Traceback (most recent call last):
File "/work/test/functional/test_framework/test_framework.py", line 142, in main
self.run_test()
File "/work/test/functional/chronik_shutdown.py", line 72, in run_test
self.stop_nodes()
File "/work/test/functional/test_framework/test_framework.py", line 640, in stop_nodes
node.wait_until_stopped()
File "/work/test/functional/test_framework/test_node.py", line 548, in wait_until_stopped
wait_until_helper(
File "/work/test/functional/test_framework/util.py", line 285, in wait_until_helper
if predicate():
File "/work/test/functional/test_framework/test_node.py", line 537, in is_node_stopped
assert return_code == 0, self._node_msg(
AssertionError: [node 0] Node returned non-zero exit code (-11) when stopping
2023-05-27T09:34:28.500000Z TestFramework (INFO): Stopping nodes
[node 0] Cleaning up leftover process
------- Stderr: -------
Traceback (most recent call last):
File "/work/test/functional/chronik_shutdown.py", line 76, in <module>
ChronikShutdown().main()
File "/work/test/functional/test_framework/test_framework.py", line 165, in main
exit_code = self.shutdown()
File "/work/test/functional/test_framework/test_framework.py", line 391, in shutdown
self.stop_nodes()
File "/work/test/functional/test_framework/test_framework.py", line 636, in stop_nodes
node.stop_node(wait=wait, wait_until_stopped=False)
File "/work/test/functional/test_framework/test_node.py", line 503, in stop_node
self.stop(wait=wait)
File "/work/test/functional/test_framework/coverage.py", line 47, in __call__
return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
File "/work/test/functional/test_framework/authproxy.py", line 176, in __call__
response, status = self._request(
File "/work/test/functional/test_framework/authproxy.py", line 125, in _request
self.__conn.request(method, path, postdata, headers)
File "/usr/lib/python3.9/http/client.py", line 1255, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib/python3.9/http/client.py", line 1301, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/lib/python3.9/http/client.py", line 1250, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.9/http/client.py", line 1010, in _send_output
self.send(msg)
File "/usr/lib/python3.9/http/client.py", line 950, in send
self.connect()
File "/usr/lib/python3.9/http/client.py", line 921, in connect
self.sock = self._create_connection(
File "/usr/lib/python3.9/socket.py", line 843, in create_connection
raise err
File "/usr/lib/python3.9/socket.py", line 831, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refusedEach failure log is accessible here:
Bitcoin ABC functional tests: chronik_shutdown.py
@bot build-linux32 build-linux64 build-linux-aarch64 build-linux-arm build-osx build-win64