Compare commits

...

93 Commits

Author SHA1 Message Date
Pratik Mankawde
3d494ee2a3 remove ignored files
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-23 16:41:39 +00:00
Pratik Mankawde
5a0b032925 Apply suggestion from @pratikmankawde 2026-02-23 16:40:34 +00:00
Pratik Mankawde
6d0d0b7a9c remove files from ignore list for asan 2026-02-23 16:37:45 +00:00
Pratik Mankawde
f6cb683ab2 add supp for gcc
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-20 14:43:16 +00:00
Pratik Mankawde
c5d650418c increase timeout
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-20 13:03:31 +00:00
Pratik Mankawde
d9f54113b3 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-20 12:14:36 +00:00
Pratik Mankawde
b22038d92f detect_stack_use_after_return=0 2026-02-19 17:38:06 +00:00
Pratik Mankawde
2f60ce71ff ignore alloc-dealloc mismatch for gcc and removed detect_stack_use_after_return=0
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-19 16:55:50 +00:00
Pratik Mankawde
c9ff20d729 Apply suggestion from @pratikmankawde
try detecting alloc_dealloc_mismatch
2026-02-19 15:29:38 +00:00
Pratik Mankawde
c2fd60dc46 added more flags
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-19 14:35:33 +00:00
Pratik Mankawde
ae4ab7d462 added two options to asan_options
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-19 14:25:39 +00:00
Pratik Mankawde
95a43f3f90 Merge branch 'pratik/Fix_asan_lsan_flagged_issues' of github.com:XRPLF/rippled into pratik/Fix_asan_lsan_flagged_issues 2026-02-19 14:13:21 +00:00
Pratik Mankawde
96187a0da8 ignore boost headers from sanitizing
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-19 14:13:11 +00:00
Pratik Mankawde
e4831258b6 remove debug=true to check if this reduces load on ci 2026-02-19 12:13:41 +00:00
Pratik Mankawde
7a7a864611 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-18 15:43:05 +00:00
Pratik Mankawde
aa3c4fbcc4 Apply suggestion from @pratikmankawde 2026-02-18 15:42:54 +00:00
Pratik Mankawde
c4a94bb000 do not fix the stack size
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-17 17:20:17 +00:00
Pratik Mankawde
5e3342c48d increase timeout
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-17 13:23:10 +00:00
Pratik Mankawde
ac7ddd0cef reverted change in Number
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-16 18:39:14 +00:00
Pratik Mankawde
eebdb58107 halt on error = 0
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-16 17:50:36 +00:00
Pratik Mankawde
4d43f2e083 remove printXXX from asan rt args
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-16 17:44:27 +00:00
Pratik Mankawde
b08b14c2cd remove symbolize option from asan
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-16 16:14:29 +00:00
Pratik Mankawde
a8ee7ef316 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-16 15:53:44 +00:00
Pratik Mankawde
e75ffc7c25 only run asan 2026-02-15 13:46:51 +00:00
Pratik Mankawde
ea2ab17b95 supp. coro releated asan errors
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-13 16:53:08 +00:00
Pratik Mankawde
358c6d95bf run sanitizer tests in parallel
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-13 16:07:11 +00:00
Pratik Mankawde
f8fcccd684 Merge remote-tracking branch 'origin/develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-13 13:11:22 +00:00
Pratik Mankawde
484fc4ce9a increase timeout for sanitizer jobs
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-13 12:32:38 +00:00
Pratik Mankawde
81a18efb9e removing timeout changes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-12 18:10:37 +00:00
Pratik Mankawde
d70ac27f0c increase timeout for sanitizer builds, since we are seeing timeouts
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-12 18:03:13 +00:00
Pratik Mankawde
496354f1c9 increase stack size of coroutine
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-12 16:38:57 +00:00
Pratik Mankawde
eb2b421cd6 unreachable return
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-12 15:21:20 +00:00
Pratik Mankawde
1a737ebb49 remove recursion from the ApplyStateTable::read and add flat call ApplyStateTable::readLocal
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-12 14:46:32 +00:00
Pratik Mankawde
d6e9986502 Silent uninitialized warning in gcc-14
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-12 12:42:35 +00:00
Pratik Mankawde
253fbf6e83 removed -flarge-source-files flag
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-12 12:30:44 +00:00
Pratik Mankawde
e6455035d5 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-12 12:23:38 +00:00
Pratik Mankawde
6029c65aa1 revert the LocalValue change
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-12 12:18:05 +00:00
Pratik Mankawde
52c7d980d4 fix to the list issue
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-11 15:00:12 +00:00
Pratik Mankawde
5982519fe0 minor correction
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-11 14:39:01 +00:00
Pratik Mankawde
8dd147d5e8 set defines
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-11 14:00:33 +00:00
Pratik Mankawde
7b36580552 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-11 11:48:28 +00:00
Pratik Mankawde
5b4c49f47b remove coroutine2 from cmake dependency since it is a header lib
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-10 16:19:11 +00:00
Pratik Mankawde
d5a4f36632 ucontext, coroutine2 and for boost asan build
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-10 15:31:13 +00:00
Pratik Mankawde
011f0a6320 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-10 13:34:52 +00:00
Pratik Mankawde
654829294e moved settings to profle
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-10 13:34:29 +00:00
Pratik Mankawde
68c9b20f2d Force build boost with asan
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-10 12:46:23 +00:00
Pratik Mankawde
69597e4b3b switch to coroutine2 and remove string caching
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-06 13:46:04 +00:00
Pratik Mankawde
65ba439117 cache strings to solve stack-use-after-scope
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-06 12:30:17 +00:00
Pratik Mankawde
14e3e098d5 change coroutine stack size to 4MB.
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-06 11:57:52 +00:00
Pratik Mankawde
1a14b813b8 removed malloc_context_size=30, fast_unwind_on_malloc=0 because they were slowing down the runs
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-05 19:08:34 +00:00
Pratik Mankawde
95c9851146 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-05 18:33:24 +00:00
Pratik Mankawde
127f44a40b fix stack-use-after-scope issue
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-05 18:19:32 +00:00
Pratik Mankawde
acca1c73cf reset verbosity back to 0
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-05 17:24:01 +00:00
Pratik Mankawde
567433d272 removing comments from the asan options
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-05 16:47:20 +00:00
Pratik Mankawde
4600c381b9 stack-buffer-overflow in coroutines.
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-05 16:34:45 +00:00
Pratik Mankawde
be28f4d489 fixing issue with ScopedStream stack-use-after-scope
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-05 16:14:43 +00:00
Pratik Mankawde
413aee0752 silence stack-buffer-overflow
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-05 15:10:36 +00:00
Pratik Mankawde
6b16a5a8ed Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-05 13:41:01 +00:00
Pratik Mankawde
fd53813746 more ASAN fixes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-05 13:40:26 +00:00
Pratik Mankawde
bbb03e153e fixed asan escape macro before return type
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-04 15:54:50 +00:00
Pratik Mankawde
63b6ec98ea added comments and haltonerror=false
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-04 15:45:03 +00:00
Pratik Mankawde
7ef9fb4290 remove suppressions
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-04 14:31:03 +00:00
Pratik Mankawde
49dcb6b60b fix memory leak in LocalValue
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-04 13:17:31 +00:00
Pratik Mankawde
26dd1fafe3 run parallel tests
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-04 11:28:24 +00:00
Pratik Mankawde
4b99771021 Don't copy the Json::StaticString
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-04 11:24:54 +00:00
Pratik Mankawde
e6664fe4cf Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-02-03 18:27:52 +00:00
Pratik Mankawde
b5001bc258 fixes to static variable destruction issue.
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-03 18:27:00 +00:00
Pratik Mankawde
5dacfa1938 clang-format updates
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-03 15:04:16 +00:00
Pratik Mankawde
394b256f02 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-03 15:03:34 +00:00
Pratik Mankawde
5bfa38f6c5 ssl context cleanup.
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-03 15:00:37 +00:00
Pratik Mankawde
7c6c49bf98 run tests in serial
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-28 16:35:45 +00:00
Pratik Mankawde
6334be1ff0 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-28 15:33:49 +00:00
Pratik Mankawde
a9c3bb84ba fixes to Number. run et even when st fails
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-28 15:30:05 +00:00
Pratik Mankawde
ca99e40290 fix memory leak.
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-28 14:49:40 +00:00
Pratik Mankawde
7612c1af0c suppress leaks in boost
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-28 14:39:43 +00:00
Pratik Mankawde
67e40be1ab run embedded test even if separate tests fails.
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-28 13:56:24 +00:00
Pratik Mankawde
0132174a7b remove boost from supps.
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-28 13:42:36 +00:00
Pratik Mankawde
8773cc4bbf Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-01-28 13:21:47 +00:00
Pratik Mankawde
dabdadfff5 Merge branch 'develop' into pratik/Fix_asan_lsan_flagged_issues 2026-01-27 15:20:10 +00:00
Pratik Mankawde
bfe2cd7893 comment out assert
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-27 15:17:48 +00:00
Pratik Mankawde
0584c20f36 updated flags
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-27 13:43:03 +00:00
Pratik Mankawde
3ced0b27b7 not using -fsanitize-recover
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-27 13:20:46 +00:00
Pratik Mankawde
f83b27f7dd putting assert back since this is the cause of asan issue
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-27 12:27:11 +00:00
Pratik Mankawde
cdb41b5376 comment out assert in Number.cpp to verify if asan is strugling with asserts
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-27 11:54:26 +00:00
Pratik Mankawde
f223c89a9f replaced throw with Throw and supp static_assert
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-27 10:50:38 +00:00
Pratik Mankawde
efe07c09f3 assert supp
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-26 19:14:58 +00:00
Pratik Mankawde
79cde8b199 skip assert
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-26 17:40:04 +00:00
Pratik Mankawde
2078ce01cf try shamap fix
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-26 15:50:47 +00:00
Pratik Mankawde
2770a9cdf3 fixes to asan errors
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-26 14:55:18 +00:00
Pratik Mankawde
05ef3b1ad8 more fixes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-23 18:28:09 +00:00
Pratik Mankawde
7dd4dbe285 fixes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-23 17:13:03 +00:00
Pratik Mankawde
b32a5f2c08 supressions and jsonvalue fixes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-23 16:20:50 +00:00
Pratik Mankawde
df76002a44 fixed asan issues
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-23 15:39:21 +00:00
37 changed files with 322 additions and 117 deletions

View File

@@ -236,21 +236,23 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# names get truncated.
# Add Address and Thread (both coupled with UB) sanitizers for specific bookworm distros.
# GCC-Asan rippled-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
if (
os["distro_version"] == "bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
):
if os[
"distro_version"
] == "bookworm" and f"{os['compiler_name']}-{os['compiler_version']}" in [
"clang-20",
"gcc-13",
]:
# Add ASAN + UBSAN configuration.
configurations.append(
{
"config_name": config_name + "-asan-ubsan",
"config_name": config_name + "-asan",
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "address,undefinedbehavior",
"sanitizers": "address",
}
)
# TSAN is deactivated due to seg faults with latest compilers.

View File

@@ -76,7 +76,8 @@ jobs:
name: ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }}
timeout-minutes: 60
# Sanitizer builds on GCC are taking longer than 60mins. Hence increasing the timeout to 90mins.
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 60 }}
env:
# Use a namespace to keep the objects separate for each configuration.
CCACHE_NAMESPACE: ${{ inputs.config_name }}
@@ -205,14 +206,22 @@ jobs:
- name: Set sanitizer options
if: ${{ !inputs.build_only && env.SANITIZERS_ENABLED == 'true' }}
run: |
echo "ASAN_OPTIONS=print_stacktrace=1:detect_container_overflow=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp" >> ${GITHUB_ENV}
echo "TSAN_OPTIONS=second_deadlock_stack=1:halt_on_error=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
echo "UBSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
echo "LSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
ASAN_OPTS="include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-asan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp"
if [[ "${{ inputs.config_name }}" == *gcc* ]]; then
ASAN_OPTS="${ASAN_OPTS}:alloc_dealloc_mismatch=0"
fi
echo "ASAN_OPTIONS=${ASAN_OPTS}" >> ${GITHUB_ENV}
echo "TSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-tsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
echo "UBSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
echo "LSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-lsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
- name: Run the separate tests
# We continue on error here because we want to try the Embedded tests before
# failing. This will give us details on all the failures at once.
continue-on-error: true
if: ${{ !inputs.build_only }}
working-directory: ${{ env.BUILD_DIR }}
id: separate_tests
# Windows locks some of the build files while running tests, and parallel jobs can collide
env:
BUILD_TYPE: ${{ inputs.build_type }}
@@ -228,8 +237,14 @@ jobs:
working-directory: ${{ runner.os == 'Windows' && format('{0}/{1}', env.BUILD_DIR, inputs.build_type) || env.BUILD_DIR }}
env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
PARALLELISM: ${{ env.SANITIZERS_ENABLED == 'true' && steps.nproc.outputs.nproc || steps.nproc.outputs.nproc }}
run: |
./xrpld --unittest --unittest-jobs "${BUILD_NPROC}"
./xrpld --unittest --unittest-jobs "${PARALLELISM}"
# Pipeline should fail if the separate tests failed.
- name: Check results of the SeparateTests
if: ${{ !inputs.build_only && steps.separate_tests.outcome == 'failure' }}
run: exit 1
- name: Debug failure (Linux)
if: ${{ failure() && runner.os == 'Linux' && !inputs.build_only }}

View File

@@ -17,12 +17,10 @@ find_dependency(Boost
chrono
container
context
coroutine
date_time
filesystem
program_options
regex
system
thread)
#[=========================================================[
OpenSSL

View File

@@ -22,7 +22,7 @@ target_compile_definitions(
BOOST_FILESYSTEM_NO_DEPRECATED
>
$<$<NOT:$<BOOL:${boost_show_deprecated}>>:
BOOST_COROUTINES_NO_DEPRECATION_WARNING
BOOST_COROUTINES2_NO_DEPRECATION_WARNING
BOOST_BEAST_ALLOW_DEPRECATED
BOOST_FILESYSTEM_DEPRECATED
>

View File

@@ -4,13 +4,12 @@ include(XrplSanitizers)
find_package(Boost REQUIRED
COMPONENTS chrono
container
coroutine
context
date_time
filesystem
json
program_options
regex
system
thread)
add_library(xrpl_boost INTERFACE)
@@ -21,7 +20,7 @@ target_link_libraries(
INTERFACE Boost::headers
Boost::chrono
Boost::container
Boost::coroutine
Boost::context
Boost::date_time
Boost::filesystem
Boost::json
@@ -32,6 +31,26 @@ target_link_libraries(
if (Boost_COMPILER)
target_link_libraries(xrpl_boost INTERFACE Boost::disable_autolinking)
endif ()
# GCC 14+ has a false positive -Wuninitialized warning in Boost.Coroutine2's
# state.hpp when compiled with -O3. This is due to GCC's intentional behavior
# change (Bug #98871, #119388) where warnings from inlined system header code
# are no longer suppressed by -isystem. The warning occurs in operator|= in
# boost/coroutine2/detail/state.hpp when inlined from push_control_block::destroy().
# See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119388
if (is_gcc AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 14)
target_compile_options(xrpl_boost INTERFACE -Wno-uninitialized)
endif ()
# Boost.Context's ucontext backend has ASAN fiber-switching annotations
# (start/finish_switch_fiber) that are compiled in when BOOST_USE_ASAN is defined.
# This tells ASAN about coroutine stack switches, preventing false positive
# stack-use-after-scope errors. BOOST_USE_UCONTEXT ensures the ucontext backend
# is selected (fcontext does not support ASAN annotations).
# These defines must match what Boost was compiled with (see conan/profiles/sanitizers).
if (enable_asan)
target_compile_definitions(xrpl_boost INTERFACE BOOST_USE_ASAN BOOST_USE_UCONTEXT)
endif ()
if (SANITIZERS_ENABLED AND is_clang)
# TODO: gcc does not support -fsanitize-blacklist...can we do something else for gcc ?
if (NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)

View File

@@ -7,16 +7,21 @@ include(default)
{% if compiler == "gcc" %}
{% if "address" in sanitizers or "thread" in sanitizers or "undefinedbehavior" in sanitizers %}
{% set sanitizer_list = [] %}
{% set defines = [] %}
{% set model_code = "" %}
{% set extra_cxxflags = ["-fno-omit-frame-pointer", "-O1", "-Wno-stringop-overflow"] %}
{% if "address" in sanitizers %}
{% set _ = sanitizer_list.append("address") %}
{% set model_code = "-mcmodel=large" %}
{% set _ = defines.append("BOOST_USE_ASAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% elif "thread" in sanitizers %}
{% set _ = sanitizer_list.append("thread") %}
{% set model_code = "-mcmodel=medium" %}
{% set _ = extra_cxxflags.append("-Wno-tsan") %}
{% set _ = defines.append("BOOST_USE_TSAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% endif %}
{% if "undefinedbehavior" in sanitizers %}
@@ -29,16 +34,22 @@ include(default)
tools.build:cxxflags+=['{{sanitizer_flags}} {{" ".join(extra_cxxflags)}}']
tools.build:sharedlinkflags+=['{{sanitizer_flags}}']
tools.build:exelinkflags+=['{{sanitizer_flags}}']
tools.build:defines+={{defines}}
{% endif %}
{% elif compiler == "apple-clang" or compiler == "clang" %}
{% if "address" in sanitizers or "thread" in sanitizers or "undefinedbehavior" in sanitizers %}
{% set sanitizer_list = [] %}
{% set defines = [] %}
{% set extra_cxxflags = ["-fno-omit-frame-pointer", "-O1"] %}
{% if "address" in sanitizers %}
{% set _ = sanitizer_list.append("address") %}
{% set _ = defines.append("BOOST_USE_ASAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% elif "thread" in sanitizers %}
{% set _ = sanitizer_list.append("thread") %}
{% set _ = defines.append("BOOST_USE_TSAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% endif %}
{% if "undefinedbehavior" in sanitizers %}
@@ -52,8 +63,24 @@ include(default)
tools.build:cxxflags+=['{{sanitizer_flags}} {{" ".join(extra_cxxflags)}}']
tools.build:sharedlinkflags+=['{{sanitizer_flags}}']
tools.build:exelinkflags+=['{{sanitizer_flags}}']
tools.build:defines+={{defines}}
{% endif %}
{% endif %}
{% endif %}
tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags"]
tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags", "tools.build:defines"]
[options]
{% if sanitizers %}
{% if "address" in sanitizers %}
# Build Boost.Context with ucontext backend (not fcontext) so that
# ASAN fiber-switching annotations (__sanitizer_start/finish_switch_fiber)
# are compiled into the library. fcontext (assembly) has no ASAN support.
# define=BOOST_USE_ASAN=1 is critical: it must be defined when building
# Boost.Context itself so the ucontext backend compiles in the ASAN annotations.
boost/*:extra_b2_flags=context-impl=ucontext address-sanitizer=on define=BOOST_USE_ASAN=1
boost/*:without_context=False
# Boost stacktrace fails to build with some sanitizers
boost/*:without_stacktrace=True
{% endif %}
{% endif %}

View File

@@ -1,4 +1,5 @@
import re
import os
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
@@ -57,6 +58,9 @@ class Xrpl(ConanFile):
"tests": False,
"unity": False,
"xrpld": False,
"boost/*:without_context": False,
"boost/*:without_coroutine": True,
"boost/*:without_coroutine2": False,
"date/*:header_only": True,
"ed25519/*:shared": False,
"grpc/*:shared": False,
@@ -125,6 +129,14 @@ class Xrpl(ConanFile):
self.options["boost"].visibility = "global"
if self.settings.compiler in ["clang", "gcc"]:
self.options["boost"].without_cobalt = True
self.options["boost"].without_context = False
self.options["boost"].without_coroutine = True
self.options["boost"].without_coroutine2 = False
# Check if environment variable exists
if "SANITIZERS" in os.environ:
sanitizers = os.environ["SANITIZERS"]
if "address" in sanitizers.lower():
self.default_options["fPIC"] = False
def requirements(self):
# Conan 2 requires transitive headers to be specified
@@ -196,7 +208,8 @@ class Xrpl(ConanFile):
"boost::headers",
"boost::chrono",
"boost::container",
"boost::coroutine",
"boost::context",
"boost::coroutine2",
"boost::date_time",
"boost::filesystem",
"boost::json",

View File

@@ -99,8 +99,10 @@ words:
- endmacro
- exceptioned
- Falco
- fcontext
- finalizers
- firewalled
- flackiness
- fmtdur
- fsanitize
- funclets
@@ -111,6 +113,7 @@ words:
- gpgcheck
- gpgkey
- hotwallet
- hwaddress
- hwrap
- ifndef
- inequation
@@ -174,6 +177,7 @@ words:
- nftpage
- nikb
- nonxrp
- norecover
- noripple
- nudb
- nullptr
@@ -233,6 +237,7 @@ words:
- soci
- socidb
- sslws
- stackful
- statsd
- STATSDCOLLECTOR
- stissue

View File

@@ -89,8 +89,8 @@ cmake --build . --parallel 4
**IMPORTANT**: ASAN with Boost produces many false positives. Use these options:
```bash
export ASAN_OPTIONS="print_stacktrace=1:detect_container_overflow=0:suppressions=path/to/asan.supp:halt_on_error=0:log_path=asan.log"
export LSAN_OPTIONS="suppressions=path/to/lsan.supp:halt_on_error=0:log_path=lsan.log"
export ASAN_OPTIONS="include=sanitizers/suppressions/runtime-asan-options.txt:suppressions=sanitizers/suppressions/asan.supp"
export LSAN_OPTIONS="include=sanitizers/suppressions/runtime-lsan-options.txt:suppressions=sanitizers/suppressions/lsan.supp"
# Run tests
./xrpld --unittest --unittest-jobs=5
@@ -108,7 +108,7 @@ export LSAN_OPTIONS="suppressions=path/to/lsan.supp:halt_on_error=0:log_path=lsa
### ThreadSanitizer (TSan)
```bash
export TSAN_OPTIONS="suppressions=path/to/tsan.supp halt_on_error=0 log_path=tsan.log"
export TSAN_OPTIONS="include=sanitizers/suppressions/runtime-tsan-options.txt:suppressions=sanitizers/suppressions/tsan.supp"
# Run tests
./xrpld --unittest --unittest-jobs=5
@@ -129,7 +129,7 @@ More details [here](https://github.com/google/sanitizers/wiki/AddressSanitizerLe
### UndefinedBehaviorSanitizer (UBSan)
```bash
export UBSAN_OPTIONS="suppressions=path/to/ubsan.supp:print_stacktrace=1:halt_on_error=0:log_path=ubsan.log"
export UBSAN_OPTIONS="include=sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=sanitizers/suppressions/ubsan.supp"
# Run tests
./xrpld --unittest --unittest-jobs=5

View File

@@ -359,6 +359,7 @@ public:
base_uint&
operator&=(base_uint const& b)
{
XRPL_ASSERT(WIDTH == b.WIDTH, "input size mismatch");
for (int i = 0; i < WIDTH; i++)
data_[i] &= b.data_[i];

View File

@@ -1,5 +1,6 @@
#pragma once
#include <xrpl/basics/sanitizers.h>
#include <xrpl/beast/type_name.h>
#include <exception>
@@ -24,7 +25,7 @@ LogThrow(std::string const& title);
control to the next matching exception handler, if any.
Otherwise, std::terminate will be called.
*/
[[noreturn]] inline void
[[noreturn]] XRPL_NO_SANITIZE_ADDRESS inline void
Rethrow()
{
LogThrow("Re-throwing exception");
@@ -32,7 +33,7 @@ Rethrow()
}
template <class E, class... Args>
[[noreturn]] inline void
[[noreturn]] XRPL_NO_SANITIZE_ADDRESS inline void
Throw(Args&&... args)
{
static_assert(

View File

@@ -0,0 +1,6 @@
// Helper to disable ASan/HwASan for specific functions
#if defined(__GNUC__) || defined(__clang__)
#define XRPL_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address", "hwaddress")))
#else
#define XRPL_NO_SANITIZE_ADDRESS
#endif

View File

@@ -1,7 +1,5 @@
#pragma once
#include <xrpl/basics/ByteUtilities.h>
namespace xrpl {
template <class F>
@@ -10,17 +8,15 @@ JobQueue::Coro::Coro(Coro_create_t, JobQueue& jq, JobType type, std::string cons
, type_(type)
, name_(name)
, running_(false)
, coro_(
[this, fn = std::forward<F>(f)](
boost::coroutines::asymmetric_coroutine<void>::push_type& do_yield) {
yield_ = &do_yield;
yield();
fn(shared_from_this());
, coro_([this, fn = std::forward<F>(f)](
boost::coroutines2::asymmetric_coroutine<void>::push_type& do_yield) {
yield_ = &do_yield;
yield();
fn(shared_from_this());
#ifndef NDEBUG
finished_ = true;
finished_ = true;
#endif
},
boost::coroutines::attributes(megabytes(1)))
})
{
}
@@ -80,6 +76,7 @@ JobQueue::Coro::resume()
coro_();
detail::getLocalValues().release();
detail::getLocalValues().reset(saved);
std::lock_guard lk(mutex_run_);
running_ = false;
cv_.notify_all();

View File

@@ -7,7 +7,7 @@
#include <xrpl/core/detail/Workers.h>
#include <xrpl/json/json_value.h>
#include <boost/coroutine/all.hpp>
#include <boost/coroutine2/all.hpp>
#include <set>
@@ -48,8 +48,8 @@ public:
std::mutex mutex_;
std::mutex mutex_run_;
std::condition_variable cv_;
boost::coroutines::asymmetric_coroutine<void>::pull_type coro_;
boost::coroutines::asymmetric_coroutine<void>::push_type* yield_;
boost::coroutines2::coroutine<void>::pull_type coro_;
boost::coroutines2::coroutine<void>::push_type* yield_;
#ifndef NDEBUG
bool finished_ = false;
#endif

View File

@@ -64,6 +64,11 @@ public:
std::shared_ptr<SLE const>
read(ReadView const& base, Keylet const& k) const;
/** Check only local items without delegating to base.
Returns std::nullopt if key not found locally. */
std::optional<std::shared_ptr<SLE const>>
readLocal(Keylet const& k) const;
std::shared_ptr<SLE>
peek(ReadView const& base, Keylet const& k);

View File

@@ -29,6 +29,9 @@ public:
bool sslVerify,
beast::Journal j);
static void
cleanupSSLContext();
static void
get(bool bSSL,
boost::asio::io_context& io_context,

View File

@@ -234,7 +234,7 @@ missing_field_error(std::string const& name)
}
inline Json::Value
missing_field_error(Json::StaticString name)
missing_field_error(Json::StaticString const& name)
{
return missing_field_error(std::string(name));
}
@@ -252,7 +252,7 @@ object_field_error(std::string const& name)
}
inline Json::Value
object_field_error(Json::StaticString name)
object_field_error(Json::StaticString const& name)
{
return object_field_error(std::string(name));
}
@@ -264,7 +264,7 @@ invalid_field_message(std::string const& name)
}
inline std::string
invalid_field_message(Json::StaticString name)
invalid_field_message(Json::StaticString const& name)
{
return invalid_field_message(std::string(name));
}
@@ -276,7 +276,7 @@ invalid_field_error(std::string const& name)
}
inline Json::Value
invalid_field_error(Json::StaticString name)
invalid_field_error(Json::StaticString const& name)
{
return invalid_field_error(std::string(name));
}
@@ -288,7 +288,7 @@ expected_field_message(std::string const& name, std::string const& type)
}
inline std::string
expected_field_message(Json::StaticString name, std::string const& type)
expected_field_message(Json::StaticString const& name, std::string const& type)
{
return expected_field_message(std::string(name), type);
}
@@ -300,7 +300,7 @@ expected_field_error(std::string const& name, std::string const& type)
}
inline Json::Value
expected_field_error(Json::StaticString name, std::string const& type)
expected_field_error(Json::StaticString const& name, std::string const& type)
{
return expected_field_error(std::string(name), type);
}

View File

@@ -46,6 +46,17 @@ public:
return id_;
}
/**
* Get the SHAMapNodeID of a child node at the specified branch.
*
* @param m The branch number (0-15) indicating which child to descend to.
* In the SHAMap's 16-way radix tree, each inner node has up to
* 16 children, indexed by the corresponding nibble (4 bits) of
* the key at the current depth.
* @return SHAMapNodeID of the child node at branch m.
* @throws std::logic_error if this node is at the maximum leaf depth (64)
* or if the node's id doesn't match its depth mask.
*/
SHAMapNodeID
getChildNodeID(unsigned int m) const;

View File

@@ -1,29 +1,29 @@
# The idea is to empty this file gradually by fixing the underlying issues and removing suppressions.
# The idea is to empty this file gradually by fixing the underlying issues and removing suppresions.
#
# ASAN_OPTIONS="print_stacktrace=1:detect_container_overflow=0:suppressions=sanitizers/suppressions/asan.supp:halt_on_error=0"
# ASAN_OPTIONS="suppressions=sanitizers/suppressions/asan.supp:include=sanitizers/suppressions/runtime-asan-options.txt"
#
# The detect_container_overflow=0 option disables false positives from:
# - Boost intrusive containers (slist_iterator.hpp, hashtable.hpp, aged_unordered_container.h)
# - Boost context/coroutine stack switching (Workers.cpp, thread.h)
# Boost coroutines cause multiple ASAN false positives due to swapcontext/fiber stack switching.
# ASAN cannot correctly track stack memory across coroutine context switches, leading to:
# - stack-use-after-return errors
# - stack-use-after-scope errors
# - stack-buffer-overflow errors in seemingly unrelated code (e.g., std::chrono::steady_clock::now())
# - stack-buffer-underflow errors in seemingly unrelated code (e.g., xxhasher::retrieveHash(), clock_gettime)
# - bad-free errors in boost::context::basic_fixedsize_stack::deallocate (ASan loses track of
# malloc allocations after fiber/context switches, reporting "free on address not malloc()-ed")
#
# See: https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow
# These are now handled by:
# 1. Using Boost.Coroutine2 with the ucontext backend (BOOST_USE_ASAN + BOOST_USE_UCONTEXT)
# 2. Runtime options in runtime-asan-options.txt:
# - alloc_dealloc_mismatch=0: Suppresses false "bad-free" errors from fiber stack deallocation, on GCC. For Clang we don't instrument boost
# - detect_stack_use_after_return=0: Prevents false positives from fake stack tracking
# - use_sigaltstack=0: Avoids conflicts with coroutine stack switching
interceptor_via_fun:swapcontext
interceptor_via_fun:makecontext
interceptor_via_fun:boost::context::fiber::~fiber
interceptor_name:boost/context/fiber_ucontext.hpp
interceptor_name:boost/context/fixedsize_stack.hpp
interceptor_name:Coro.ipp
# Boost
interceptor_name:boost/asio
# Leaks in Doctest tests: xrpl.test.*
interceptor_name:src/libxrpl/net/HTTPClient.cpp
interceptor_name:src/libxrpl/net/RegisterSSLCerts.cpp
interceptor_name:src/tests/libxrpl/net/HTTPClient.cpp
interceptor_name:xrpl/net/AutoSocket.h
interceptor_name:xrpl/net/HTTPClient.h
interceptor_name:xrpl/net/HTTPClientSSLContext.h
interceptor_name:xrpl/net/RegisterSSLCerts.h
# Suppress false positive stack-buffer errors in thread stack allocation
# Related to ASan's __asan_handle_no_return warnings (github.com/google/sanitizers/issues/189)
# These occur during multi-threaded test initialization on macOS
interceptor_name:memcpy
interceptor_name:clock_gettime
interceptor_name:__bzero
interceptor_name:__asan_memset
interceptor_name:__asan_memcpy
interceptor_name:nudb

View File

@@ -1,16 +1,13 @@
# The idea is to empty this file gradually by fixing the underlying issues and removing suppresions.
# Suppress leaks detected by asan in rippled code.
leak:src/libxrpl/net/HTTPClient.cpp
leak:src/libxrpl/net/RegisterSSLCerts.cpp
leak:src/tests/libxrpl/net/HTTPClient.cpp
leak:xrpl/net/AutoSocket.h
leak:xrpl/net/HTTPClient.h
leak:xrpl/net/HTTPClientSSLContext.h
leak:xrpl/net/RegisterSSLCerts.h
leak:ripple::HTTPClient
leak:ripple::HTTPClientImp
# Suppress leaks detected by asan in boost code.
leak:boost::asio
leak:boost/asio
# These are false positives from Boost.Asio SSL internals that use OpenSSL BIO structures.
# The BIO structures are managed by OpenSSL's internal reference counting and freed at process exit.
#leak:boost::asio
#leak:boost/asio
# OpenSSL BIO memory is managed internally and freed at process exit
leak:CRYPTO_malloc
leak:bio_make_pair
leak:BIO_new_bio_pair

View File

@@ -0,0 +1,5 @@
detect_container_overflow=0
detect_stack_use_after_return=0
halt_on_error=0
print_summary=true
use_sigaltstack=0

View File

@@ -0,0 +1 @@
halt_on_error=0

View File

@@ -0,0 +1,2 @@
halt_on_error=0
second_deadlock_stack=1

View File

@@ -0,0 +1 @@
halt_on_error=0

View File

@@ -20,10 +20,15 @@ signal:test/beast/beast_PropertyStream_test.cpp
signal:xrpld/core/detail/Workers.cpp
signal:xrpld/core/JobQueue.cpp
src:beast/utility/beast_Journal.cpp
src:beast/utility/beast_PropertyStream.cpp
src:core/detail/Workers.cpp
src:core/JobQueue.cpp
src:libxrpl/beast/utility/beast_Journal.cpp
src:test/beast/beast_PropertyStream_test.cpp
src:src/test/app/Invariants_test.cpp
# src:beast/utility/beast_Journal.cpp
# src:beast/utility/beast_PropertyStream.cpp
# src:core/detail/Workers.cpp
# src:core/JobQueue.cpp
# src:libxrpl/beast/utility/beast_Journal.cpp
# src:test/beast/beast_PropertyStream_test.cpp
# src:src/test/app/Invariants_test.cpp
# Boost coroutines cause false positive stack-buffer-underflow in xxhasher
# This is a known ASAN limitation with stackful coroutines
# See: https://github.com/google/sanitizers/issues/189
src:beast/hash/xxhasher.h

View File

@@ -140,6 +140,7 @@ unsigned-integer-overflow:src/libxrpl/protocol/tokens.cpp
unsigned-integer-overflow:src/libxrpl/shamap/SHAMap.cpp
unsigned-integer-overflow:src/test/app/Batch_test.cpp
unsigned-integer-overflow:src/test/app/Invariants_test.cpp
unsigned-integer-overflow:src/test/app/Loan_test.cpp
unsigned-integer-overflow:src/test/app/NFToken_test.cpp
unsigned-integer-overflow:src/test/app/Offer_test.cpp
unsigned-integer-overflow:src/test/app/Path_test.cpp

View File

@@ -0,0 +1,7 @@
#include <xrpl/basics/LocalValue.h>
namespace xrpl {
namespace detail {
} // namespace detail
} // namespace xrpl

View File

@@ -11,6 +11,7 @@
#include <numeric>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
@@ -107,7 +108,7 @@ public:
int& exponent,
internalrep const& minMantissa,
internalrep const& maxMantissa,
std::string location);
std::string_view location);
// Modify the result to the correctly rounded value
template <UnsignedMantissa T>
@@ -116,7 +117,7 @@ public:
// Modify the result to the correctly rounded value
void
doRound(rep& drops, std::string location);
doRound(rep& drops, std::string_view location);
private:
void
@@ -242,7 +243,7 @@ Number::Guard::doRoundUp(
int& exponent,
internalrep const& minMantissa,
internalrep const& maxMantissa,
std::string location)
std::string_view location)
{
auto r = round();
if (r == 1 || (r == 0 && (mantissa & 1) == 1))
@@ -258,7 +259,7 @@ Number::Guard::doRoundUp(
}
bringIntoRange(negative, mantissa, exponent, minMantissa);
if (exponent > maxExponent)
throw std::overflow_error(location);
Throw<std::overflow_error>(std::string(location));
}
template <UnsignedMantissa T>
@@ -284,7 +285,7 @@ Number::Guard::doRoundDown(
// Modify the result to the correctly rounded value
void
Number::Guard::doRound(rep& drops, std::string location)
Number::Guard::doRound(rep& drops, std::string_view location)
{
auto r = round();
if (r == 1 || (r == 0 && (drops & 1) == 1))
@@ -298,7 +299,7 @@ Number::Guard::doRound(rep& drops, std::string location)
// or "(maxRep + 1) / 10", neither of which will round up when
// converting to rep, though the latter might overflow _before_
// rounding.
throw std::overflow_error(location); // LCOV_EXCL_LINE
throw std::overflow_error(std::string(location)); // LCOV_EXCL_LINE
}
++drops;
}

View File

@@ -193,17 +193,17 @@ Value::Value(ValueType type) : type_(type), allocated_(0)
}
}
Value::Value(Int value) : type_(intValue)
Value::Value(Int value) : type_(intValue), allocated_(0)
{
value_.int_ = value;
}
Value::Value(UInt value) : type_(uintValue)
Value::Value(UInt value) : type_(uintValue), allocated_(0)
{
value_.uint_ = value;
}
Value::Value(double value) : type_(realValue)
Value::Value(double value) : type_(realValue), allocated_(0)
{
value_.real_ = value;
}
@@ -230,7 +230,7 @@ Value::Value(StaticString const& value) : type_(stringValue), allocated_(false)
value_.string_ = const_cast<char*>(value.c_str());
}
Value::Value(bool value) : type_(booleanValue)
Value::Value(bool value) : type_(booleanValue), allocated_(0)
{
value_.bool_ = value;
}

View File

@@ -335,6 +335,28 @@ ApplyStateTable::read(ReadView const& base, Keylet const& k) const
return sle;
}
std::optional<std::shared_ptr<SLE const>>
ApplyStateTable::readLocal(Keylet const& k) const
{
auto const iter = items_.find(k.key);
if (iter == items_.end())
return std::nullopt;
auto const& item = iter->second;
auto const& sle = item.second;
switch (item.first)
{
case Action::erase:
return nullptr;
case Action::cache:
case Action::insert:
case Action::modify:
break;
};
if (!k.check(*sle))
return nullptr;
return sle;
}
std::shared_ptr<SLE>
ApplyStateTable::peek(ReadView const& base, Keylet const& k)
{

View File

@@ -49,7 +49,24 @@ ApplyViewBase::succ(key_type const& key, std::optional<key_type> const& last) co
std::shared_ptr<SLE const>
ApplyViewBase::read(Keylet const& k) const
{
return items_.read(*base_, k);
// Iteratively walk up the chain of ApplyViewBase layers
// instead of recursing through items_.read(*base_, k).
auto const* current = this;
while (current)
{
if (auto result = current->items_.readLocal(k))
return *result;
// Check if the base is another ApplyViewBase layer
auto const* next = dynamic_cast<ApplyViewBase const*>(current->base_);
if (!next)
return current->base_->read(k);
current = next;
}
// Unreachable: current starts as `this` (non-null) and the loop
// always returns before current could become null.
UNREACHABLE("xrpl::ApplyViewBase::read : unreachable");
return nullptr;
}
auto

View File

@@ -26,6 +26,12 @@ HTTPClient::initializeSSLContext(
httpClientSSLContext.emplace(sslVerifyDir, sslVerifyFile, sslVerify, j);
}
void
HTTPClient::cleanupSSLContext()
{
httpClientSSLContext.reset();
}
//------------------------------------------------------------------------------
//
// Fetch a web page via http or https.

View File

@@ -1003,7 +1003,12 @@ amountFromJson(SField const& name, Json::Value const& v)
else if (v.isString())
{
std::string val = v.asString();
// Pre-allocate to avoid reallocation during split. This function is often
// called deep in the RPC stack (via JSON parsing) where stack space is
// limited. ASAN detected stack-buffer-overflow here at ~95% coroutine
// stack usage (1001376/1048576 bytes). Coroutine stack increased to 2MB.
std::vector<std::string> elements;
elements.reserve(3);
boost::split(elements, val, boost::is_any_of("\t\n\r ,/"));
if (elements.size() > 3)

View File

@@ -69,7 +69,7 @@ make_name(std::string const& object, std::string const& field)
if (field.empty())
return object;
return object + "." + field;
return {object + "." + field};
}
static inline Json::Value

View File

@@ -6,7 +6,11 @@
namespace xrpl {
static uint256 const&
// Returns a depth mask by value to avoid potential lifetime issues in
// multi-threaded contexts. Returning by const reference to a static member
// could trigger stack-use-after-scope errors when the reference is used in
// temporary expressions with operator& in concurrent coroutine scenarios.
static uint256 const
depthMask(unsigned int depth)
{
enum { mask_size = 65 };
@@ -72,7 +76,8 @@ SHAMapNodeID::getChildNodeID(unsigned int m) const
if (depth_ >= SHAMap::leafDepth)
Throw<std::logic_error>("Request for child node ID of " + to_string(*this));
if (id_ != (id_ & depthMask(depth_)))
auto const idAtDepth = id_ & depthMask(depth_);
if (id_ != idAtDepth)
Throw<std::logic_error>("Incorrect mask for " + to_string(*this));
SHAMapNodeID node{depth_ + 1, id_};

View File

@@ -148,7 +148,7 @@ private:
std::vector<std::string> emptyCfgKeys;
struct publisher
{
publisher(FetchListConfig const& c) : cfg{c}
publisher(FetchListConfig const& c) : cfg{c}, isRetry{false}
{
}
std::shared_ptr<TrustedPublisherServer> server;

View File

@@ -184,6 +184,9 @@ private:
};
// Helper function to run HTTP client test
// Note: Caller must ensure HTTPClient::initializeSSLContext has been called
// before this function, and HTTPClient::cleanupSSLContext is called after
// all tests are completed.
bool
runHTTPTest(
TestHTTPServer& server,
@@ -191,14 +194,9 @@ runHTTPTest(
bool& completed,
int& resultStatus,
std::string& resultData,
boost::system::error_code& resultError)
boost::system::error_code& resultError,
beast::Journal& j)
{
// Create a null journal for testing
beast::Journal j{TestSink::instance()};
// Initialize HTTPClient SSL context
HTTPClient::initializeSSLContext("", "", false, j);
HTTPClient::get(
false, // no SSL
server.ioc(),
@@ -232,6 +230,9 @@ runHTTPTest(
}
}
// Drain any remaining handlers to ensure proper cleanup of HTTPClientImp
server.ioc().poll();
return completed;
}
@@ -260,19 +261,28 @@ TEST(HTTPClient, case_insensitive_content_length)
std::string resultData;
boost::system::error_code resultError;
bool testCompleted =
runHTTPTest(server, "/test", completed, resultStatus, resultData, resultError);
beast::Journal j{TestSink::instance()};
HTTPClient::initializeSSLContext("", "", false, j);
bool testCompleted =
runHTTPTest(server, "/test", completed, resultStatus, resultData, resultError, j);
// Verify results
EXPECT_TRUE(testCompleted);
EXPECT_FALSE(resultError);
EXPECT_EQ(resultStatus, 200);
EXPECT_EQ(resultData, testBody);
}
// Clean up SSL context to prevent memory leaks
HTTPClient::cleanupSSLContext();
}
TEST(HTTPClient, basic_http_request)
{
// Initialize SSL context once for the entire test
beast::Journal j{TestSink::instance()};
HTTPClient::initializeSSLContext("", "", false, j);
TestHTTPServer server;
std::string testBody = "Test response body";
server.setResponseBody(testBody);
@@ -284,16 +294,23 @@ TEST(HTTPClient, basic_http_request)
boost::system::error_code resultError;
bool testCompleted =
runHTTPTest(server, "/basic", completed, resultStatus, resultData, resultError);
runHTTPTest(server, "/basic", completed, resultStatus, resultData, resultError, j);
EXPECT_TRUE(testCompleted);
EXPECT_FALSE(resultError);
EXPECT_EQ(resultStatus, 200);
EXPECT_EQ(resultData, testBody);
// Clean up SSL context to prevent memory leaks
HTTPClient::cleanupSSLContext();
}
TEST(HTTPClient, empty_response)
{
// Initialize SSL context once for the entire test
beast::Journal j{TestSink::instance()};
HTTPClient::initializeSSLContext("", "", false, j);
TestHTTPServer server;
server.setResponseBody(""); // Empty body
server.setHeader("Content-Length", "0");
@@ -304,16 +321,23 @@ TEST(HTTPClient, empty_response)
boost::system::error_code resultError;
bool testCompleted =
runHTTPTest(server, "/empty", completed, resultStatus, resultData, resultError);
runHTTPTest(server, "/empty", completed, resultStatus, resultData, resultError, j);
EXPECT_TRUE(testCompleted);
EXPECT_FALSE(resultError);
EXPECT_EQ(resultStatus, 200);
EXPECT_TRUE(resultData.empty());
// Clean up SSL context to prevent memory leaks
HTTPClient::cleanupSSLContext();
}
TEST(HTTPClient, different_status_codes)
{
// Initialize SSL context once for the entire test
beast::Journal j{TestSink::instance()};
HTTPClient::initializeSSLContext("", "", false, j);
std::vector<unsigned int> statusCodes = {200, 404, 500};
for (auto status : statusCodes)
@@ -328,10 +352,13 @@ TEST(HTTPClient, different_status_codes)
boost::system::error_code resultError;
bool testCompleted =
runHTTPTest(server, "/status", completed, resultStatus, resultData, resultError);
runHTTPTest(server, "/status", completed, resultStatus, resultData, resultError, j);
EXPECT_TRUE(testCompleted);
EXPECT_FALSE(resultError);
EXPECT_EQ(resultStatus, static_cast<int>(status));
}
// Clean up SSL context to prevent memory leaks
HTTPClient::cleanupSSLContext();
}