From: Paul C Date: 2001-03-13T13:40:08+09:00 Subject: [ruby-talk:12542] Re: Strange segmentation fault problem with C++ extension I know it is probably bad form to reply to oneself however I just wanted to apologise for the awful grammar/spelling of this message. Of course, the errors only revealed themselves after the message has been posted and I was reading through the version sent out to the world ! Regards, Paul "Paul C" wrote in message news:tar6s72d93ts58@corp.supernews.com... > Hi, > > I have been beating my head against the monitor for a couple of days with a > repeatable segmentation problem with a C++ extension - I am sure that there > is something obvious that I am missing and would be grateful for any advice. > > I am trying to create a Ruby wrapper for the ZIPIOS C++ Zip file reader > library (http://zipios.sourceforge.net). I managed to get this mostly > working however I have been stuck with a deterministic problem with the > extension core dumping in the method to extract a zip file entry under the > following conditions - > > - Running under IRB > > - Calling the method without a 'begin/rescue' block (ie caught interactively > by IRB) > > - (Optional) Call the method with a filename which exists in archive -> OK > > - Call the method with a filename which does not exist in the archive -> > Throws an exception > > - Call the method with a filename which does exist -> Core Dump > > If the failing method call is enclosed in a begin/rescue block the problem > goes away (which would always be the case outside the interactive shell). > > If the method is called multiple times with a valid entry or even multiple > times with an invalid entry it works fine - it is just the sequence > invalid/valid which causes the program to crash. > > Unfortunately I am not a C++ programmer (and following this experience have > no desire to become one) so I would ask you to excuse the code - however I > wasnt able to find a C Zip file library. I am concerned that there is an > underlying problem in the code somewhere which is causing this but havent > been able to make any progress (I will of course be releasing the module to > the RAA once I get this fixed). > > I have instrumented the module and the strange thing is that there is no > apparent difference in the calling sequence between a method that succeeds > and a subsequent method that causes a segmentation fault (after an > intervening request for an non-existant entry). > > The source code for the method that is failing is at the end of the > message - if anyone would like the source code to the whole extension please > let me know and I will e-mail it. > > The debug trace below is equivalent for the first/third calls (which should > be the same without the failing call between them). The final debug print of > the return VALUE is generated immediately before the method returns and > shows the the VALUE to be returned has been created successfully within the > method. The method segemntation faults when the functio tries to return the > VALUE. > > I am at a loss as to why this happens - any suggestions ? > > Regards, Paul > > PS. I forgot the obligatory thanks to Matz and the Ruby community for a > great language - it is a pleasure to use (and hopefully extend if I can get > this !#$&&*# module working!) > > PPS. Versions are - Ruby 1.6.3 / NetBSD 1.5 > > =========== DEBUG TRACE =========== > > # irb --prompt xmp > > require 'Zip' > ==>true > > z = Zip::ZipFile.new "test.zip" > ==># > > z.entries { |e| print e.path, "\n" } # Get Zip Directory > extconf.rb > Makefile > ==># > > z.entry "extconf.rb" # OK > (zip.cpp:186) MSG: Entering Function #ZipFile_entry > (zip.cpp:187) VALUE: self -> # > (zip.cpp:191) PTR: ZipFile ->135501760 > (zip.cpp:201) MSG: GetEntry OK > (zip.cpp:203) PTR: ConstEntryPointer ->135870784 > (zip.cpp:205) VALUE: zipLocalEntry -> # @path="extconf.rb"> > ==># > > z.entry "zzzzzzz" # Invalid Entry > (zip.cpp:186) MSG: Entering Function #ZipFile_entry > (zip.cpp:187) VALUE: self -> # > (zip.cpp:191) PTR: ZipFile ->135501760 > (zip.cpp:196) MSG: GetEntry Failed > RuntimeError: Entry not found > (irb):10:in `entry' > (irb):10:in `irb_binding' > > z.entry "extconf.rb" # Should be OK > (zip.cpp:186) MSG: Entering Function #ZipFile_entry > (zip.cpp:187) VALUE: self -> # > (zip.cpp:191) PTR: ZipFile ->135501760 > (zip.cpp:201) MSG: GetEntry OK > (zip.cpp:203) PTR: ConstEntryPointer ->136008256 > (zip.cpp:205) VALUE: zipLocalEntry -> # @path="extconf.rb"> > (irb):12: [BUG] Segmentation fault > ruby 1.6.3 (2001-03-07) [i386-netbsd1.5] > Abort (core dumped) > > =========== METHOD SOURCE =========== > > static VALUE ZipFile_entry ( VALUE self, VALUE name ) { > > VALUE zipLocalEntry = Qnil ; > ConstEntryPointer entry ; > ConstEntryPointer *ptr_entry ; > ZipFile *zf ; > > const string sname = STR2CSTR(name) ; > > DEBUG_MSG("Entering Function #ZipFile_entry") ; > DEBUG_VALUE("self",self) ; > > Get_ZipFile ( self, zf ) ; > > DEBUG_PTR("ZipFile",zf) ; > > try { > if ( (entry = zf->getEntry(sname)) == 0 ) { > > DEBUG_MSG("GetEntry Failed") ; > rb_raise ( rb_eRuntimeError, "Entry not found" ) ; > } > else { > > DEBUG_MSG("GetEntry OK") ; > ptr_entry = new ConstEntryPointer ( entry ) ; > DEBUG_PTR("ConstEntryPointer",ptr_entry) ; > zipLocalEntry = ZipLocalEntry_new ( ptr_entry ) ; > DEBUG_VALUE("zipLocalEntry",zipLocalEntry) ; > > return zipLocalEntry ; > } > } > catch ( exception &excp ) { > > DEBUG_MSG("Exception") ; > rb_raise ( rb_eRuntimeError, excp.what() ) ; > } > } > > > > > >