Compare commits

..

1 Commits

Author SHA1 Message Date
Pratik Mankawde
547b7c4e04 fixes for string ref and stack alloc
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-02-19 14:55:25 +00:00
11 changed files with 40 additions and 59 deletions

View File

@@ -236,12 +236,10 @@ 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']}" in [
"clang-20",
"gcc-15",
]:
if (
os["distro_version"] == "bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
):
# Add ASAN + UBSAN configuration.
configurations.append(
{
@@ -256,7 +254,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
}
)
# TSAN is deactivated due to seg faults with latest compilers.
activate_tsan = True
activate_tsan = False
if activate_tsan:
configurations.append(
{

View File

@@ -17,7 +17,7 @@ find_dependency(Boost
chrono
container
context
coroutine2
coroutine
date_time
filesystem
program_options

View File

@@ -4,7 +4,7 @@ include(XrplSanitizers)
find_package(Boost REQUIRED
COMPONENTS chrono
container
context
coroutine
date_time
filesystem
json
@@ -21,7 +21,7 @@ target_link_libraries(
INTERFACE Boost::headers
Boost::chrono
Boost::container
Boost::context
Boost::coroutine
Boost::date_time
Boost::filesystem
Boost::json

View File

@@ -13,18 +13,15 @@ include(default)
{% if "address" in sanitizers %}
{% set _ = sanitizer_list.append("address") %}
{% set model_code = "-mcmodel=large" %}
tools.build:defines+=["BOOST_USE_ASAN", "BOOST_USE_UCONTEXT"]
{% elif "thread" in sanitizers %}
{% set _ = sanitizer_list.append("thread") %}
{% set model_code = "-mcmodel=medium" %}
{% set _ = extra_cxxflags.append("-Wno-tsan") %}
tools.build:defines+=["BOOST_USE_TSAN", "BOOST_USE_UCONTEXT"]
{% endif %}
{% if "undefinedbehavior" in sanitizers %}
{% set _ = sanitizer_list.append("undefined") %}
{% set _ = sanitizer_list.append("float-divide-by-zero") %}
tools.build:defines+=["BOOST_USE_UBSAN", "BOOST_USE_UCONTEXT"]
{% endif %}
{% set sanitizer_flags = "-fsanitize=" ~ ",".join(sanitizer_list) ~ " " ~ model_code %}
@@ -40,17 +37,14 @@ include(default)
{% if "address" in sanitizers %}
{% set _ = sanitizer_list.append("address") %}
tools.build:defines+=["BOOST_USE_ASAN", "BOOST_USE_UCONTEXT"]
{% elif "thread" in sanitizers %}
{% set _ = sanitizer_list.append("thread") %}
tools.build:defines+=["BOOST_USE_TSAN", "BOOST_USE_UCONTEXT"]
{% endif %}
{% if "undefinedbehavior" in sanitizers %}
{% set _ = sanitizer_list.append("undefined") %}
{% set _ = sanitizer_list.append("float-divide-by-zero") %}
{% set _ = sanitizer_list.append("unsigned-integer-overflow") %}
tools.build:defines+=[ "BOOST_USE_UBSAN", "BOOST_USE_UCONTEXT"]
{% endif %}
{% set sanitizer_flags = "-fsanitize=" ~ ",".join(sanitizer_list) %}
@@ -62,20 +56,4 @@ include(default)
{% endif %}
{% endif %}
tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags", "tools.build:defines"]
[options]
{% if compiler == "gcc" or compiler == "apple-clang" or compiler == "clang" %}
{% if sanitizers == "Address" or sanitizers == "Thread" %}
boost/*:without_context=False
boost/*:without_stacktrace=True
boost/*:without_coroutine2=False
{% if sanitizers == "Address" %}
boost/*:extra_b2_flags="context-impl=ucontext address-sanitizer=norecover undefined-sanitizer=norecover --with-coroutine2"
{% elif sanitizers == "Thread" %}
boost/*:extra_b2_flags="context-impl=ucontext thread-sanitizer=norecover undefined-sanitizer=norecover --with-coroutine2"
{% endif %}
{% endif %}
{% endif %}
tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags"]

View File

@@ -125,7 +125,6 @@ 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_coroutine2 = False
def requirements(self):
# Conan 2 requires transitive headers to be specified
@@ -197,8 +196,7 @@ class Xrpl(ConanFile):
"boost::headers",
"boost::chrono",
"boost::container",
"boost::context",
"boost::coroutine2",
"boost::coroutine",
"boost::date_time",
"boost::filesystem",
"boost::json",

View File

@@ -173,7 +173,6 @@ words:
- nftpage
- nikb
- nonxrp
- norecover
- noripple
- nudb
- nullptr

View File

@@ -10,14 +10,16 @@ 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::coroutines2::asymmetric_coroutine<void>::push_type& do_yield) {
yield_ = &do_yield;
yield();
fn(shared_from_this());
, coro_(
[this, fn = std::forward<F>(f)](boost::coroutines::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)))
{
}

View File

@@ -7,7 +7,7 @@
#include <xrpl/core/detail/Workers.h>
#include <xrpl/json/json_value.h>
#include <boost/coroutine2/all.hpp>
#include <boost/coroutine/all.hpp>
#include <set>
@@ -48,8 +48,8 @@ public:
std::mutex mutex_;
std::mutex mutex_run_;
std::condition_variable cv_;
boost::coroutines2::asymmetric_coroutine<void>::pull_type coro_;
boost::coroutines2::asymmetric_coroutine<void>::push_type* yield_;
boost::coroutines::asymmetric_coroutine<void>::pull_type coro_;
boost::coroutines::asymmetric_coroutine<void>::push_type* yield_;
#ifndef NDEBUG
bool finished_ = false;
#endif
@@ -326,7 +326,7 @@ private:
other requests while the RPC command completes its work asynchronously.
postCoro() creates a Coro object. When the Coro ctor is called, and its
coro_ member is initialized (a boost::coroutines2::pull_type), execution
coro_ member is initialized (a boost::coroutines::pull_type), execution
automatically passes to the coroutine, which we don't want at this point,
since we are still in the handler thread context. It's important to note
here that construction of a boost pull_type automatically passes execution to

View File

@@ -229,7 +229,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));
}
@@ -247,7 +247,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));
}
@@ -259,7 +259,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));
}
@@ -271,7 +271,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));
}
@@ -283,7 +283,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);
}
@@ -295,7 +295,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

@@ -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
@@ -238,7 +239,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))
@@ -254,7 +255,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>
@@ -276,7 +277,7 @@ Number::Guard::doRoundDown(bool& negative, T& mantissa, int& exponent, internalr
// 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))
@@ -290,7 +291,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

@@ -984,7 +984,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)