Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

panic: leave_scope inconsistency. (need help creating Tie::PureDB)

by PodMaster (Abbot)
on Apr 07, 2003 at 18:46 UTC ( [id://248697]=perlquestion: print w/replies, xml ) Need Help??

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

So in response to Perl bindings for puredb, I started writing an interface to pure-db (Tie::PureDB), but I'm faced with confuzzlment. I'd really apreciate lots of help in figuring this out ;)(writing the rest of the interface should be trivial, just as soon as you help me figure out what's wrong with the little I got already).

http://crazyinsomniac.perlmonk.org/perl/files/Tie-PureDB-0.01.helpme.txt
http://crazyinsomniac.perlmonk.org/perl/files/Tie-PureDB-0.01.tar.bz2

E:\dev\PureDB\Tie-PureDB-0.01>perl Makefile.PL Checking if your kit is complete... Looks good Warning: '-L./pure-db-2.1/windows' changed to '-LE:/dev/PureDB/Tie-Pur +eDB-0.01/./pure-db-2.1/windows' Writing Makefile for Tie::PureDB E:\dev\PureDB\Tie-PureDB-0.01>nmake test Microsoft (R) Program Maintenance Utility Version 6.00.8168.0 Copyright (C) Microsoft Corp 1988-1998. All rights reserved. cp PureDB.pm blib\lib\Tie\PureDB.pm C:\Perl\bin\perl.exe C:\Perl\lib\ExtUtils/xsubpp -typemap C:\ +Perl\lib\ExtUtils\typemap -typemap typemap PureDB.xs > PureDB.xsc && C:\Perl\bin\perl.exe -MExtUtils::Command -e mv PureDB.xsc PureDB.c cl -c -I./pure-db-2.1/windows -nologo -O1 -MD -DNDEBUG -DWIN +32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT - +D PERL_IMPLICIT_SYS -DPERL_MSVCRT_READFIX -O1 -MD -DNDEBUG -DVERSION= +\"0.01\" -DXS_VERSION=\"0.01\" "-IC:\Perl\lib\CORE" PureDB.c PureDB.c PureDB.xs(32) : warning C4700: local variable 'RETVAL' used without ha +ving been initialized "Running Mkbootstrap for Tie::PureDB ()" C:\Perl\bin\perl.exe -MExtUtils::Command -e chmod 644 PureDB.b +s C:\Perl\bin\perl.exe -MExtUtils::Mksymlists -e "Mksymlists('N +AME'=>\"Tie::PureDB\", 'DLBASE' => 'PureDB', 'DL_FUNCS' => { }, 'FUN +C LIST' => [], 'IMPORTS' => { }, 'DL_VARS' => []);" link -out:blib\arch\auto\Tie\PureDB\PureDB.dll -dll -nologo -n +odefaultlib -release -libpath:"C:/Perl\lib\CORE" -machine:x86 PureD +B .obj C:\Perl\lib\CORE\perl56.lib E:\dev\PureDB\Tie-PureDB-0.01\pure- +db-2.1\windows\libpuredb_write.lib E:\dev\PureDB\Tie-PureDB-0.01\pure +- db-2.1\windows\libpuredb_read.lib "C:\Program Files\Microsoft Visual S +tudio\VC98\lib\oldnames.lib" "C:\Program Files\Microsoft Visual Studi +o \VC98\lib\kernel32.lib" "C:\Program Files\Microsoft Visual Studio\VC98 +\lib\user32.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\g +d i32.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\winspool.l +ib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\comdlg32.lib" +" C:\Program Files\Microsoft Visual Studio\VC98\lib\advapi32.lib" "C:\Pr +ogram Files\Microsoft Visual Studio\VC98\lib\shell32.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\ole32.lib" "C:\Program Files\Mi +crosoft Visual Studio\VC98\lib\oleaut32.lib" "C:\Program Files\Micros +o ft Visual Studio\VC98\lib\netapi32.lib" "C:\Program Files\Microsoft Vi +sual Studio\VC98\lib\uuid.lib" "C:\Program Files\Microsoft Visual Stu +d io\VC98\lib\wsock32.lib" "C:\Program Files\Microsoft Visual Studio\VC9 +8\lib\mpr.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\win +m m.lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib\version.lib" + "C:\Program Files\Microsoft Visual Studio\VC98\lib\odbc32.lib" "C:\P +r ogram Files\Microsoft Visual Studio\VC98\lib\odbccp32.lib" "C:\Program + Files\Microsoft Visual Studio\VC98\lib\msvcrt.lib" -def:PureDB.def Creating library blib\arch\auto\Tie\PureDB\PureDB.lib and object bl +ib\arch\auto\Tie\PureDB\PureDB.exp C:\Perl\bin\perl.exe -MExtUtils::Command -e chmod 755 blib\arc +h\auto\Tie\PureDB\PureDB.dll C:\Perl\bin\perl.exe -MExtUtils::Command -e cp PureDB.bs blib\ +arch\auto\Tie\PureDB\PureDB.bs C:\Perl\bin\perl.exe -MExtUtils::Command -e chmod 644 blib\arc +h\auto\Tie\PureDB\PureDB.bs C:\Perl\bin\perl.exe "-Iblib\lib" "-Iblib\arch" test.pl 1..1 ok 1 Success reading './pure-db-2.1/puredb.pdb' #Tie::PureDB::Read SV = RV(0x1aa2a58) at 0x1ab2394 REFCNT = 1 FLAGS = (PADBUSY,PADMY,ROK) RV = 0x1abf174 SV = PVMG(0x1c161c4) at 0x1abf174 REFCNT = 1 FLAGS = (OBJECT,IOK,pIOK) IV = 29481936 NV = 0 PV = 0 STASH = 0x1aaffec "Tie::PureDB::Read" # ok 2 $VAR1 = bless( do{\(my $o = 29481936)}, 'Tie::PureDB::Read' ); ok 3 Success reading './pure-db-2.1/puredb.pdb' ok 4 Success reading './pure-db-2.1/puredb.pdb' #looking for key42 ... Tie::PureDB::Read a system error occured: Bad file descriptor not ok 5 # Failed test 5 in test.pl at line 35 #begin tie testing Success reading './pure-db-2.1/puredb.pdb' ok 6 ok 7 # exists/fetch a system error occured: Bad file descriptor a system error occured: Bad file descriptor not ok 8 # Failed test 8 in test.pl at line 53 a system error occured: Bad file descriptor not ok 9 # Failed test 9 in test.pl at line 54 a system error occured: Bad file descriptor not ok 10 # Failed test 10 in test.pl at line 55 panic: leave_scope inconsistency. panic: leave_scope inconsistency. NMAKE : fatal error U1077: 'C:\Perl\bin\perl.exe' : return code '0x9' Stop. E:\dev\PureDB\Tie-PureDB-0.01>


MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
I run a Win32 PPM repository for perl 5.6x+5.8x. I take requests.
** The Third rule of perl club is a statement of fact: pod is sexy.

Replies are listed 'Best First'.
Re: panic: leave_scope inconsistency. (need help creating Tie::PureDB) (less XS)
by tye (Sage) on Apr 07, 2003 at 19:41 UTC

    I'll repeat my previous advice. Don't use T_OBJPTR. Instead, have your XS code deal with very simple C data types and do all of the object creation/destruction in wrapper methods written in Perl (as part of your module).

    The reason I advise this is exactly because XS code is so easy to get wrong and so hard to debug.

    sub new { my $ptr= xs_new( ... ); bless \$ptr, ...; } sub DESTROY { my $self= shift(@_); xs_free( $$self ); }
    and
    int xs_new( ... ) WHATEVER* pObj= ...; RETVAL= (int)pObj; void xs_free( self ) int self CODE: free( (void *)self );

                    - tye
      I have taken your advice, and after some tomfoolery, I have finished writing the xs.
      I still feel this is a really really ghetto way to go about it, but that's how it goes
      ;( I have asked the author of Extending and Embedding perl to take a look at the panic.
      I'm not holding my breath, but it'd be real slick if I got that version working ).

      Anyway, check it out, http://crazyinsomniac.perlmonk.org/perl/files/Tie-PureDB-0.02.tar.gz.
      The pod is scarce for now, but if you're curious how the interface works just look at the tests.

      Thanks for the strategy.
      I'd appreciate if people would give it a test run before I add the pod and release it on CPAN (aka feedback).

      BTW -- all XS programmers should use Safefree and New instead of malloc and free, in addition to PTR2IV and INT2PTR.

      MJD says you can't just make shit up and expect the computer to know what you mean, retardo!
      I run a Win32 PPM repository for perl 5.6x+5.8x. I take requests.
      ** The Third rule of perl club is a statement of fact: pod is sexy.

        Thanks for the notes on proper allocation/free and converting between pointers and integers.

        The approach I outlined is very similar to T_PTROBJ, both of which are about the best you can do (which isn't very good in my book) if you need to have Perl deal with data structures that Perl does not allocate.

        Since you can use Safefree/New, then you are allocating the space and you can have a better interface by having Perl allocate the space instead.

        SV * xs_new( ... ) CODE: size_t len= number_of_bytes_needed(); sv_grow( RETVAL, len ); // "malloc" void *buf= SvPV( RETVAL ); size_t used= constructor( buf, len, ... ); // Tell Perl how much of the buffer is actually in use: SvCUR_set( RETVAL, used );
        Then you end up with a Perl scalar that contains a string value which is the contents of the buffer you allocated and Perl will be happy to free() it when it needs to and you don't even need a DESTROY method for that anymore. You can also access the buffer data directly from Perl now in case there are simple things you want to do that don't really require that XS code be written.

        You can get the pointer to this buffer by simply using "char *" arguments in other XS functions.

        And if you want a destroy method for other reasons, then I'd still do the bless and DESTROY in Perl code rather than in XS.

        Be aware that passing this string value around directly in Perl can easily result in the value being copied (a new buffer malloc()d and the data copied from the old buffer to the new buffer) and that you can modify the buffer from Perl code such that Perl decides to realloc() the buffer which can relocate it in memory (and that both of these things can invalidate some types of data such a buffers that contain pointers into themselves).

        Note that the value is not copied when you use the string as an argument to a function but that typical Perl functions include my $buf= shift(@_); or my( $buf, ... )= @_; which is where the copy takes place. So using the string directly in an XS function with a parameter type of "char *" works great.

        I realize that PodMaster probably knows most or all of this, but I include this information for others that might read this node.

        So you might want to wrap this string up as an object so passing around the object will just be copying references to the string (or references to some data structure that contains the string) and the string itself won't get copied.

        Doing that means that you have an extra dereference required in your methods. You can do that in Perl, but if that is the only bit of "Perl written in C" that you need for that method, you might just do it all in XS. The big problems with writing "Perl in C" for XS is if you are creating things on the stack (everyone gets the mortal/refcount stuff wrong even though it isn't that complicated/confusing if you really get your mind around it) or trying to deal with Perl variables that users pass to you (XS code only deals with very vanilla variables and simply breaks in the face of tie or magic or a need for autovivification, etc. -- I've been thinking about croaking on "thinkfirst" in my XS code in future).

                        - tye

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://248697]
Approved by vek
Front-paged by diotalevi
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-03-29 07:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found