hoelzro / inline-lua

Perl extension for embedding Lua scripts into Perl code
4 stars 5 forks source link

true/false returned as unref'd scalars #31

Closed murdegern closed 4 years ago

murdegern commented 4 years ago

Hi,

it would be great if you could help me with this problem below.

We are currently working on using a current version of perl (currently 5.14) and, trying out 5.24 with Lua 5.1.5, Inline 0.80 and Inline::Lua 0.16 I hit the following problem:

#!/path/to/my/bin/perl5.24
use Inline Lua => "function dang() return true end";
my $dang = dang();

This will print

panic: attempt to copy freed scalar 2522230 to 2538bd8 at ./x.pl line 3. Attempt to free unreferenced scalar: SV 0x2522230.

The same happens with perl 5.32. The same does NOT happen if I return 1, or { 1, 2, 3 }, or "abc". Only booleans seem to be affected.

I fumbled around with a few other versions, e.g. Lua 5.3.5 + perl 5.30 + Inline 0.86, Inline::Lua 0.16, and the same problem appears.

Any help is greatly appreciated. Regards, Torsten

hoelzro commented 4 years ago

Hi @murdegern, thanks for the report!

I looked into this today - would you mind grabbing what's on the fix-boolean-frees branch and verifying that that fixes the problem for you? If it does, I can push a new release.

murdegern commented 4 years ago

I'll look into it today. Thank you!

murdegern commented 4 years ago

Looks very good!

murdegern commented 4 years ago

Mh, I'm hitting more internal problems now: "Bizarre copy of ARRAY in subroutine exit at (eval 7274) line 8."

This is when we test our lua libs from perl, awfully dynamic stuff. If you have an idea immediately, that'd be great, otherwise I'll try to reduce it to a failing snippet - I couldn't yet.

It still looks like something's being reused, because I need to do two nearly identical calls after another for the bug to appear.

Regards, Torsten

murdegern commented 4 years ago

Oh, I found another one. Try this:

#!/cs/re/2020-10-perl5.24-64-Apache2_pg9.6_rh6/bin/perl

use strict;
use warnings;

use Inline Lua => <<EOF;
function ouch()
  return true
end
EOF

use Data::Dumper; 
my $dung = ouch();
print Dumper($dung);

$dung = ouch();

It gives me the "attempt to copy freed scalar" message again, even with your fixed branch.

hoelzro commented 4 years ago

@murdegern Ok, thanks for the additional digging! I am able to reproduce that second example - I don't know if I'll be able to look at it today, but I'll see what I can do. I also managed to reproduce the "Bizzare copy of ARRAY" thing, so I'll dig into that as well.

hoelzro commented 4 years ago

@murdegern Ok, I fixed that example and my own example with the "bizarre copy" thing - could you try out the latest commit on that branch? I think there are probably other memory issues lurking around here, but I'd like to see if my change results in progress on your end.

murdegern commented 4 years ago

I'm on it, will take some time though. Thank you for looking into it!

murdegern commented 4 years ago

@hoelzro Now I only have one case of "bizarre ARRAY copy" left. I'll make a brief version of the test tomorrow.

murdegern commented 4 years ago

@hoelzro It seems to be complicated. The one test which is still failing with our (huge) application does some contrived stuff like calling into perl objects from lua. It does not always fail in the same way; I saw "bizarre HASH copy", segfault, wrong return values and sometimes even success when running the test.

I hope I can get myself some time for working on this; it has now been revalued as lower priority 🙄

murdegern commented 4 years ago

@hoelzro Ok, used a boring meeting ... the following snippet shows a few "Attempt to free unreferenced scalar" errors (usually around 4):

use strict;
use warnings;

my ($lua, $retval);

use Inline Lua => <<EOLUA;
function _lua_run (_lua_code)
  local func, error_message = loadstring(_lua_code)
  local status, return_value = pcall(func)
  return return_value
end
EOLUA

for( my $i=0; $i<10; ++$i ) {
  $lua = <<'EOT';
  local status, val = pcall(function () return 1/1 end)
  return { status, val }
EOT
  $retval = _lua_run($lua);

  $lua = <<'EOT';
  local status, val = pcall(function () error("my error") end)
  return { status, val }
EOT

  $retval = _lua_run($lua);
}

What is really funny: if you remove one of the _lua_run calls (doesn't matter which one), it works.

hoelzro commented 4 years ago

@murdegern Thanks for the additional information - I don't know when I'll be able to take a deeper look, but I'll try by the end of the weekend!

hoelzro commented 4 years ago

@murdegern I spent some time with this today, and pushed my latest work to the fix-boolean-frees-take-2 branch - could you give that a try?

murdegern commented 4 years ago

I will. I'm on a 3 day vacation, but I can probably start a new runtime build in the evening and let the tests run tomorrow.

hoelzro commented 4 years ago

@murdegern Sounds good, enjoy your vacation!

murdegern commented 4 years ago

Tests are running, and it looks very good so far! No errors with perl 5.24 nor 5.14. I'll keep on hammering our test systems, but I think you've nailed it.

hoelzro commented 4 years ago

Excellent! If things still look good by the weekend I'll make a new release.

murdegern commented 4 years ago

At least our tests run fine now, with different perl versions.

hoelzro commented 4 years ago

@murdegern I just published version 0.17 with the fix - if that works for you, I'll close this issue. Thanks again for the report and helping to test!

murdegern commented 4 years ago

Fixed by @hoelzro in version 0.17