CxxWrap-based wrapper throws error in running finalizer: ReadOnlyMemoryError()

Hi

I am updating a CxxWrap-based wrapper for a C++ library from Julia 1.0 and CxxWrap 0.8.1 - with succesful unit tests - and a dev container - to Julia 1.6 (1.3+) and the latest released CxxWrap, 0.11.2: https://github.com/IHPSystems/pylon_julia_wrapper

Now, I am getting some errors I do not quite know how to debug - it looks like some finalizers are accessing invalid memory (the errors do not crash the Julia process though):

Precompiling project...
 ✓ Libiconv_jll
 ✓ XML2_jll
 ✓ EzXML
 ✓ TestReports
 ✓ PylonWrapper
 5 dependencies successfully precompiled in 7 seconds (8 already precompiled)
[ Info: Testing PylonWrapper
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x19698a0)
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x19698a0)
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x19698a0)

On this branch

The wrapper is wrapping a couple of methods that return and take pointers to abstract C++ interfaces, IPylonDevice*, which gives off a warning when wrapping the abstract C++ interface “data type”: I am wondering whether that may be the source of error:

[build] In file included from /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/jlcxx.hpp:14:
[build] /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/module.hpp:892:5: warning: delete called on 'Pylon::IDevice' that is abstract but has non-virtual destructor [-Wdelete-non-virtual-dtor]
[build]     delete to_delete;
[build]     ^
[build] /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/module.hpp:937:34: note: in instantiation of function template specialization 'jlcxx::detail::finalize<Pylon::IDevice>' requested here
[build]   mod.method("__delete", detail::finalize<T>);
[build]                                  ^
[build] /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/module.hpp:1183:5: note: in instantiation of function template specialization 'jlcxx::add_default_methods<Pylon::IDevice>' requested here
[build]     add_default_methods<T>(*this);
[build]     ^
[build] /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/module.hpp:1194:10: note: in instantiation of function template specialization 'jlcxx::Module::add_type_internal<Pylon::IDevice, jlcxx::ParameterList<>, _jl_datatype_t>' requested here
[build]   return add_type_internal<T, SuperParametersT>(name, super);
[build]          ^
[build] /workspaces/pylon_julia_wrapper/src/pylon_wrapper.cpp:249:10: note: in instantiation of function template specialization 'jlcxx::Module::add_type<Pylon::IDevice, jlcxx::ParameterList<>, _jl_datatype_t>' requested here
[build]   module.add_type<IDevice>("IDevice")
[build]          ^
[build] In file included from /workspaces/pylon_julia_wrapper/src/pylon_wrapper.cpp:2:
[build] In file included from /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/jlcxx.hpp:14:
[build] /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/module.hpp:892:5: warning: delete called on 'Pylon::IPylonDevice' that is abstract but has non-virtual destructor [-Wdelete-non-virtual-dtor]
[build]     delete to_delete;
[build]     ^
[build] /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/module.hpp:937:34: note: in instantiation of function template specialization 'jlcxx::detail::finalize<Pylon::IPylonDevice>' requested here
[build]   mod.method("__delete", detail::finalize<T>);
[build]                                  ^
[build] /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/module.hpp:1183:5: note: in instantiation of function template specialization 'jlcxx::add_default_methods<Pylon::IPylonDevice>' requested here
[build]     add_default_methods<T>(*this);
[build]     ^
[build] /root/.julia/artifacts/16e1de4679fb8520a8af4e6831c7c8e9893d18b4/include/jlcxx/module.hpp:1194:10: note: in instantiation of function template specialization 'jlcxx::Module::add_type_internal<Pylon::IPylonDevice, jlcxx::ParameterList<>, _jl_datatype_t>' requested here
[build]   return add_type_internal<T, SuperParametersT>(name, super);
[build]          ^
[build] /workspaces/pylon_julia_wrapper/src/pylon_wrapper.cpp:252:10: note: in instantiation of function template specialization 'jlcxx::Module::add_type<Pylon::IPylonDevice, jlcxx::ParameterList<>, _jl_datatype_t>' requested here
[build]   module.add_type<IPylonDevice>("IPylonDevice", jlcxx::julia_base_type<IDevice>());
[build]          ^
[build] 6 warnings generated.

But I also get these finalizer errors when I just pass void* (6 errors) instead of IPylonDevice* (3 errors):

[ Info: Testing PylonWrapper
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x2191870)
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x1ef91c0)
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x1ef91c0)
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x1ef91c0)
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x24a0ff0)
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x2317300)
error in running finalizer: ReadOnlyMemoryError()
unknown function (ip: 0x18dfd50)

The wrapper has to work around a blocking C++ call, in order to get/wait for frames from a camera without blocking the Julia thread, so it spins up a C++ std::thread, but this C++ thread is only interacting with the Julia runtime by calling uv_async_send: https://github.com/IHPSystems/pylon_julia_wrapper/blob/master/src/pylon_wrapper.cpp#L51

Any ideas for resolving warnings or getting rid of the errors?

Don’t spend time on this - I am quite sure the cause for the finalizer errors is due to the wrapped library and neither Julia, nor CxxWrap: The wrapped type destructors and thus the finalizers are failing due to the wrapped type trying to release the same resource more than once.