[MacRuby] #604: EXC_BAD_ACCESS while opening stream
#604: EXC_BAD_ACCESS while opening stream -----------------------------------+---------------------------------------- Reporter: jakub.suder@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: -----------------------------------+---------------------------------------- I've recently started a new project using MacRuby 0.5, in which I have some classes in ObjC brought from another project. These classes are used for connecting to a web service, and they use the ASIHTTPRequest library to make HTTP requests. Now, as long as I'm only sending GET requests everything is fine, but once I send a POST request with non-empty body, I get a EXC_BAD_ACCESS error. The error appears when I call ASIHTTPRequest and it in turn calls CFReadStreamOpen, but in the end the backtrace leads to internal Ruby methods: {{{ #0 0x100080dba in rb_scan_args #1 0x1000aed31 in rb_file_open #2 0x1001b5316 in rb_vm_call_with_cache2 #3 0x1000c9652 in rb_class_new_instance #4 0x1000ac32d in rb_f_open #5 0x7fff851187ea in CFReadStreamOpen #6 0x7fff853b026e in HTTPNetConnection::prepareTransmission #7 0x7fff853af530 in NetConnection::enqueue #8 0x7fff853af409 in _CFNetConnectionEnqueue #9 0x7fff853af392 in HTTPNetStreamInfo::streamOpen #10 0x7fff853af354 in CFNetworkReadStream::httpStreamOpen #11 0x7fff85108036 in _CFStreamOpen #12 0x7fff851187c6 in CFReadStreamOpen #13 0x7fff85404421 in HTTPReadStream::startRequest #14 0x7fff85405814 in HTTPReadStream::streamOpen #15 0x7fff853af354 in CFNetworkReadStream::httpStreamOpen #16 0x7fff85108036 in _CFStreamOpen #17 0x7fff851187c6 in CFReadStreamOpen #18 0x10000a2e1 in -[ASIHTTPRequest startRequest] at ASIHTTPRequest.m:975 #19 0x1000080f8 in -[ASIHTTPRequest main] at ASIHTTPRequest.m:620 #20 0x100007ae0 in -[ASIHTTPRequest startAsynchronous] at ASIHTTPRequest.m:542 (...) }}} The same code works perfectly well if I replace the macruby_main line in main.c with one that runs the ObjC version of NSApplication. I've tried the nightly version of Macruby but no change... -- Ticket URL: <http://www.macruby.org/trac/ticket/604> MacRuby <http://macruby.org/>
#604: EXC_BAD_ACCESS while opening stream -----------------------------------+---------------------------------------- Reporter: jakub.suder@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: -----------------------------------+---------------------------------------- Comment(by lsansonetti@…): It's kind of hard to know what's happening here, I don't know why rb_f_open() is suddenly called. Would it be possible to reduce the problem to a sample project? -- Ticket URL: <http://www.macruby.org/trac/ticket/604#comment:3> MacRuby <http://macruby.org/>
#604: EXC_BAD_ACCESS while opening stream -----------------------------------+---------------------------------------- Reporter: jakub.suder@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: -----------------------------------+---------------------------------------- Comment(by martinlagardette@…): Laurent: the crash comes from the fact that rb_f_open receives argc == 4 with argv == 0x0. I don't know why rb_f_open is called here, since the code should be dealing with C / CF sockets. I guess this is the issue that should be looked upon, but as a temporary fix, a quick check of argc NULL-ness makes the whole thing work (see io.c.diff). -- Ticket URL: <http://www.macruby.org/trac/ticket/604#comment:4> MacRuby <http://macruby.org/>
#604: EXC_BAD_ACCESS while opening stream -----------------------------------+---------------------------------------- Reporter: jakub.suder@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: -----------------------------------+---------------------------------------- Comment(by lsansonetti@…): We need to find out what's going wrong exactly. I suspect io.c overwrites a Foundation "open" method which is then called using the wrong ABI. -- Ticket URL: <http://www.macruby.org/trac/ticket/604#comment:5> MacRuby <http://macruby.org/>
#604: EXC_BAD_ACCESS while opening stream -----------------------------------+---------------------------------------- Reporter: jakub.suder@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: -----------------------------------+---------------------------------------- Comment(by jakub.suder@…): I've tried the "if NULL" fix, but all it does is makes my request fail instead of crashing the program, so it's not really a solution... I think you're right that Ruby must be overriding something that it shouldn't override. The previous function on the stack is CFReadStreamOpen and I found some sources here http://www.opensource.apple.com/source/CF/CF-550/CFStream.c from which it looks like the CFReadStreamOpen function should just call "open" method on the provided stream object, but instead it magically appears in the Ruby's Kernel::open method (if I understand correctly what rb_f_open means)... I tried to figure out if I can reroute the call to the proper place from rb_f_open, but I just don't know the code well enough. Looks like the argc is 4, argv is NULL, SEL is a "open" string, but I have no idea what I can do with that. For now I'll try to work around this by using pure NSURLConnection or even some non-Cocoa Ruby code, but please take a look at this. -- Ticket URL: <http://www.macruby.org/trac/ticket/604#comment:6> MacRuby <http://macruby.org/>
#604: EXC_BAD_ACCESS while opening stream -----------------------------------+---------------------------------------- Reporter: jakub.suder@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: -----------------------------------+---------------------------------------- Comment(by martinlagardette@…): I just looked closely: the problem is that our `io.c` does the following: {{{ #!c rb_objc_define_module_function(rb_mKernel, "open", rb_f_open, -1); }}} It defines the "open" method over `rb_mKernel`, which is the super class of every object, even NSObject! This is to allow code like: {{{ #!ruby open("testfile") do |f| print f.gets end }}} This avoids the need to use `IO.open`. But this means that we supersede the original "open" from Obj-C, which is why our function gets called. I'm not sure yet what action should be taken. I'll discuss that with Laurent. -- Ticket URL: <http://www.macruby.org/trac/ticket/604#comment:7> MacRuby <http://macruby.org/>
#604: EXC_BAD_ACCESS while opening stream -----------------------------------+---------------------------------------- Reporter: jakub.suder@… | Owner: lsansonetti@… Type: defect | Status: closed Priority: critical | Milestone: MacRuby 0.6 Component: MacRuby | Resolution: invalid Keywords: | -----------------------------------+---------------------------------------- Changes (by martinlagardette@…): * status: new => closed * resolution: => invalid * milestone: => MacRuby 0.6 Comment: OK, we found the culprit. The problem is that `ASIHTTPRequest` defines `ASIInputStream`, which inherits from `NSObject` (and not `NSInputStream` because it's a little bit complicated). To overcome this limitation and simulate inheriting `NSInputStream`, `ASIInputStream` forwards all unknown invocations to its internal `NSInputStream`. However, since MacRuby defines `#open` on `Kernel` (included by `Object`), when `-open` is sent to `ASIInputStream`, the Obj-C runtime considers the object knows how to respond to this message, which is why instead of asking the object if a message forwarding is needed, it just sends it `-open` (aka our `rb_f_open`). The fix is very easy, and I am going to mail the author of ASIHTTPRequest just in case. Open `ASIInputStream.m`, and add the following between the implementations of `-read:maxLength:` and `methodSignatureForSelector:`: {{{ - (void)open { [stream open]; } }}} -- Ticket URL: <http://www.macruby.org/trac/ticket/604#comment:8> MacRuby <http://macruby.org/>
#604: EXC_BAD_ACCESS while opening stream -----------------------------------+---------------------------------------- Reporter: jakub.suder@… | Owner: lsansonetti@… Type: defect | Status: closed Priority: critical | Milestone: MacRuby 0.6 Component: MacRuby | Resolution: invalid Keywords: | -----------------------------------+---------------------------------------- Comment(by jakub.suder@…): Thanks! -- Ticket URL: <http://www.macruby.org/trac/ticket/604#comment:9> MacRuby <http://macruby.org/>
participants (1)
-
MacRuby