-
Notifications
You must be signed in to change notification settings - Fork 454
Reducing Warnings - Misaligned Address of Over-Aligned Types #1072
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Addition of the new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done. LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pain.
Not because of these changes, but because they are necessary.
LGTM, but with a remark about deduplication that may be useful at some point.
ret_handshake_sd = | ||
bson_aligned_alloc0 (BSON_ALIGNOF (mongoc_server_description_t), | ||
sizeof (mongoc_server_description_t)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern of aligned_alloc(alignof(T), sizeof(T))
is pretty repetitive. It might be useful to have a bson_alloc_new(T)
function-like macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. Added BSON_ALIGNED_ALLOC
and BSON_ALIGNED_ALLOC0
convenience macros to avoid type repetition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. One possible improvement on the alloc macro, otherwise good.
src/libbson/src/bson/bson-memory.h
Outdated
@@ -58,6 +63,11 @@ BSON_EXPORT (void) | |||
bson_zero_free (void *mem, size_t size); | |||
|
|||
|
|||
#define BSON_ALIGNED_ALLOC(T) bson_aligned_alloc (BSON_ALIGNOF (T), sizeof (T)) | |||
#define BSON_ALIGNED_ALLOC0(T) \ | |||
bson_aligned_alloc0 (BSON_ALIGNOF (T), sizeof (T)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you insert an explicit cast-to-T*
, that can catch incompatible-pointer assignments. i.e. double* d = BSON_ALIGNED_ALLOC0(int)
Description
Resolves CDRIVER-4434. This PR resolves ASan runtime errors regarding misalignment of over-aligned types, particularly when the C Driver is configured with
ENABLE_EXTRA_ALIGNMENT=ON
(which should probably be deprecated as was done forENABLE_AUTOMATIC_INIT_AND_CLEANUP=ON
).This has impacted end users even with
ENABLE_EXTRA_ALIGNMENT=OFF
as reported in CDRIVER-1051.As a drive-by improvement, the
debug-compile-aws
andlink-sample-program
-based tasks were updated to correctly configure C99 standard conformance options for correct detection of (the lack of) C11 features, which was interfering with selection ofaligned_alloc
alternatives.BSON_ALIGNOF
Essential to the scope of this PR was introducing a utility to query the alignment of a given type (to avoid the use of magic numbers or defining numerous
BSON_ALIGN_OF_<Type>
constants). The C11_Alignof
operator is used if available; otherwise, compiler extensions are utilized instead.BSON_ALIGN_OF_PTR
was updated to be defined in terms ofBSON_ALIGNOF
instead ofsizeof
(should have no behavioral difference).Note: the special-casing of
_MSC_VER
forBSON_ALIGN_OF_PTR
are preserved as__declspec (align (N))
only supports integer literals forN
, prohibiting the use ofBSON_ALIGNOF
withinBSON_ALIGNED_*
macros (which was initially attempted but subsequently reverted to preserve compatibility with existing platforms). This also prevented redefining the extended alignment ofbson_impl_inline_t
andbson_impl_alloc_t
in terms ofbson_t
.aligned_alloc
Empowered by the addition of
BSON_ALIGNOF
,bson_aligned_alloc
andbson_aligned_alloc0
were added tobson-memory.h
and an.aligned_alloc
member added tobson_mem_vtable_t
to support correctly aligned allocations.bson_aligned_alloc0
was added primarily for convenience as an alignment-aware equivalent tobson_malloc0
.bson_aligned_alloc
is designed to behave as a stand-in for C11aligned_alloc
. Although POSIX conformance requiresalignment
to be a power of 2 and a multiple ofsizeof (void *)
andnum_bytes
to be a multiple ofalignment
,bson_aligned_alloc
defers actual assertions to the appropriate implementation-defined function that is invoked rather than explicitly (potentially redundantly) asserting the requirements. When neither C11 orposix_memalign
are available, the implementation defers tomalloc
. (Note, for MSVC, the alternative_aligned_alloc
cannot satisfy C11aligned_alloc
requirements as it modifieserrno
and requires the returned memory be freed by a dedicated_aligned_free
function instead offree
.)Every instance of a call to
bson_malloc
orbson_malloc0
allocating a type with extended alignment requirements (as detected by ASan) was replaced with a call tobson_aligned_alloc
orbson_aligned_alloc0
respectively. For nearly all instances, this transformation was trivial. Exceptions that required additional effort are noted below.Note: as
_Alignof
does not support expressions as arguments, correspondingsizeof
were converted from expressions to the explicit type for symmetry:mongoc_array_aligned_init
To support correct alignment of elements of
mongoc_array_t
, amongoc_array_aligned_init
function was added. Existing calls tomongoc_array_init
that do not require extended alignment support are thus left unmodified.As there is not an aligned equivalent to
realloc
, if the array was initialized with alignment requirements, storage extension performs anbson_aligned_alloc
+memmove
to maintain alignment requirements. If the array was not initialized with alignment requirements,realloc
is used as was done prior.pool_node::data
This struct presented numerous challenges w.r.t. correct alignment due to the use of a flexible member array to allocate elements (aka items) inline within the
pool_node
object. This inline allocation is required to allow for the owningpool_node
object to be obtained given a pointer to the element.Given this requirement, several adjustments to
mongoc_ts_pool
were made accordingly:_pool_node_data_offset
Rather than using
pool_node::data
as the location of the element (aka item), an offset is applied such that the element is correctly aligned in memory. This required extending the allocation size ofpool_node
to padpool_node::data
accordingly:The difference (padding) between the address of the element and the address of
pool_node::data
is expressed as_pool_node_data_offset
.Given a call to
<PoolName>_new_with_params
, the alignment is detected automatically viaBSON_ALIGNOF
. However, the alignment may be set manually via a direct call to<PoolName>_new
, including opting out of alignment requirements by setting.element_alignment = 0
(as is done intest_ts_pool_simple
). A non-zero alignment that is too small to satisfybson_aligned_alloc
requirements is automatically promoted to a compatible alignment on initialization of the pool; otherwise, any pool whose element type has an alignment less thanvoid *
would be forced to go out of its way to explicitly set the alignment._pool_node_from_item
The owning
pool_node
object must be obtainable from a pointer to an element inpool_node::data
. This operation was abstracted as_pool_node_from_item
, which requires_pool_node_data_offset
to be known for the given element, which in turn requires access to thepool::element_alignment
for the owning pool object. This operation forced some functions to be modified to request a pointer to thepool
object:mongoc_ts_pool_return (elem)
->mongoc_ts_pool_return (pool, elem)
mongoc_ts_pool_drop (elem)
->mongoc_ts_pool_drop (pool, elem)
For all instances of calls to these two functions (note: all non-test instances were restricted to
mongoc-topology.c
), the corresponding pool was easily obtainable and thus were modified accordingly.