async icon indicating copy to clipboard operation
async copied to clipboard

Usage in dynamic objects fails due to alignment

Open lahwaacz opened this issue 3 years ago • 0 comments

async::queue and all classes using it have alignment requirements, which does not play nice with dynamic objects in C++.

Consider the following code:

#include <iostream>
#include <cstddef>  // std::max_align_t
#include "async/async/threadpool.h"

struct A
{
    A() : tp(1) {}

    async::threadpool tp;
};

int main()
{
    std::cout << "alignof(std::max_align_t) = " << alignof(std::max_align_t) << std::endl;
    std::cout << "sizeof(async::threadpool) = " << sizeof(async::threadpool) << std::endl;
    std::cout << "alignof(async::threadpool) = " << alignof(async::threadpool) << std::endl;

    std::vector<std::shared_ptr<A>> vec;
    for (int i = 0; i < 1000; i++)
        vec.push_back(std::make_shared<A>());
}

Compile it with g++ -pthread -g -fsanitize=undefined code.cpp, then the typical output may look like

alignof(std::max_align_t) = 16
sizeof(async::threadpool) = 9152
alignof(async::threadpool) = 64
/usr/include/c++/10.2.0/bits/shared_ptr_base.h:682:16: runtime error: constructor call on misaligned address 0x55d39b50cf70 for type 'struct _Sp_cp_type', which requires 64 byte alignment
0x55d39b50cf70: note: pointer points here
 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^ 
/usr/include/c++/10.2.0/bits/shared_ptr_base.h:546:2: runtime error: member access within misaligned address 0x55d39b50cf70 for type 'struct _Sp_counted_ptr_inplace', which requires 64 byte alignment
0x55d39b50cf70: note: pointer points here
 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^ 
...

(The error output is actually much longer.)

This is because the dynamic allocation in C++ is not required to satisfy alignment requirements stricter than the std::max_align_t type (which requires only 16 bytes compared to 64 bytes of the async::threadpool). See https://stackoverflow.com/a/53485295 and https://stackoverflow.com/a/16510895/4180822 for details.

lahwaacz avatar Dec 30 '20 23:12 lahwaacz