почему выравнивание может вызвать это
От Черновик C ++ Выравнивание p1 :
Типы объектов имеют требования к выравниванию ([базовые c .fundamental], [basi c .compound]), которые накладывают ограничения на адреса, по которым может быть размещен объект этого типа.
Выражение:
new (bad_ptr + 1) std::condition_variable{};
вызывает неопределенное поведение в системах, где bad_ptr + 1
не выравнивается с alignof(std::condition_variable)
. Тестирование на godbolt с gcc10, alignof(std::confition_variable)
равно 8
.
Оба доступа bad->
являются невыровненными и оба являются неопределенным поведением.
Кто-нибудь знает, почему это произошло?
Проверяя strace
вывод при выполнении исполняемого файла, мы видим, что:
futex(0x557da3e262e9, FUTEX_WAIT_BITSET_PRIVATE, 0, {tv_sec=2439, tv_nsec=619296657}, FUTEX_BITSET_MATCH_ANY) = -1 EINVAL (Invalid argument)
Потому что uaddr
первый аргумент, который должен быть указатель на int
из futex
, вызов не выровнен с _Alignof(int)
, ядро обнаруживает его здесь и возвращает futex EINVAL
. Стандартная библиотека просто закрывает приложение, что является прекрасным поведением для неопределенного поведения.