Do not mark move operations that allocate through memory-tracking containers as noexcept#106096
Conversation
…ppends through memory-tracking containers and can throw MEMORY_LIMIT_EXCEEDED, terminating the server
…on move ops and ActionsDAG::decorrelate; they allocate and can throw
…-free by defaulting them (steal impl instead of make_unique)
|
Workflow [PR], commit [632873c] Summary: ❌
AI ReviewSummaryThis PR removes incorrect Final VerdictStatus: ✅ Approve |
…had the same noexcept-but-allocating issue
…; an in-place *impl = std::move copies SettingFieldString (which has no move op) and can throw under the noexcept wrapper
nickitat
left a comment
There was a problem hiding this comment.
If there is a focused reproducer, let's add it as a test.
…s throw (std::bad_alloc), not only via the memory-tracking containers
…ans of a UNION query so a fault lands in QueryPlanResourceHolder::append; the server must not terminate
…ryPlanResourceHolder, which allocates and can throw (move ctor stays noexcept, it steals the holder)
…onally can throw; marking them noexcept would reintroduce the std::terminate (same NOLINT as StorageInMemoryMetadata)
|
Found another, different, issue in the CI preventing the merge: Fixing it here |
…SSL callback exception-safe; otherwise memory_tracker_fault_probability injects a fault that unwinds through C and terminates
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered by tests: 84/114 (73.68%) | Lost baseline coverage (was covered on master, now uncovered in this PR): 2 line(s) · Uncovered code |
ecb53ca
A recent change (
d45e6cd6d6bc, "Convert std containers insrc/QueryPipelineto*WithMemoryTrackingaliases") madeQueryPlanResourceHolder's move-assignment able to throw: it appends intoVectorWithMemoryTrackingmembers, which allocate through the throwing memory tracker and raiseMEMORY_LIMIT_EXCEEDED. The function (and theQueryPipeline/BlockIOmove-assignments that call it) are markednoexcept, so under a memory limit the throw hits thenoexceptboundary and callsstd::terminate. It reproduces with aSELECT ... SETTINGS extremes = 1, max_memory_usage = '4Mi', which terminates the server while the resultBlockIOis move-assigned inTCPHandler.This removes
noexceptfrom that move-assignment chain (QueryPlanResourceHolder,QueryPipeline,BlockIO).While auditing other
noexceptspecifications it also fixes:ConstraintsDescription/ColumnDescriptionmove operations andActionsDAG::decorrelate, which allocate (rebuild derived data, clone ASTs, append to vectors) and can throw.noexceptmove constructors and move assignments either allocated a new impl viamake_unique, or move-assigned the impl in place (*impl = std::move(*settings.impl)). The latter is also unsafe:BaseSettings/Datamove walks per-fieldSettingFields, andSettingFieldString(and friends) declare a copy assignment but no move, so the rvalue assignment falls back to copying aString, which allocates and can throw. Both move ops are now= default, so they simply steal theunique_ptr(noexceptand allocation-free); the impl/BaseSettingsis never moved.Closes ClickHouse/ClickHouse#106079
References ClickHouse/ClickHouse#105580
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
...