I believe that this is actually a result of Perl 6 delegating responsibility of memory management for arguments passed to callbacks from native code to the native code.
I wonder if the issue is that you're sending a constant which is being reallocated and recreated and never cleared out from the native code. Keep in mind, however, I've been sick lately and I am on heavy antihistamines, so I could just have medicine head. Here's the document I'm drawing this guess from: https://docs.perl6.org/language/nativecall#Function_arguments > On Jan 21, 2018, at 19:24, David E. <da...@empireofgames.com> wrote: > > I'm not certain where to report this (ie: rakudo vs MoarVM), so I'm starting > here. > > After some experimentation, I finally traced down a segfault I've been > getting to a memory leak in the NativeCall interface. I'm using it to > facilitate testing of a 32-bit embedded (meaning no dynamic allocation) C > library in an easier/more-comprehensive way than I could otherwise -- though > this memory leak is preventing me from running the long-duration tests that I > need to. > > I'm currently running 2017.12.1 (commit > c84ed2942d224e4cd524fa389e0603e4e4642f77) under a 32-bit Docker Ubuntu image > (I started with 2017.10). I can easily observe the memory leak using "docker > stats". At it's worst, with my full application, I'm seeing approximately > 0.01 GiB of memory per second getting lost. > > Below is sample code that is able to reproduce the leak. I believe that it > has something to do with the callback, maybe with the C-string conversion. > > Please advise, > thanks, > -David > > > test_memleak.pl6: > use v6; > use NativeCall; > > constant LIB_DTEST = 'libtestlib.so'; > > sub dtest_log_init(&dt_csv_log (Str)) is native(LIB_DTEST) {*}; > sub test_cb() is native(LIB_DTEST) {*}; > > sub dt_csv_log(Str $data) > { > prompt "dt_csv_log($data)"; > } > > sub MAIN() > { > dtest_log_init(&dt_csv_log); > > while 1 { > # prompt "Call test_cb()"; > test_cb(); > } > } > > test_memleak.c: > #include <stdio.h> > void (*dtlf)(char* s); > void dtest_log_init(void (*fp)(char* s)) > { > printf("Assigning dtlf to fp=0x%x\n", (int)fp); > dtlf = fp; > } > void test_cb(void) > { > dtlf("test_cb"); > } > > The following is a snippet from my Dockerfile that installed perl6: > && git clone https://github.com/rakudo/rakudo/ > <https://github.com/rakudo/rakudo/> /root/rakudo \ > && echo 'export > PATH="$HOME/rakudo/install/bin:$HOME/rakudo/install/share/perl6/site/bin:$PATH"' > >> ~/.bashrc \ > && cd ~/rakudo && git checkout master && git pull \ > && git checkout $(git describe --abbrev=0 --tags) \ > && perl Configure.pl --gen-moar --gen-nqp --backends=moar \ > && make && make install \ >