boostorg / python

Boost.org python module
http://boostorg.github.io/python
Boost Software License 1.0
468 stars 201 forks source link

Assertion `(char *) aligned_storage + holder_size <= (char *)base_storage + base_allocation' failed. #384

Open aristk opened 2 years ago

aristk commented 2 years ago

Hi,

Many thanks for the great library!

We just migrated to boost 1.78 and start getting:

python3: libs/python/src/object/class.cpp:762: static void* boost::python::instance_holder::allocate(PyObject*, std::size_t, std::size_t, std::size_t): Assertion `(char *) aligned_storage + holder_size <= (char *)base_storage + base_allocation' failed.

on arm platform. On x64 everything works perfect.

I took a look into boost::python::instance_holder::allocate with debugger and see:

sizeof(alignment_marker_t) == 4
alignment == 4
holder_size == 16

so assertion is correct.

I'm a bit confused, why we need -1 at https://github.com/boostorg/python/blame/develop/src/object/class.cpp#L750?

Looking forward for your answer!

aristk commented 2 years ago

OK, this -1 is there, since it is not expected to reach end of base_storage, as in this case no alignment is need.

But then formula in https://github.com/boostorg/python/blame/develop/src/object/class.cpp#L759 should be corrected. (x & (alignment - 1)) == 0 should be used as condition.

Minimonium commented 2 years ago

Can confirm that it fails on x86.

Osyotr commented 2 years ago

I can confirm that changing const uintptr_t padding = alignment == 1 ? 0 : ( alignment - (x & (alignment - 1)) ); to const uintptr_t padding = ((x & (alignment - 1)) == 0) ? 0 : ( alignment - (x & (alignment - 1)) ); fixes the issue. Thanks @aristk

teeks99 commented 3 months ago

I can confirm that this impacts windows 32-bit builds, this seems like a pretty important issue.

I was able to apply @Osyotr and @aristk 's fix from above and it then started working as expected.