Discussion:
segfault while invoking C++ class destructor
(too old to reply)
Dongxu Ma
2005-08-10 04:31:54 UTC
Permalink
Hi there,

I am learning how to port C++ interface to Perl by perlxs. At first, I
wrote a simple C++ class,which has one public method only, compiled as
libtest.so.
----------------------------------test.h
-------------------------------------------
#ifndef _TEST_H
#define _TEST_H
class Test
{
public:
Test();
~Test();
void print(void);
};
#endif
----------------------------------------------------------------------------------------
--------------------------------test.cpp----------------------------------------------
#include "test.h"
#include <iostream.h>
Test::Test()
{
cout<<"new inst created"<<endl;
}
Test::~Test()
{
cout<<"inst destroyed"<<endl;
}
void
Test::print(void)
{
cout<<"Test::print called"<<endl;
}
--------------------------------------------------------------------------------------------

Then called `h2xs -A -n Test`, wrote Makefile.PL Test.xs and typemap:

---------------------------------Makefile.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'
libtest.so under subdir clib
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
);
-------------------------------------------------------------------------------------------
-------------------------------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()
CODE:
delete THIS;
fprintf(stdout, "here\n");

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 = ($type)SvIV($arg);
} else {
warn(\"$arg is not a blessed object\");
XSRETURN_UNDEF;
}

################
OUTPUT
T_OBJECT
sv_setref_pv($arg, \"Test\", (void*)$var);
---------------------------------------------------------------------------------------------

After running `perl Makefile.PL` and `make`, I got Test.so
Finally, I wrote a test script:
---------------------test.plx---------------------------------------------------------------
#! /usr/bin/perl
use warnings;
use strict;

use blib q(blib);
use Test ();

my $inst = Test::->new();
$inst->print();

undef $inst;
----------------------------------------------------------------------------------------------

ran it in shell I got:
-----------------------output of
`test.plx`-------------------------------------------------
***@cn_dongxu ~/tmp/Test $ ./test.plx
new inst created
Test::print called
inst destroyed
Segmentation fault
***@cn_dongxu ~/tmp/Test $
----------------------------------------------------------------------------------------------

while running the same script in perldb, I got:
-------------------output of `perl -d -MDevel::Peek test.plx`
------------------------
Loading DB routines from perl5db.pl version 1.28
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(test.plx:9): my $inst = Test::->new();
DB<1> n
new inst created
main::(test.plx:10): $inst->print();
DB<1> Dump $inst
SV = PVMG(0x844b680) at 0x81aea98
REFCNT = 2
FLAGS = (PADBUSY,PADMY,ROK)
IV = 0
NV = 0
RV = 0x852a01c
SV = PVMG(0x844b700) at 0x852a01c
REFCNT = 1
FLAGS = (OBJECT,IOK,pIOK)
IV = 135961544
NV = 0
PV = 0
STASH = 0x8416f74 "Test"
PV = 0x852a01c ""
CUR = 0
LEN = 0

DB<2> s
Test::print called
main::(test.plx:12): undef $inst;
DB<2> s
inst destroyed
here
Debugged program terminated. Use q to quit or R to restart,
use O inhibit_exit to avoid stopping after program termination,
h q, h R or h O to get additional info.
DB<2>
-------------------------------------------------------------------------------------------

As seen, in debug mode, "DELETE THIS;", which calls Test::~Test() in
c++ code, returned successfully. While in normal shell, it caused a
segfault.
Is there any error in my code above? Does anyone know the reason?
Thanks in advance.
--
Bst Rgrs, Dongxu
Reinhard Pagitsch
2005-08-10 11:51:53 UTC
Permalink
Hello,

I think
void
Test::DESTROY()
CODE:
delete THIS;

makes the segmentation fault.

Try the following:

MODULE = Test PACKAGE = Test

Test *
Test::new()
void
Test::DESTROY()

NO_OUTPUT void
Test::print()
CODE:
THIS->print();


regards
Reinhard
Post by Dongxu Ma
Hi there,
I am learning how to port C++ interface to Perl by perlxs. At first, I
wrote a simple C++ class,which has one public method only, compiled as
libtest.so.
----------------------------------test.h
-------------------------------------------
#ifndef _TEST_H
#define _TEST_H
class Test
{
Test();
~Test();
void print(void);
};
#endif
----------------------------------------------------------------------------------------
--------------------------------test.cpp----------------------------------------------
#include "test.h"
#include <iostream.h>
Test::Test()
{
cout<<"new inst created"<<endl;
}
Test::~Test()
{
cout<<"inst destroyed"<<endl;
}
void
Test::print(void)
{
cout<<"Test::print called"<<endl;
}
--------------------------------------------------------------------------------------------
---------------------------------Makefile.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
()),
CC => 'g++',
LD => 'g++',
LDFLAGS => '-g',
LDDLFLAGS => '-shared -g',
LIBS => ['-Lclib -ltest'], # e.g., '-lm'
libtest.so under subdir clib
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
INC => '-I.', # e.g., '-I. -I/usr/include/other'
XSOPT => ' -C++ ',
# OBJECT => '$(O_FILES)', # link all the C files too
);
-------------------------------------------------------------------------------------------
-------------------------------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()
delete THIS;
fprintf(stdout, "here\n");
NO_OUTPUT void
Test::print()
THIS->print();
---------------------------------------------------------------------------------------------
-----------------------------typemap----------------------------------------------------
TYPEMAP
Test * T_OBJECT
################
INPUT
T_OBJECT
if(sv_isa($arg, \"Test\") && sv_isobject($arg)) {
$var = ($type)SvIV($arg);
} else {
warn(\"$arg is not a blessed object\");
XSRETURN_UNDEF;
}
################
OUTPUT
T_OBJECT
sv_setref_pv($arg, \"Test\", (void*)$var);
---------------------------------------------------------------------------------------------
After running `perl Makefile.PL` and `make`, I got Test.so
---------------------test.plx---------------------------------------------------------------
#! /usr/bin/perl
use warnings;
use strict;
use blib q(blib);
use Test ();
my $inst = Test::->new();
$inst->print();
undef $inst;
----------------------------------------------------------------------------------------------
-----------------------output of
`test.plx`-------------------------------------------------
new inst created
Test::print called
inst destroyed
Segmentation fault
----------------------------------------------------------------------------------------------
-------------------output of `perl -d -MDevel::Peek test.plx`
------------------------
Loading DB routines from perl5db.pl version 1.28
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(test.plx:9): my $inst = Test::->new();
DB<1> n
new inst created
main::(test.plx:10): $inst->print();
DB<1> Dump $inst
SV = PVMG(0x844b680) at 0x81aea98
REFCNT = 2
FLAGS = (PADBUSY,PADMY,ROK)
IV = 0
NV = 0
RV = 0x852a01c
SV = PVMG(0x844b700) at 0x852a01c
REFCNT = 1
FLAGS = (OBJECT,IOK,pIOK)
IV = 135961544
NV = 0
PV = 0
STASH = 0x8416f74 "Test"
PV = 0x852a01c ""
CUR = 0
LEN = 0
DB<2> s
Test::print called
main::(test.plx:12): undef $inst;
DB<2> s
inst destroyed
here
Debugged program terminated. Use q to quit or R to restart,
use O inhibit_exit to avoid stopping after program termination,
h q, h R or h O to get additional info.
DB<2>
-------------------------------------------------------------------------------------------
As seen, in debug mode, "DELETE THIS;", which calls Test::~Test() in
c++ code, returned successfully. While in normal shell, it caused a
segfault.
Is there any error in my code above? Does anyone know the reason?
Thanks in advance.
--
Bst Rgrs, Dongxu
Loading...