ARMPL FFT memory leak: ASAN reports alloc-dealloc-mismatch on Linux

Hi all,

When running ASAN on an internal library that utilizes ARMPL's FFT functionality, the following issue was reported. Here's the relevant portion of the ASAN trace 

=================================================================
==933787==ERROR: AddressSanitizer: alloc-dealloc-mismatch (operator new vs free) on 0xff9619457380
#0 0xff96614af0d8 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0xff964acfb38c in std::array<sloejit::padded<std::vector<unsigned char, std::allocator<unsigned char> > >, 4ul>::~array() (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x817b38c)
#2 0xff964ad16dec in sloejit::block::iterate_input_output_set(sloejit::arch_traits const*, sloejit::function_options_t) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x8196dec)
#3 0xff964ad21108 in sloejit::function::finalise(sloejit::stack_frame_info const*) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x81a1108)
#4 0xff964ad0e000 in sloejit::function::emit_bin(std::vector<sloejit::reloc_info, std::allocator<sloejit::reloc_info> >*, std::vector<sloejit::note_info, std::allocator<sloejit::note_info> >*, sloejit::stack_frame_info const*) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x818e000)
#5 0xff964abd7414 in arm::fft1d::wfta::print_common(arm::fft1d::wfta::kernel_registry_entry<void>*, std::__cxx11::list<arm::fft1d::wfta::expr, std::allocator<arm::fft1d::wfta::expr> >, arm::fft1d::wfta::options_t const&, long, arm::fft1d::wfta::io_pointers const&, std::vector<long, std::allocator<long> > const&, std::vector<long, std::allocator<long> > const&, char, arm::fft1d::wfta::direction_kind, arm::fft1d::wfta::rtype, arm::fft1d::wfta::rtype, arm::fft1d::wfta::rtype, arm::fft1d::wfta::order_kind, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, arm::fft1d::wfta::out_mods, arm::fft1d::wfta::in_mods, arm::fft1d::wfta::dist_types, std::optional<int>) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x8057414)
#6 0xff964abdb230 in arm::fft1d::wfta::kernel_data arm::fft1d::wfta::print_algo<std::complex<float>, std::complex<float>, std::complex<float> >(arm::fft1d::wfta::kernel_registry_entry<void>*, std::__cxx11::list<arm::fft1d::wfta::expr, std::allocator<arm::fft1d::wfta::expr> >, long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, arm::fft1d::wfta::io_pointers const&, std::vector<long, std::allocator<long> > const&, std::vector<long, std::allocator<long> > const&, char, arm::fft1d::wfta::direction_kind, arm::fft1d::wfta::order_kind, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, arm::fft1d::wfta::options_t const&, arm::fft1d::wfta::dist_types, std::optional<int>, arm::fft1d::wfta::out_mods, arm::fft1d::wfta::in_mods) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x805b230)
#7 0xff964abbc88c in void arm::fft1d::wfta::kernel_printer<std::complex<float>, std::complex<float>, std::complex<float> >::print_algo<void (std::complex<float> const*, std::complex<float>*, long, long, long, long, long)>(arm::fft1d::wfta::kernel_registry_entry<void (std::complex<float> const*, std::complex<float>*, long, long, long, long, long)>*, char, arm::fft1d::wfta::order_kind, arm::fft1d::wfta::out_mods, arm::fft1d::wfta::in_mods) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x803c88c)
#8 0xff964abbea18 in std::optional<arm::fft1d::kernel_data<std::complex<float>, std::complex<float>, void> > arm::fft1d::get_kernel_data<std::complex<float>, std::complex<float> >(long, long, long, long, long, arm::fft1d::direction, int, want_kernel_type) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x803ea18)
#9 0xff964ab689a8 in std::optional<arm::fft1d::level_data_info> arm::fft1d::make_level_data<(arm::fft1d::level_type)2, std::complex<float>, std::complex<float> >(arm::fft1d::unique_ptr<arm::fft1d::level_data_base<std::complex<float>, std::complex<float> > >*, long, long, long, long, long, long, long, long, long, arm::fft1d::direction, double, double, bool, bool, bool, bool) [clone .constprop.0] (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x7fe89a8)
#10 0xff964ab6b9a0 in std::pair<bool, std::optional<arm::fft1d::composition<std::complex<float>, std::complex<float> > > > arm::fft1d::composite_init_from_factors<std::complex<float>, std::complex<float> >(long, long, long, long, long, long, arm::fft1d::direction, arm::fft1d::pod_vector<long, arm::fft1d::reallocator> const&, double, double, bool, bool) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x7feb9a0)
#11 0xff964ab6bc70 in bool arm::fft1d::audition_perms<std::complex<float>, std::complex<float> >(arm::fft1d::pod_vector<long, arm::fft1d::reallocator>, long, std::complex<float> const*, std::complex<float>*, long, long, long, long, long, arm::fft1d::direction, double, double, arm::fft1d::composition<std::complex<float>, std::complex<float> >&, bool, bool) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x7febc70)
#12 0xff964ab6c414 in std::pair<bool, arm::fft1d::composition<std::complex<float>, std::complex<float> > > arm::fft1d::composite_init<std::complex<float>, std::complex<float> >(long, long, long, long, long, long, arm::fft1d::direction, double, double, bool) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x7fec414)
#13 0xff964ab3a190 in arm::fft1d::unique_ptr<arm::fft1d::fft_detail_plan> arm::fft1d::make_1d_plan<std::complex<float>, std::complex<float> >(long, std::complex<float> const*, std::complex<float>*, long, long, long, long, long, int, arm::fft1d::r2r_variant, bool, double, double) (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x7fba190)
#14 0xff964b88b3d4 in fftwf_plan_dft_1d (/opt/armpl/armpl_25.07.1_gcc/lib/libarmpl.so+0x8d0b3d4)
0xff9619457380 is located 0 bytes inside of 573-byte region [0xff9619457380,0xff96194575bd)

System info: Ubuntu 22.04, aarch-64, Linux kernel v6.8.0-83-generic

Tested on ARMPL versions: 24.10. 25.04, 25.07, 25.07.1

I couldn't find this reported before. Has anyone seen this? Let me know if you need more information.

Thanks,

Andrew