mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-06 18:26:51 +00:00
Merge develop into confidential MPT
This commit is contained in:
50
docker/test_files/compile-cpp-sources.sh
Executable file
50
docker/test_files/compile-cpp-sources.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
# Compile all C++ test binaries during the Docker image build.
|
||||
# Each binary has the target system's ELF PT_INTERP (dynamic-linker path)
|
||||
# baked in so it can run on the (potentially minimal) final BASE_IMAGE.
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
src_dir="${1:?usage: $0 <src_dir> <dst_dir>}"
|
||||
dst_dir="${2:?usage: $0 <src_dir> <dst_dir>}"
|
||||
|
||||
loader="$(/tmp/loader-path.sh)"
|
||||
|
||||
mkdir -p "${dst_dir}"
|
||||
|
||||
function compile() {
|
||||
local compiler="${1}"
|
||||
local name="${2}"
|
||||
local san_flag="${3:-}"
|
||||
|
||||
local src="${src_dir}/${name}.cpp"
|
||||
local binary="${dst_dir}/${name}-${compiler}"
|
||||
|
||||
echo "=== Compile ${name} with ${compiler} ==="
|
||||
cmd="${compiler} -std=c++23 -O1 -g \
|
||||
-pthread \
|
||||
-Wl,--dynamic-linker=${loader} \
|
||||
${san_flag} \
|
||||
${src} -o ${binary}"
|
||||
echo "Command: ${cmd}"
|
||||
eval "${cmd}"
|
||||
}
|
||||
|
||||
declare -A sanitize=(
|
||||
[regular]=""
|
||||
|
||||
[asan]="-fsanitize=address"
|
||||
[tsan]="-fsanitize=thread"
|
||||
[ubsan]="-fsanitize=undefined -fno-sanitize-recover=all"
|
||||
)
|
||||
|
||||
for name in regular asan tsan ubsan; do
|
||||
san_flag="${sanitize[${name}]}"
|
||||
for compiler in g++ clang++; do
|
||||
compile "${compiler}" "${name}" "${san_flag}"
|
||||
done
|
||||
done
|
||||
|
||||
echo "=== All binaries compiled ==="
|
||||
|
||||
ls -la "${dst_dir}"
|
||||
28
docker/test_files/cpp_sources/asan.cpp
Normal file
28
docker/test_files/cpp_sources/asan.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
__attribute__((noinline))
|
||||
#elif defined(_MSC_VER)
|
||||
__declspec(noinline)
|
||||
#endif
|
||||
int
|
||||
read_after_free(volatile int* array, std::size_t index)
|
||||
{
|
||||
std::atomic_signal_fence(std::memory_order_seq_cst);
|
||||
int value = array[index];
|
||||
std::atomic_signal_fence(std::memory_order_seq_cst);
|
||||
return value;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
int* array = new int[5]{10, 20, 30, 40, 50};
|
||||
delete[] array;
|
||||
|
||||
std::cout << "Value at index 2: " << read_after_free(array, 2) << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
28
docker/test_files/cpp_sources/regular.cpp
Normal file
28
docker/test_files/cpp_sources/regular.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
static std::mutex gMutex;
|
||||
|
||||
void
|
||||
worker(int id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(gMutex);
|
||||
std::cout << "Hello from thread " << id << "\n";
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
constexpr int kNumThreads = 10;
|
||||
std::vector<std::thread> threads;
|
||||
threads.reserve(kNumThreads);
|
||||
for (int i = 0; i < kNumThreads; ++i)
|
||||
threads.emplace_back(worker, i);
|
||||
for (auto& t : threads)
|
||||
t.join();
|
||||
|
||||
std::cout << "Hello from main thread\n";
|
||||
return 0;
|
||||
}
|
||||
26
docker/test_files/cpp_sources/tsan.cpp
Normal file
26
docker/test_files/cpp_sources/tsan.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
static int kCounter = 0;
|
||||
|
||||
void
|
||||
increment()
|
||||
{
|
||||
for (int i = 0; i < 100'000; ++i)
|
||||
{
|
||||
++kCounter;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
std::thread t1(increment);
|
||||
std::thread t2(increment);
|
||||
|
||||
t1.join();
|
||||
t2.join();
|
||||
|
||||
std::cout << "Final counter value: " << kCounter << std::endl;
|
||||
return 0;
|
||||
}
|
||||
13
docker/test_files/cpp_sources/ubsan.cpp
Normal file
13
docker/test_files/cpp_sources/ubsan.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
int maxInt = std::numeric_limits<int>::max();
|
||||
int volatile one = 1;
|
||||
std::cout << "Current max: " << maxInt << std::endl;
|
||||
int overflowed = maxInt + one;
|
||||
std::cout << "Overflowed result: " << overflowed << std::endl;
|
||||
return 0;
|
||||
}
|
||||
62
docker/test_files/run-test-binaries.sh
Executable file
62
docker/test_files/run-test-binaries.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
# Run pre-compiled sanitizer binaries and confirm each emits its expected diagnostic.
|
||||
# Binaries must already exist in <bins_dir> with the layout:
|
||||
# <name>-g++ and <name>-clang++ for name in {regular,asan,tsan,ubsan}
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
bins_dir="${1:?usage: $0 <bins_dir>}"
|
||||
|
||||
# Run a binary and verify its exit code and output.
|
||||
# Usage: run <binary> <expected_output> <expected_rc>
|
||||
function run() {
|
||||
local binary="${1}"
|
||||
local expected_output="${2}"
|
||||
local expected_rc="${3}"
|
||||
|
||||
local out_file
|
||||
out_file="$(mktemp)"
|
||||
|
||||
echo "=== Run ${binary} ==="
|
||||
local rc=0
|
||||
"${binary}" >"${out_file}" 2>&1 || rc=$?
|
||||
|
||||
cat "${out_file}"
|
||||
|
||||
if [ "${expected_rc}" = "nonzero" ]; then
|
||||
if [ "${rc}" -eq 0 ]; then
|
||||
echo "ERROR: expected non-zero exit code from ${binary}, got ${rc}" >&2
|
||||
exit 1
|
||||
fi
|
||||
elif [ "${rc}" -ne "${expected_rc}" ]; then
|
||||
echo "ERROR: expected exit code ${expected_rc} from ${binary}, got ${rc}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
grep -q "${expected_output}" "${out_file}" ||
|
||||
{
|
||||
echo "ERROR: expected '${expected_output}' from ${binary}" >&2
|
||||
exit 1
|
||||
}
|
||||
echo "OK: '${expected_output}' detected"
|
||||
}
|
||||
|
||||
declare -A expect=(
|
||||
[regular]="Hello from main thread"
|
||||
|
||||
[asan]="heap-use-after-free"
|
||||
[tsan]="data race"
|
||||
[ubsan]="signed integer overflow"
|
||||
)
|
||||
|
||||
for compiler in g++ clang++; do
|
||||
for name in regular asan tsan ubsan; do
|
||||
binary="${bins_dir}/${name}-${compiler}"
|
||||
if [ "${name}" = "regular" ]; then
|
||||
expected_rc=0
|
||||
else
|
||||
expected_rc=nonzero
|
||||
fi
|
||||
run "${binary}" "${expect[$name]}" "${expected_rc}"
|
||||
done
|
||||
done
|
||||
Reference in New Issue
Block a user