-----BEGIN PGP SIGNED MESSAGE-----
Moin,
I have written a (simple?) routine in XS that uses the GMP library to
calculate the modular inverse. When running a small test file, it segfaults
at the end of the testfile like this:
...
ok 253
ok 254
ok 255
Segmentation fault
Running it under valgrind gives the text below.
Here is the XS code. I have tried several variations, but to no avail (I
really don't know what I do, maybe I should first read the Perl Embedding
book fully :) Does somebody spot something wrong or something I could do
better?
The routine basically only returns (undef,undef) (but not in my testcase!) or
(4404, '+'). The case of ($somenumber, '-') shouldn't happen (and does not in
my testcase, anyway).
void
_modinv(class,x,y)
SV* class
mpz_t* x
mpz_t* y
PREINIT:
int rc, sign;
SV* s;
PPCODE:
rc = mpz_invert(*x, *x, *y);
EXTEND(SP, 2); /* we return two values */
if (rc == 0)
{
/* inverse doesn't exist, return value undefined */
PUSHs ( &PL_sv_undef );
PUSHs ( &PL_sv_undef );
}
else
{
/* inverse exists, get sign */
sign = mpz_sgn (*x);
/* absolute result */
mpz_abs (*x, *x);
PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)x));
if (sign >= 0)
{
PUSHs ( &PL_sv_undef ); /* result is ok, keep it */
}
else
{
s = sv_newmortal();
sv_setpvn (s, "-", 1);
PUSHs ( s ); /* result must be negated */
}
}
I tried to allocate a new GMP object and return a ref to that instead, but
this is exactly the same segfault.
Thank you in advance,
Tels
ok 255
==5047== Invalid read of size 4
==5047== at 0x41F090A5: __gmpz_clear (in /usr/lib/libgmp.so.3.3.2)
==5047== by 0x41ED12A1: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/
math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so)
==5047== by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl)
==5047== by 0x8060DCE: Perl_call_sv (in /usr/bin/perl)
==5047== Address 0x41D18D4C is 0 bytes inside a block of size 12 free'd
==5047== at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so)
==5047== by 0x41ED12A9: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/
math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so)
==5047== by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl)
==5047== by 0x8060DCE: Perl_call_sv (in /usr/bin/perl)
==5047==
==5047== Invalid read of size 4
==5047== at 0x41F090AE: __gmpz_clear (in /usr/lib/libgmp.so.3.3.2)
==5047== by 0x41ED12A1: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/
math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so)
==5047== by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl)
==5047== by 0x8060DCE: Perl_call_sv (in /usr/bin/perl)
==5047== Address 0x41D18D54 is 8 bytes inside a block of size 12 free'd
==5047== at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so)
==5047== by 0x41ED12A9: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/
math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so)
==5047== by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl)
==5047== by 0x8060DCE: Perl_call_sv (in /usr/bin/perl)
==5047==
==5047== Invalid free() / delete / delete[]
==5047== at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so)
==5047== by 0x41F010BC: __gmp_default_free (in /usr/lib/libgmp.so.3.3.2)
==5047== by 0x41F090BB: __gmpz_clear (in /usr/lib/libgmp.so.3.3.2)
==5047== by 0x41ED12A1: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/
math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so)
==5047== Address 0x41D18D88 is 0 bytes inside a block of size 8 free'd
==5047== at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so)
==5047== by 0x41F010BC: __gmp_default_free (in /usr/lib/libgmp.so.3.3.2)
==5047== by 0x41F090BB: __gmpz_clear (in /usr/lib/libgmp.so.3.3.2)
==5047== by 0x41ED12A1: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/
math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so)
==5047==
==5047== Invalid free() / delete / delete[]
==5047== at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so)
==5047== by 0x41ED12A9: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/
math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so)
==5047== by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl)
==5047== by 0x8060DCE: Perl_call_sv (in /usr/bin/perl)
==5047== Address 0x41D18D4C is 0 bytes inside a block of size 12 free'd
==5047== at 0x40028E01: free (in /usr/lib/valgrind/vgskin_memcheck.so)
==5047== by 0x41ED12A9: XS_Math__BigInt__GMP_DESTROY (in /home/te/perl/
math/Math-BigInt-GMP-1.13/blib/arch/auto/Math/BigInt/GMP/GMP.so)
==5047== by 0x80C2786: Perl_pp_entersub (in /usr/bin/perl)
==5047== by 0x8060DCE: Perl_call_sv (in /usr/bin/perl)
==5047==
==5047== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 1)
==5047== malloc/free: in use at exit: 613982 bytes in 12112 blocks.
==5047== malloc/free: 32648 allocs, 20538 frees, 12875889 bytes allocated.
==5047== For a detailed leak analysis, rerun with: --leak-check=yes
==5047== For counts of detected errors, rerun with: -v
- --
Signed on Sat Jan 10 16:03:05 2004 with key 0x93B84C15.
Visit my photo gallery at http://bloodgate.com/photos/
PGP key on http://bloodgate.com/tels.asc or per email.
"Yeah. Whatever."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux)
Comment: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.
iQEVAwUBQAAV0HcLPEOTuEwVAQEy2gf/UtDtuHq6Xy2qpsr6kqanvcVZcc4mKBDq
RAvqnuE/1izRCN9VyLS18f4CR6nzJ3mS05lhZl9EfJWf1zrcls4UlvRCerdCq533
aK81kEqfBA8De8++pEESs5sS3XSKz+jaM5mh0Drem4SeArulY2+a+WlFRc3VcLi5
Zj+SU9brxlWV/rcM4LYJxZB10unusaDtTFI3VUJROPIb8DSAa7NT11GPgt9czVtx
vsUUPDJYQFep7xEmXy8oKWN5cOjFlRfHLUSlziezWuQZ5Bf3o26vPY9uVzGNJ/Iu
SAZ8XhiS24XBRKR98y5EWy3mBOs+kCjr5cdy3yG1c0hP1lwDMlx5Yw==
=5EeZ
-----END PGP SIGNATURE-----