Strange segmentation fault problem with C++ extension 
Author Message
 Strange segmentation fault problem with C++ extension

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://www.*-*-*.com/ ). 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:191) PTR: ZipFile ->135501760
    (zip.cpp:201) MSG: GetEntry OK
    (zip.cpp:203) PTR: ConstEntryPointer ->135870784


z.entry "zzzzzzz"                      # Invalid Entry
    (zip.cpp:186) MSG: Entering Function #ZipFile_entry

    (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:191) PTR: ZipFile ->135501760
    (zip.cpp:201) MSG: GetEntry OK
    (zip.cpp:203) PTR: ConstEntryPointer ->136008256

(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() ) ;
    }

Quote:
}



Sat, 30 Aug 2003 12:13:50 GMT  
 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


Quote:
> 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:191) PTR: ZipFile ->135501760
>     (zip.cpp:201) MSG: GetEntry OK
>     (zip.cpp:203) PTR: ConstEntryPointer ->135870784
>     (zip.cpp:205) VALUE: zipLocalEntry -> #<Zip::ZipEntry:0x81545cc


> z.entry "zzzzzzz"                      # Invalid Entry
>     (zip.cpp:186) MSG: Entering Function #ZipFile_entry

>     (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:191) PTR: ZipFile ->135501760
>     (zip.cpp:201) MSG: GetEntry OK
>     (zip.cpp:203) PTR: ConstEntryPointer ->136008256
>     (zip.cpp:205) VALUE: zipLocalEntry -> #<Zip::ZipEntry:0x814d36c

> (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() ) ;
>     }
> }



Sat, 30 Aug 2003 12:40:36 GMT  
 Strange segmentation fault problem with C++ extension

P>             zipLocalEntry = ZipLocalEntry_new ( ptr_entry ) ;

 What is missing is the source of ZipLocalEntry_new, to see how you create
 your object.

Guy Decoux



Sat, 30 Aug 2003 14:03:41 GMT  
 Strange segmentation fault problem with C++ extension
Hi,

In message "[ruby-talk:12540] Strange segmentation fault problem with C++ extension"

|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.

Could you provide us the stacktrace of segfault, probably using where
command of gdb.   It would help us a lot.

                                                        matz.



Sat, 30 Aug 2003 14:01:00 GMT  
 Strange segmentation fault problem with C++ extension
Matz,

Thanbks for your response. I apologise for not providing the stacktrace
(wasnt thinking) - here it is.

Please let me know if there is any more information you need

Regards, Paul

#0  0x4816bbb7 in kill ()
#1  0x4816ad91 in abort ()
#2  0x80ae549 in rb_bug () at error.c:178
#3  0x809859d in sigsegv () at signal.c:385
#4  0xbfbfdfc9 in ?? ()
#5  0x8058885 in call_cfunc (
    func=0x481f6798 <ZipFile_entry(unsigned long, unsigned long)>,
    recv=135709732, len=1, argc=1, argv=0xbfbf8a78) at eval.c:4194
#6  0x8058d4e in rb_call0 (klass=135143100, recv=135709732, id=12777,
argc=1,
    argv=0xbfbf8a78, body=0x80e187c, nosuper=1) at eval.c:4327
#7  0x80593f3 in rb_call (klass=135143100, recv=135709732, mid=12777,
argc=1,
    argv=0xbfbf8a78, scope=0) at eval.c:4527
#8  0x8054df4 in rb_eval (self=135322760, n=0x814d3a8) at eval.c:2531
#9  0x8051917 in eval_node (self=135322760, node=0x814d3a8) at eval.c:1077
#10 0x8059c0e in eval (self=135322760, src=135597792, scope=135255880,
    file=0x8190260 "(irb)", line=11) at eval.c:4818
#11 0x8059f72 in rb_f_eval (argc=4, argv=0xbfbf8fbc, self=135254860)
    at eval.c:4921
#12 0x8058871 in call_cfunc (func=0x8059e18 <rb_f_eval>, recv=135254860,
    len=-1, argc=4, argv=0xbfbf8fbc) at eval.c:4188
#13 0x8058d4e in rb_call0 (klass=135326860, recv=135254860, id=3649, argc=4,
    argv=0xbfbf8fbc, body=0x810d5d0, nosuper=1) at eval.c:4327
#14 0x80593f3 in rb_call (klass=135326860, recv=135254860, mid=3649, argc=4,
    argv=0xbfbf8fbc, scope=1) at eval.c:4527
#15 0x8054df4 in rb_eval (self=135254860, n=0x80f7884) at eval.c:2531
#16 0x80549ec in rb_eval (self=135254860, n=0x80f785c) at eval.c:2508
#17 0x8057610 in rb_yield_0 (val=4, self=135254860, klass=0, acheck=0)
    at eval.c:3583
#18 0x8054296 in rb_eval (self=135254860, n=0x80f57f0) at eval.c:2345
#19 0x805456d in rb_eval (self=135254860, n=0x80f5700) at eval.c:2395
#20 0x80590da in rb_call0 (klass=135547832, recv=135254860, id=9569, argc=0,
    argv=0x0, body=0x80f5700, nosuper=0) at eval.c:4439
#21 0x80593f3 in rb_call (klass=135547832, recv=135254860, mid=9569, argc=0,
    argv=0x0, scope=1) at eval.c:4527
#22 0x8054df4 in rb_eval (self=135254860, n=0x80f780c) at eval.c:2531
#23 0x8053f7b in rb_eval (self=135254860, n=0x80f77f8) at eval.c:2266
#24 0x80535f7 in rb_eval (self=135254860, n=0x80f75c8) at eval.c:2015
#25 0x8054332 in rb_eval (self=135254860, n=0x80f659c) at eval.c:2355
#26 0x8057610 in rb_yield_0 (val=4, self=135254860, klass=0, acheck=0)
    at eval.c:3583
#27 0x8054296 in rb_eval (self=135254860, n=0x80f5a34) at eval.c:2345
#28 0x805456d in rb_eval (self=135254860, n=0x80f5afc) at eval.c:2395
#29 0x80590da in rb_call0 (klass=135547832, recv=135254860, id=9401, argc=0,
    argv=0xbfbfaf00, body=0x80f5afc, nosuper=0) at eval.c:4439
#30 0x80593f3 in rb_call (klass=135547832, recv=135254860, mid=9401, argc=1,
#31 0x8054df4 in rb_eval (self=135254860, n=0x80f79ec) at eval.c:2531
#32 0x8053f7b in rb_eval (self=135254860, n=0x80f6560) at eval.c:2266
#33 0x8057610 in rb_yield_0 (val=135583072, self=135254860, klass=0,
acheck=0)
    at eval.c:3583
#34 0x8054296 in rb_eval (self=135253680, n=0x80e326c) at eval.c:2345
#35 0x80535f7 in rb_eval (self=135253680, n=0x80e371c) at eval.c:2015
#36 0x8057610 in rb_yield_0 (val=4, self=135253680, klass=0, acheck=0)
    at eval.c:3583
#37 0x8057815 in rb_f_loop () at eval.c:3674
#38 0x805887b in call_cfunc (func=0x8057804 <rb_f_loop>, recv=135253680,
    len=0, argc=0, argv=0x0) at eval.c:4191
#39 0x8058d4e in rb_call0 (klass=135326860, recv=135253680, id=3673, argc=0,
    argv=0x0, body=0x810d490, nosuper=1) at eval.c:4327
#40 0x80593f3 in rb_call (klass=135326860, recv=135253680, mid=3673, argc=0,
    argv=0x0, scope=1) at eval.c:4527
#41 0x8054df4 in rb_eval (self=135253680, n=0x80e3000) at eval.c:2531
#42 0x8053f7b in rb_eval (self=135253680, n=0x80e2fd8) at eval.c:2266
#43 0x80590da in rb_call0 (klass=135658292, recv=135253680, id=9553, argc=0,
    argv=0x0, body=0x80e2fd8, nosuper=0) at eval.c:4439
#44 0x80593f3 in rb_call (klass=135658292, recv=135253680, mid=9553, argc=0,
    argv=0x0, scope=0) at eval.c:4527
#45 0x8054df4 in rb_eval (self=135254860, n=0x80f7af0) at eval.c:2531
#46 0x8053f7b in rb_eval (self=135254860, n=0x80f7b54) at eval.c:2266
    argv=0xbfbfaefc, scope=1) at eval.c:4527
#47 0x80590da in rb_call0 (klass=135547832, recv=135254860, id=8817, argc=0,
    argv=0x0, body=0x80f7b54, nosuper=0) at eval.c:4439
#48 0x80593f3 in rb_call (klass=135547832, recv=135254860, mid=8817, argc=0,
    argv=0x0, scope=0) at eval.c:4527
#49 0x8054df4 in rb_eval (self=135558912, n=0x80ff930) at eval.c:2531
#50 0x8057610 in rb_yield_0 (val=2256142, self=135558912, klass=0, acheck=0)
    at eval.c:3583
#51 0x8060af0 in rb_f_catch (dmy=135558912, tag=2256142) at eval.c:8699
#52 0x8058885 in call_cfunc (func=0x8060a7c <rb_f_catch>, recv=135558912,
    len=1, argc=1, argv=0xbfbfcf00) at eval.c:4194
#53 0x8058d4e in rb_call0 (klass=135326860, recv=135558912, id=3737, argc=1,
    argv=0xbfbfcf00, body=0x810d238, nosuper=1) at eval.c:4327
#54 0x80593f3 in rb_call (klass=135326860, recv=135558912, mid=3737, argc=1,
    argv=0xbfbfcf00, scope=1) at eval.c:4527
#55 0x8054df4 in rb_eval (self=135558912, n=0x80ff994) at eval.c:2531
#56 0x8053f7b in rb_eval (self=135558912, n=0x80ff8f4) at eval.c:2266
#57 0x80535f7 in rb_eval (self=135558912, n=0x8100204) at eval.c:2015
#58 0x80590da in rb_call0 (klass=135550392, recv=135558912, id=5273, argc=0,
    argv=0xbfbfd86c, body=0x8100204, nosuper=0) at eval.c:4439
#59 0x80593f3 in rb_call (klass=135550392, recv=135558912, mid=5273, argc=1,
    argv=0xbfbfd868, scope=0) at eval.c:4527
#60 0x8054df4 in rb_eval (self=135322760, n=0x81011f4) at eval.c:2531
#61 0x8051917 in eval_node (self=135322760, node=0x81011f4) at eval.c:1077
#62 0x8051c75 in ruby_run () at eval.c:1207
#63 0x8050728 in main (argc=4, argv=0xbfbfdc04, envp=0xbfbfdc18) at
main.c:50
#64 0x80504cd in ___start ()


Quote:
> Hi,

> In message "[ruby-talk:12540] Strange segmentation fault problem with C++
extension"

> |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.

> Could you provide us the stacktrace of segfault, probably using where
> command of gdb.   It would help us a lot.

> matz.



Sat, 30 Aug 2003 21:51:54 GMT  
 Strange segmentation fault problem with C++ extension

Having played around a but more it looks like the behaviour of the module
when called within a begin/rescue block is a somewhat more complex that I
had described earlier and depending on context I can get a segmentation
fault in either ruby or IRB

Some of the calling sequences I have tried are shown below.

As far as I can work out the symptoms are -

In Ruby:
    - The sequence {ok-fail-ok} works ok within a block context
    - The sequence {ok-fail-ok-ok} causes a segmentation fault
    - Multiple sequences of {ok-fail} in separate blocks are ok
    - Multiple sequences of {ok-fail-ok} cause a segmentation fault

In IRB:
    - The sequence {ok-fail-ok} within a block always causes a segmentation
fault
    - Multiple repetitions of an {ok-fail} are ok

Also if I replace the 'raise' in the offending function with a 'return Qnil'
all the problems go away.

I am fairly sure that I have some sort of loose pointer in the code which
gets reset with the block context however I havent been able to track
anything down yet.

Apologies for the length of the post and thanks in advance for everybodies
help

Regards, Paul

==== test_ok.rb

:   require 'Zip'
:   z = Zip::ZipFile.new "test.zip"
:
:   begin
:       entry = z.entry "extconf.rb"
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:
:   begin
:       entry = z.entry "zzzzzz"
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:
:   begin
:       entry = z.entry "extconf.rb"
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end

# ruby test_ok.rb -> OK
# irb test_ok.rb -> Segmentation Fault

==== test_ok2.rb

:   require 'Zip'
:   z = Zip::ZipFile.new "test.zip"
:
:   5.times {
:       begin
:           entry = z.entry "extconf.rb"
:           print entry.inspect, "\n"
:       rescue RuntimeError => err
:           print "Caught Exception: #{err}\n"
:       end
:
:       begin
:           entry = z.entry "zzzzz"
:           print entry.inspect, "\n" #fails
:       rescue RuntimeError => err
:           print "Caught Exception: #{err}\n"
:       end
:   }

# ruby test_ok2.rb -> OK
# irb test_ok2.rb -> OK

==== test_ok3.rb

:   require 'Zip'
:   z = Zip::ZipFile.new "test.zip"
:
:   ["extconf.rb","zzzzzz"].each { |e|
:       begin
:           entry = z.entry e
:           print entry.inspect, "\n"
:       rescue RuntimeError => err
:           print "Caught Exception: #{err}\n"
:       end
:   }
:
:   ["extconf.rb","zzzzzz"].each { |e|
:       begin
:           entry = z.entry e
:           print entry.inspect, "\n"
:       rescue RuntimeError => err
:           print "Caught Exception: #{err}\n"
:       end
:   }

# ruby test_ok3.rb -> OK
# irb test_ok3.rb -> Segmentation Fault

# ruby test_ok3.rb -> OK
# irb test_ok3.rb -> Segmentation Fault

==== test_fail.rb

:   require 'Zip'
:   z = Zip::ZipFile.new "test.zip"
:
:   begin
:       entry = z.entry "extconf.rb"
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:
:   begin
:       entry = z.entry "zzzzzz"
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:
:   begin
:       entryntry = z.entry "extconf.rb"
:       print entryntry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:
:   begin
:       entry = z.entry "extconf.rb"
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end

# ruby test_fail.rb -> Segmentation Fault
# irb test_fail.rb -> Segmentation Fault

==== test_fail2.rb

:require 'Zip'
:
:z = Zip::ZipFile.new "test.zip"
:
:5.times {
:
:   begin
:       entry = z.entry "extconf.rb"
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:
:   begin
:       entry = z.entry "zzzzz"
:       print entry.inspect, "\n" #fails
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:
:   begin
:       entry = z.entry "extconf.rb"
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:}

# ruby test_fail2.rb -> Segmentation Fault
# irb test_fail2.rb -> Segmentation Fault

==== test_fail3.rb

:   require 'Zip'
:   z = Zip::ZipFile.new "test.zip"
:
:   ["extconf.rb","zzzzzz","extconf.rb"].each { |e|
:
:   begin
:       entry = z.entry e
:       print entry.inspect, "\n"
:   rescue RuntimeError => err
:       print "Caught Exception: #{err}\n"
:   end
:
:   }

# ruby test_fail3.rb -> Segmentation Fault
# irb test_fail3.rb -> Segmentation Fault



Sun, 31 Aug 2003 04:18:26 GMT  
 Strange segmentation fault problem with C++ extension

Quote:

> Having played around a but more it looks like the behaviour of the module
> when called within a begin/rescue block is a somewhat more complex that I
> had described earlier and depending on context I can get a segmentation
> fault in either ruby or IRB

Does it ever fail if you disable garbage collection?

Dave



Sun, 31 Aug 2003 04:50:58 GMT  
 Strange segmentation fault problem with C++ extension

Quote:

> Does it ever fail if you disable garbage collection?

> Dave

Dave,

Disabling GC doesnt seem to make a difference.

Paul



Sun, 31 Aug 2003 05:48:09 GMT  
 Strange segmentation fault problem with C++ extension

Quote:

> P>             zipLocalEntry = ZipLocalEntry_new ( ptr_entry ) ;

>  What is missing is the source of ZipLocalEntry_new, to see how you create
>  your object.

> Guy Decoux

For some reason my news account doesnt seem to like me posting attachments
(or at least they dont show up at my end) and I have therefore attached the
source code for the offending module below. If anyone would like me to email
as an attachment pse let me know.

Apologies to anyone who ends up getting this multiple times

========= Original Message =========

Guy,

I am attaching the source code for the module. To compile it you need to
install the zipios++ (zipios.sourceforge.com) and run extconf.rb
with --zipios-(include|lib) set appropriately (extconf.rb is a bit of a hack
in order to detect the c++ libs properly).

I have added some instrumentation to the ZipLocalEntry_new - the debug trace
with this added is below.

Thanks, Paul

=========== DEBUG TRACE ===========

# irb --prompt xmp

require 'Zip'
    ==>true

z = Zip::ZipFile.new "test.zip"

z.entries { |e| print e.path, "\n" }   # Get Zip Directory
    (zip.cpp:279) MSG: Entering Function #ZipLocalEntry_new
    (zip.cpp:280) PTR: ConstEntryPointer ->135928464
    (zip.cpp:284) PTR: zipLocalEntry ->135469952

    (zip.cpp:290) MSG: Leaving Function #ZipLocalEntry_new
extconf.rb
    (zip.cpp:279) MSG: Entering Function #ZipLocalEntry_new
    (zip.cpp:280) PTR: ConstEntryPointer ->135928468
    (zip.cpp:284) PTR: zipLocalEntry ->135470080

    (zip.cpp:290) MSG: Leaving Function #ZipLocalEntry_new
Makefile

z.entry "extconf.rb"                   # OK
    (zip.cpp:403) MSG: Entering Function #ZipFile_entry

    (zip.cpp:408) PTR: ZipFile ->135501760
    (zip.cpp:418) MSG: GetEntry OK
    (zip.cpp:420) PTR: ConstEntryPointer ->135871104
    (zip.cpp:279) MSG: Entering Function #ZipLocalEntry_new
    (zip.cpp:280) PTR: ConstEntryPointer ->135871104
    (zip.cpp:284) PTR: zipLocalEntry ->135489024

    (zip.cpp:290) MSG: Leaving Function #ZipLocalEntry_new

    (zip.cpp:423) MSG: Leaving Function #ZipFile_entry

z.entry "zzzzzzz"                      # Invalid Entry
    (zip.cpp:403) MSG: Entering Function #ZipFile_entry

    (zip.cpp:408) PTR: ZipFile ->135501760
    (zip.cpp:413) 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:403) MSG: Entering Function #ZipFile_entry

    (zip.cpp:408) PTR: ZipFile ->135501760
    (zip.cpp:418) MSG: GetEntry OK
    (zip.cpp:420) PTR: ConstEntryPointer ->136008400
    (zip.cpp:279) MSG: Entering Function #ZipLocalEntry_new
    (zip.cpp:280) PTR: ConstEntryPointer ->136008400
    (zip.cpp:284) PTR: zipLocalEntry ->135126848

    (zip.cpp:290) MSG: Leaving Function #ZipLocalEntry_new

    (zip.cpp:423) MSG: Leaving Function #ZipFile_entry
(irb):12: [BUG] Segmentation fault
ruby 1.6.3 (2001-03-07) [i386-netbsd1.5]
Abort (core dumped)

====== extconf.rb =====
require 'mkmf'

CPP.gsub! /g?cc/, "c++"
LINK.gsub! /g?cc/, "c++"

dir_config ( "zipios" ) ;

if ( have_header ( "zipios++/zipfile.h" ) and
     have_library ( "gcc", "__pure_virtual" ) and
     have_library ( "zipios", "FListScannerwrap" ) and
     have_library ( "z", "inflate" ) and
     have_library ( "stdc++", "cin" ) )

    $defs[-1].tr! ( "++", "" )

    create_makefile ( "Zip" )
end

====== zip.cpp =====//// zip.cpp//
// Ruby extension to use the Zipios++ Zip file reader library
// (http://zipios.sourceforge.com)
//
// Module
//
//      Zip - Module Namespace
//
// Classes
//
//      Zip::ZipFile - Zip File
//      Zip::ZipEntry - Zip File Entry
//
// Methods
//
// Zip::ZipFile
// ============
//
//      Zip::ZipFile#new (fileName, [fileOffset=0]) -> ZipFile
//
//          Constructor - open zip file
//
//      Zip::ZipFile#openEmbeddedZipFile (fileName) -> ZipFile
//
//          Constructor - open zIp file appended to another file
//
//          File must have Zip file offset encoded in last 4 bytes
//          in Zip file (little endian byte order) eg. using
//          'appendzip' program from zipios++ distribution
//
//      ZipFile#inspect -> String
//
//      ZipFile#name -> String
//
//          Return Zip file name
//
//      ZipFile#items -> Number
//
//          Returns number of items in ZipFile
//
//      ZipFile#entry -> ZipEntry List
//
//          Return ZipEntry list (contents) for ZipFile
//          In block context call block once for each entry
//
//      ZipFile#entries ( pathString ) -> ZipEntry
//
//          Return ZipEntry for given path
//          Raises RuntimeError is entry not found
//
//      ZipFile#getData ( ZipEntry | pathString ) -> String
//
//          Returns uncompressed data for ZipEntry or pathString
//          Raises RuntimeError is entry not found
//
// Zip::ZipEntry
// =============
//
// Note: There is no direct sconstructor for Zip::ZipEntry - must
// created through ZipFile#entry or ZipFile#entries
//
//      ZipEntry#inspect -> String
//
//      (The following ZipEntry methods are largely accessors for the
//      ZipEntry file attributes)
//
//      ZipEntry#comment -> String
//      ZipEntry#compressed_size -> Number
//      ZipEntry#crc -> Number (this doesnt look right??)
//      ZipEntry#size -> Number
//      ZipEntry#time -> Number (format not defined - see Zipios docs)
//      ZipEntry#isValid? -> Boolean
//      ZipEntry#isDirectory? -> Boolean
//      ZipEntry#path
//      ZipEntry#filename
//
// BUGS/TODO
//
//      - Fix ZipEntry#entry coredump
//      - Utility to create embedded Zipfiles
//      - Convert ZipEntry#time to Ruby date
//      - ZipStream support (code removed until I work out how to fix)
//      - Use Ruby IO object in ZipFile#new (may need complete rewrite)
//
//      On reflection it might have been easier to write simple C
//      extension supporting the Zip file structure and reuse the Ruby
//      Zlib module for decompression
//
// LICENSE
//
//      The zipios++ library is released under the GNU LGPL
//      (http://www.gnu.org/copyleft/lesser.html)
//
//      Ruby is releaed under a combined GPL/Artistic lisence
//      (http://www.ruby-lang.org/en/LICENSE.txt)
//
//      This code is freely distributable under whatever the combined
//      restrictions of the two above licenses might be
//

//
// $Id: zip.cpp,v 1.1.1.1 2001/03/13 17:43:52 paulc Exp $
//
// $Log: zip.cpp,v $
// Revision 1.1.1.1  2001/03/13 17:43:52  paulc
// Initial Import
//
//

extern "C" {
#include "ruby.h"

Quote:
}

#include "zipios++/zipfile.h"
#include "zipios++/zipinputstream.h"
#include "zipios++/ziphead.h"

//
// C++ object wrapper macros stolen from SWIG
//

#define VALUEFUNC(f) ((VALUE (*)(...))f)
#define VOIDFUNC(f) ((void (*)(...))f)

#define Wrap_Class(klass,mark,free,ptr) \
    ((ptr)?Data_Wrap_Struct(klass,VOIDFUNC(mark),VOIDFUNC(free),ptr):Qnil)

#define Get_Class(val,rtype,ctype,ptr) {\
    if (NIL_P(val)) ptr = NULL;\
    else {\
        if (!rb_obj_is_kind_of(val, rtype))\
            rb_raise(rb_eTypeError, "Wrong argument type");\
        Data_Get_Struct(val, ctype, ptr);\
        if (!ptr) rb_raise(rb_eRuntimeError, "Class already released");\
    }\

Quote:
}

#define Wrap_ZipFile(klass,ptr) \
    Wrap_Class(klass,0,free_ZipFile,ptr)
#define Get_ZipFile(val,ptr) \
    Get_Class(val,cZipFile,ZipFile,ptr)
#define Wrap_ZipLocalEntry(klass,ptr) \
    Wrap_Class(klass,0,free_ZipLocalEntry,ptr)
#define Get_ZipLocalEntry(val,ptr) \
    Get_Class(val,cZipLocalEntry,ZipLocalEntry,ptr)

//
// Debug macros - compile with -DDEBUG to enable
//

#define VALUE2STR(value) STR2CSTR(rb_funcall(value,rb_intern("to_s"),0))

#ifdef DEBUG
#define DEBUG_MSG(msg) printf ( "    (%s:%d) MSG: %s\n", \
                __FILE__, __LINE__, msg ) ;
#define DEBUG_NUM(msg,num) printf ( "    (%s:%d) NUM: %s ->%d\n", \
                __FILE__, __LINE__, msg, num ) ;
#define DEBUG_STR(msg,str) printf ( "    (%s:%d) NUM: %s ->%s\n", \
                __FILE__, __LINE__, msg, str) ;
#define DEBUG_PTR(msg,ptr) printf ( "    (%s:%d) PTR: %s ->%d\n", \
                __FILE__, __LINE__, msg,ptr ) ;
#define DEBUG_VALUE(msg,value) printf ( "    (%s:%d) VALUE: %s -> %s\n", \
                __FILE__, __LINE__, msg, \
                VALUE2STR(rb_funcall(value,rb_intern("inspect"),0)))
#define DEBUG_METHOD(msg,value,method) printf ( "    (%s:%d) METHOD: %s ->
%s\n", \
                __FILE__, __LINE__, msg, \
                VALUE2STR(rb_funcall(value,rb_intern(#method),0)))
#else
#define DEBUG_MSG(msg) ;
#define DEBUG_NUM(msg,num) ;
#define DEBUG_NUM(msg,str) ;
#define DEBUG_PTR(msg,ptr) ;
#define DEBUG_VALUE(msg,value) ;
#define DEBUG_METHOD(msg,value,method) ;
#endif

//
// C++ Namespace
//

using namespace zipios ;

//
// Function prototypes
//

static VALUE ZipLocalEntry_inspect ( VALUE self ) ;
static VALUE ZipLocalEntry_getProperties ( ...

read more »



Sun, 31 Aug 2003 06:00:00 GMT  
 Strange segmentation fault problem with C++ extension

# For some reason my news account doesnt seem to like me posting
# attachments (or at least they dont show up at my end) and I have
# therefore attached the source code for the offending module below.

FYI -- the 'some reason' is this: posting any sort of attachments (or
HTML or RTF text for that matter) to USENET Newsgroups (or mail lists
mirrored to them) is a violation of USENET Netiquette
(also widely spelled Netiquitte).

This is supposed to be a "plain old text" medium, apparently for
various reasons of maximal backwards compatibility, maximal range of
OS/application accessibility, and lowest common denominator archival
searchability.

Don't worry about *occasional* long posts, especially if the subject
line carries a courtesy "[Long]" warning for those stuck behind slow
modems.

Hmm. Looks like we're overdue for a posting of the Ruby Newsgroup FAQ
and Newsgroup Netiquette Reminder.

Conrad Schneiker
(This note is unofficial and subject to improvement without notice.)



Sun, 31 Aug 2003 07:37:29 GMT  
 Strange segmentation fault problem with C++ extension

In message "[ruby-talk:12565] Re:Strange segmentation fault problem with C++ extension  [stacktrace]"

|Matz,
|
|Thanbks for your response. I apologise for not providing the stacktrace
|(wasnt thinking) - here it is.

Thank you.  Normally I find a bug from this information, but this time
I couldn't.  ;-<

|Please let me know if there is any more information you need

Could you send me whole source of your extension, if possible?

                                                        matz.



Sun, 31 Aug 2003 12:42:09 GMT  
 
 [ 24 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Segmentation fault... but strange

2. Segmentation fault and other strange errors with extended Wish

3. While using Oratcl extension, calls to exit product a segmentation fault

4. Another Segmentation Fault problem

5. how to find segmentation fault problem with Sun f90

6. Memory problem Segmentation fault / exhaust

7. segmentation fault problem

8. dimensions and segmentation fault problem

9. Problem with Tcl_Alloc, Tcl_LinkVar, and segmentation faults

10. Segmentation Fault problem

11. visual works 3.1 image has segmentation fault on 2.4 kernel (red hat 8.0)

12. segmentation fault on gabage collect

 

 
Powered by phpBB® Forum Software