rb_raise problem in C extension

B

bdezonia

I am using Ruby 1.8.6-26 from the One Click Installer on Windows. I
have a C extension that tries to calloc() memory. If the calloc()
fails I call rb_raise(rb_eNoMemError,"Cannot allocate data"). My
program is getting stuck in this code. Debugging (unfortunately via
print statements) I can see that rb_raise() is going to be called.
After that the exception is never caught by the outermost rescue loop.
The program just stops doing anything (0% cpu) except it keeps
updating a timer in another thread. Are there things I need to know
about rb_raise() and how to use it?
 
E

Eric Hodel

I am using Ruby 1.8.6-26 from the One Click Installer on Windows. I
have a C extension that tries to calloc() memory. If the calloc()
fails I call rb_raise(rb_eNoMemError,"Cannot allocate data"). My
program is getting stuck in this code. Debugging (unfortunately via
print statements) I can see that rb_raise() is going to be called.
After that the exception is never caught by the outermost rescue loop.
The program just stops doing anything (0% cpu) except it keeps
updating a timer in another thread. Are there things I need to know
about rb_raise() and how to use it?

If ruby is out of memory how could it allocate more memory to raise an
exception?

Ruby itself allocates a NoMemError at startup to ensure it can raise
one when it runs out of memory. You'll probably need to do the same.
See gc.c rb_memerror().
 
B

bdezonia

If ruby is out of memory how could it allocate more memory to raise an  
exception?

Ruby itself allocates a NoMemError at startup to ensure it can raise  
one when it runs out of memory.  You'll probably need to do the same.  
See gc.c rb_memerror().

There is plenty of memory available (4-6 gig free). But I'm asking
calloc() for a 1 gb chunk and it can't find one. Is there a different
exception I should throw in this case? Will the rb_raise() in my
nested C code percolate out to my handler in my nested ruby code? (As
a test for now I'm just changing it to an eException but would
appreciate any feedback you have)
 
E

Eric Hodel

There is plenty of memory available (4-6 gig free). But I'm asking
calloc() for a 1 gb chunk and it can't find one. Is there a different
exception I should throw in this case? Will the rb_raise() in my
nested C code percolate out to my handler in my nested ruby code? (As
a test for now I'm just changing it to an eException but would
appreciate any feedback you have)

In that case, rb_raise should do what you want, however you may need
to explicitly rescue it:

$ ruby
begin
begin
raise NoMemoryError
rescue
puts "caught with plain rescue"
end
rescue Exception # or NoMemoryError
puts "caught with rescue Exception"
end
^D
caught with rescue Exception


For this reason, you should use RuntimeError or StandardError
(especially for custom error classes) instead of Exception, since
Exception isn't caught by a plain rescue.
 
K

Ken Bloom

If ruby is out of memory how could it allocate more memory to raise an
exception?

Ruby itself allocates a NoMemError at startup to ensure it can raise one
when it runs out of memory. You'll probably need to do the same. See
gc.c rb_memerror().

Is rb_memerror() exposed for him to call? He could just call that, and it
would spare him all issues with preallocation.

--Ken
 
E

Eric Hodel

Is rb_memerror() exposed for him to call? He could just call that,
and it
would spare him all issues with preallocation.

yeah, looks like it's in intern.h.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top