Hi All,

I am learning how to use XS (C). 
Firstly, I wrote a simple C++ class, compiled to libtest.so. A simple
main proved the test lib works fine.
--------------------------------test.h-------------------------------
#ifndef _TEST_H
#define _TEST_H
class Test 
{
  public:
    Test();
    ~Test();
    void print(void);
  private:
    int i;
};
#endif
----------------------------------------------------------------------
----------------------------test.cpp-------------------------------
#include "test.h"
#include <iostream.h>

Test::Test()
{
    i = 1;
    cout<<"new inst created"<<endl;
}

Test::~Test()
{
    cout<<"inst destroyed"<<endl;
}

void
Test::print(void)
{
    cout<<"i = "<< this->i << endl;
    cout<<"Test::print called"<<endl;
}
-----------------------------------------------------------------------

Then, I wrote XS stuff and a test perl script(refer to below). The
script got a segfault while invoking `delete this' in c++ code.
Besides, the initial value of member variable i missed also.
-------------- output of `./test.plx -------------------------------
[EMAIL PROTECTED] ~/tmp/Test $ ./test.plx 
new inst created
i = 136090952
Test::print called
inst destroyed
Segmentation fault
-----------------------------------------------------------------------

I checked memleak via valgrind:
------ output of `valgrind --leak-check=yes test.plx' ------
[EMAIL PROTECTED] ~/tmp/Test $ valgrind --leak-check=yes test.plx 
==31931== Memcheck, a memory error detector for x86-linux.
==31931== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==31931== Using valgrind-2.4.0, a program supervision framework for x86-linux.
==31931== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==31931== For more details, rerun with: -v
==31931== 
new inst created
i = 464868768
Test::print called
inst destroyed
==31931== Invalid free() / delete / delete[]
==31931==    at 0x1B905A4E: operator delete(void*) (in
/usr/lib/valgrind/vgpreload_memcheck.so)
==31931==    by 0x1BEE0229: XS_Test_DESTROY(interpreter*, cv*) (Test.c:52)
==31931==  Address 0x1BACBDE4 is 756 bytes inside a block of size 4080 alloc'd
==31931==    at 0x1B9052F4: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==31931==    by 0x80D3291: Perl_safesysmalloc (in /usr/bin/perl5.8.7)
==31931== 
==31931== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 41 from 2)
==31931== malloc/free: in use at exit: 753961 bytes in 12648 blocks.
==31931== malloc/free: 24174 allocs, 11527 frees, 1316185 bytes allocated.
==31931== For counts of detected errors, rerun with: -v
==31931== searching for pointers to 12648 not-freed blocks.
==31931== checked 1114300 bytes.
==31931== 
==31931== 
==31931== 5 bytes in 1 blocks are definitely lost in loss record 2 of 21
==31931==    at 0x1B9052F4: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==31931==    by 0x80D46CE: Perl_savesharedpv (in /usr/bin/perl5.8.7)
==31931== 
==31931== 
==31931== 192 bytes in 1 blocks are definitely lost in loss record 11 of 21
==31931==    at 0x1B905DFB: realloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==31931==    by 0x80D3424: Perl_safesysrealloc (in /usr/bin/perl5.8.7)
==31931== 
==31931== 
==31931== 14709 (1991 direct, 12718 indirect) bytes in 14 blocks are
definitely lost in loss record 14 of 21
==31931==    at 0x1B9052F4: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==31931==    by 0x80D3291: Perl_safesysmalloc (in /usr/bin/perl5.8.7)
==31931== 
==31931== 
==31931== 6160 bytes in 1 blocks are possibly lost in loss record 17 of 21
==31931==    at 0x1B905DFB: realloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==31931==    by 0x80D3424: Perl_safesysrealloc (in /usr/bin/perl5.8.7)
==31931== 
==31931== 
==31931== 181636 bytes in 14 blocks are possibly lost in loss record 20 of 21
==31931==    at 0x1B9052F4: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so)
==31931==    by 0x80D3291: Perl_safesysmalloc (in /usr/bin/perl5.8.7)
==31931== 
==31931== LEAK SUMMARY:
==31931==    definitely lost: 2188 bytes in 16 blocks.
==31931==    indirectly lost: 12718 bytes in 80 blocks.
==31931==      possibly lost: 187796 bytes in 15 blocks.
==31931==    still reachable: 551259 bytes in 12537 blocks.
==31931==         suppressed: 0 bytes in 0 blocks.
==31931== Reachable blocks (those to which a pointer was found) are not shown.
==31931== To see them, rerun with: --show-reachable=yes
-------------------------------------------------------------------

According to typemap in ExtUtils and perl.h, casting IV to pointer
should be safe in this case, since on my machine(32bit, kernel
2.6.12), sizeof(int) == 4, which is the same as a  pointer. Does
anyone have any idea about this issue?

Refer to XS source below:
---------------------- Test.xs -----------------------------------
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

#include "clib/test.h"
#include "stdio.h"

MODULE = Test           PACKAGE = Test          

Test *
Test::new()

void
Test::DESTROY()

NO_OUTPUT void
Test::print()
CODE:
        THIS->print();
--------------------------------------------------------------------
-------------------------typemap-------------------------------
TYPEMAP
Test *          T_OBJECT

################
INPUT
T_OBJECT
        if(sv_isa($arg, \"Test\") && sv_isobject($arg)) {
                $var = INT2PTR($type, SvIV($arg));
        } else {
                warn(\"$arg is not a blessed object\");
                XSRETURN_UNDEF;
        }

################
OUTPUT
T_OBJECT
        sv_setref_pv($arg, \"Test\", (void*)$var);
---------------------------------------------------------------------
----------------------Makefiel.PL---------------------------------
use 5.008007;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    NAME              => 'Test',
    VERSION_FROM      => 'lib/Test.pm', # finds $VERSION
    PREREQ_PM         => {}, # e.g., Module::Name => 1.1
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/Test.pm', # retrieve abstract from module
       AUTHOR         => 'A. U. Thor <>') :
         ()),
    CC                => 'g++',
    LD                => 'g++',
    LDFLAGS           => '-g',
    LDDLFLAGS         => '-shared -g',
    LIBS              => ['-Lclib -ltest'], # e.g., '-lm'
    DEFINE            => '', # e.g., '-DHAVE_SOMETHING'
    INC               => '-I.', # e.g., '-I. -I/usr/include/other'
    XSOPT             => ' -C++ ',
        # Un-comment this if you add C files to link with later:
    # OBJECT            => '$(O_FILES)', # link all the C files too
);
----------------------------------------------------------------------
-- 
Bst Rgrs, Dongxu

Reply via email to