Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updated: When to "mortalize" a variable in Perl Inline::C

I am trying to wrap a C library into Perl. I have tinkered with XS but being unsuccessful I thought I should start simply with Inline::C. My question is on Mortalization. I have been reading perlguts as best as I am able, but am still confused. Do I need to call sv_2mortal on an SV* that is to be returned if I am not pushing it onto the stack?

(PS I really am working on a less than functional knowledge of C which is hurting me. I have a friend who knows C helping me, but he doesn't know any Perl).

I am providing a sample below. The function FLIGetLibVersion simply puts len characters of the library version onto char* ver. My question is will the version_return form of my C code leak memory?

N.B. any other comments on this code is welcomed.

#!/usr/bin/perl

use strict;
use warnings;

use 5.10.1;

use Inline (
  C => 'DATA',
  LIBS => '-lm -lfli',
  FORCE_BUILD => 1,
);

say version_stack();
say version_return();

__DATA__
__C__

#include <stdio.h>

#include "libfli.h"

void version_stack() {

  Inline_Stack_Vars;
  Inline_Stack_Reset;

  size_t len = 50;
  char ver[len];

  FLIGetLibVersion(ver, len);

  Inline_Stack_Push(sv_2mortal(newSVpv(ver,strlen(ver))));
  Inline_Stack_Done;

}

SV* version_return() {

  size_t len = 50;
  char ver[len];

  FLIGetLibVersion(ver, len);
  SV* ret = newSVpv(ver, strlen(ver));

  return ret;

}

Edit:

In an attempt to answer this myself, I tried changing the line to

SV* ret = sv_2mortal(newSVpv(ver, strlen(ver)));

and now when I run the script I get the same output that I did previously plus an extra warning. Here is the output:

Software Development Library for Linux 1.99
Software Development Library for Linux 1.99
Attempt to free unreferenced scalar: SV 0x2308aa8, Perl interpreter: 0x22cb010.

I imagine that this means that I don't need to mortalize in this case? I suspect that the error is saying that I marked for collection something that was already in line for collection. Can someone confirm for me that that is what that warning means?

like image 711
Joel Berger Avatar asked Nov 14 '22 02:11

Joel Berger


1 Answers

I've been maintaining Set::Object for many years and had this question, too - perhaps best to look at the source of that code to see when stuff should be mortalised (github.com/samv/Set-Object). I know Set::Object has it right after many changes. I think though, it's whenever you're pushing the SV onto the return stack. Not sure how Inline changes all that.

like image 191
Sam Vilain Avatar answered Dec 24 '22 20:12

Sam Vilain