Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

this code :
use Inline C => Config => BUILD_NOISY => 1; use Inline C => << 'EOC'; void inc_refcnt(SV * sv ) { SvREFCNT_inc(sv); } SV * get_refcnt(SV * sv) { return newSVuv(svREFCNT(sv)); } EOC my $globalVAR = 1; my $refCNT; if ( 1 ) { $refCNT = get_refcnt($globalVAR); $globalVAR++; inc_refcnt($globalVAR); $refCNT = get_refcnt($globalVAR); } else { die; }
resulted in :
/tmp/ccPL0xed.s: Assembler messages: /tmp/ccPL0xed.s:10: Error: `8(%rdi)' is not a valid 32 bit base/index +expression /tmp/ccPL0xed.s:25: Error: suffix or operands invalid for `movslq' /tmp/ccPL0xed.s:43: Error: `8(%rsp)' is not a valid 32 bit base/index +expression
and the <>.xs (as well as the <>.c) file looks fine. how does one debug assembler errors?

Replies are listed 'Best First'.
Re: Inline C : assembler errors!
by syphilis (Archbishop) on Oct 03, 2006 at 01:00 UTC
    There's a typo in the code - it should be "SvREFCNT" not "svREFCNT" in the get_refcnt() function. But I don't think that would produce the errors you see.

    I have no idea what is producing those errors. I have never seen "Asembler messages" produced when running Inline::C code. Are you generally able to build perl extensions (ie modules whose source includes XS files) ? Can you show us what the XS file that Inline::C generated in the build directory looks like.

    Once the typo is fixed, the code compiles and runs correctly for me on both Win32 and Linux (mandrake-9.1).

    Cheers,
    Rob

      thanks for spotting the typo. it still failed to compile and it still fails at the assembler stage. many of the assembler messages are :

      8(%rdi)' is not a valid 32 bit base/index expression
      yet i am on a 64b opteron. all the perl packages are 64b. could it be that another flag is needed to tell the assembler this?

      anyway, the XS file is :

      #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "INLINE.h" void inc_refcnt(SV * sv ) { SvREFCNT_inc(sv); } SV * get_refcnt(SV * sv) { return newSVuv(svREFCNT(sv)); } MODULE = exp_pl_aa05 PACKAGE = main PROTOTYPES: DISABLE void inc_refcnt (sv) SV * sv PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; inc_refcnt(sv); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ SV * get_refcnt (sv) SV * sv
      the resulting C code is :
      /* * This file was generated automatically by xsubpp version 1.9508 from + the * contents of exp_pl_aa05.xs. Do not edit this file, edit exp_pl_aa05 +.xs instead. * * ANY CHANGES MADE HERE WILL BE LOST! * */ #line 1 "exp_pl_aa05.xs" #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "INLINE.h" void inc_refcnt(SV * sv ) { SvREFCNT_inc(sv); } SV * get_refcnt(SV * sv) { return newSVuv(svREFCNT(sv)); } #line 24 "exp_pl_aa05.c" XS(XS_main_inc_refcnt) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: main::inc_refcnt(sv)"); SP -= items; { SV * sv = ST(0); #line 23 "exp_pl_aa05.xs" I32* temp; #line 35 "exp_pl_aa05.c" #line 25 "exp_pl_aa05.xs" temp = PL_markstack_ptr++; inc_refcnt(sv); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ #line 46 "exp_pl_aa05.c" PUTBACK; return; } } XS(XS_main_get_refcnt) { dXSARGS; if (items != 1) Perl_croak(aTHX_ "Usage: main::get_refcnt(sv)"); { SV * sv = ST(0); SV * RETVAL; RETVAL = get_refcnt(sv); ST(0) = RETVAL; sv_2mortal(ST(0)); } XSRETURN(1); } #ifdef __cplusplus extern "C" #endif XS(boot_exp_pl_aa05) { dXSARGS; char* file = __FILE__; XS_VERSION_BOOTCHECK ; newXS("main::inc_refcnt", XS_main_inc_refcnt, file); newXS("main::get_refcnt", XS_main_get_refcnt, file); XSRETURN_YES; }
        Nothing obvious (to me, anyway) in the C or XS files.

        Does this happen only with Inline::C ?
        Do you get the same sort of behaviour with a "Hello World" type of Inline::C script ? (ie a script that doesn't explicitly use any of the perl API functions.)
        Do you get the same sort of behaviour whenever you build a perl extension ?

        Cheers,
        Rob
Re: Inline C : assembler errors!
by Fletch (Bishop) on Oct 03, 2006 at 12:15 UTC

    Checking google for "is not a valid 32 bit base/index expression" brings up some hits that say this can happen when you're trying to compile 64-bit code with a 32-bit copy of binutils. Bug your sysadmin and have them make sure that all of the tools in your compiler chain (Perl, GCC, binutils) match and were compiled with the same options (i.e. all 64-bit).

Re: Inline C : assembler errors!
by GrandFather (Saint) on Oct 03, 2006 at 00:24 UTC

    Very likely there are those who will guess correctly, but what compiler and OS are you using?


    DWIM is Perl's answer to Gödel
      the makefile down in _INLINE/build/<>/ uses "cc"; so i assume that it's whatever the environment variable is.
      CC: gcc version 3.2.3 20030502 OS : red hat 2.4.21-47.ELsmp