#3214

Benchmark analysis crashes: out-of-bounds index in Detail::bootstrap

Openbkaradzicopened 22d ago

Describe the bug

Catch2 v3.16.0 (also v3.13.0). Running benchmarks with analysis enabled (the default) intermittently segfaults on the analysis thread in Catch::Benchmark::Detail::bootstrap:

auto lo = static_cast<size_t>( (std::max)( cumn( a1 ), 0l ) );
auto hi = static_cast<size_t>( (std::min)( cumn( a2 ), n - 1 ) );
return { point, resample[lo], resample[hi], confidence_level };

lo is only clamped from below and hi only from above. When sum_squares is 0, accel is 0/0 = NaN, so a1/a2 are NaN. std::lround(NaN) then returns LONG_MIN, hi becomes a huge size_t, and resample[hi] reads out of bounds. Whether it triggers depends on the measured samples, so it looks random. It happens with very fast benchmarks (a few ns per call).

Seen with MinGW GCC 14.2 on Windows x64: 2 of 6 runs crashed. --benchmark-no-analysis avoids it.

Fix: handle NaN and clamp both indices to [0, n-1]:

const long clo = std::isnan( a1 ) ? 0l : cumn( a1 );
const long chi = std::isnan( a2 ) ? n - 1 : cumn( a2 );
auto lo = static_cast<size_t>( (std::min)( (std::max)( clo, 0l ), n - 1 ) );
auto hi = static_cast<size_t>( (std::min)( (std::max)( chi, 0l ), n - 1 ) );

With this, the same run had 0 crashes in 10 runs.

Activity

0

No activity yet.