From: Jacob Repp Date: 2006-02-21T16:33:28+09:00 Subject: Re: Need help understanding exceptions handling from C extensions I caught the exception using rb_protect() but there is still a problem: rbaio.c(1279): ruby error: NoMethodError: ??? rbaio.c(1292): from tc_client.rb:125:in `process' rbaio.c(1292): from tc_client.rb:125:in `test_addr_lookup_name_async' The class name I can interpret okay but when I take $! and call the to_s method on it I get another exception because of the NULL issue. I don't yet know why that is the case. lasterr = rb_gv_get("$!"); // class and message klass = rb_class_path(CLASS_OF(lasterr)); //message = rb_obj_as_string(lasterr); DBG2("ruby error: %s: %s", RSTRING(klass)->ptr, "???");//RSTRING(message)->ptr); Uncommenting the conversion to string results in the NULL error. On 2/20/06, Jacob Repp wrote: > I'm working on the test cases for my AIO extension library on windows > and I have been running into this error consistently on one of my > tests: > > test_addr_lookup_name_async(ClientTest): > ArgumentError: NULL pointer given > tc_client.rb:129:in `to_s' > tc_client.rb:129:in `test_addr_lookup_name_async' > > The offending line is in the rescue block: > > begin > q = AIOQueue.new > a = AIOAddr.new(q) > c = Callback.new > n = 0 > > assert(a.is_attached?, "should be attached") > a.lookup("www.google.com", c, :lookup_complete) > > 5.times { n += q.process(100) } > > assert(c.lookups == 1, "didn't receive lookup callback") > assert(n == 1, "not enough contexts processed") > rescue Exception => ex > puts "caught #{ex}" > end > > The exception is raised from q.process which hooks directly to a C > functions and makes another function call to an internal API I > defined. In this code I have my async context handler: > > case CTX_ADDR_LOOKUP: > rb_funcall( > pctx->recvr, > pctx->symbid, > 1, > > UINT2NUM(((Address*)(pctx->pbase))->addr.sin_addr.s_addr)); > > I believe this is 'raising' an exception. I see in other extensions > the usage of rb_protect() etc. I am under the impression that setjmp, > longjmp is being used to simulate exceptions in ruby, of which I'm > unfortunately not an expert in the usage. > > I would like to be able to call out to ruby code without losing my > instruction pointer so that I may deliver the error to a registered > async error facility. > > If someone could smack me over the head with a clue-by-four right now > that would be most appreciated ;) > > Of course I will continue learning and experimenting but I thouht this > would be a good time to solicit the knowledge of ruby-talk. > >