Hello,

In order to correctly bridge the Objective-C instance lifecycle, Monobjc
inserts itself in the dealloc message hierarchy (see
http://www.monobjc.net/index.php?page=bridging). This way, Monobjc
intercepts all dealloc messages, removes any existing managed wrapper, and
then pass the dealloc message to the original implementation. This trick is
called method swizzling (as used by Cocoa in Bindings); see
http://www.cocoadev.com/index.pl?MethodSwizzling for details.

It seems overkill that ALL dealloc messages are to be intercepted, but I
think this is the only way to synchronize native deallocation and managed
wrapper disposal.

As far as I know, there was no report of error for the NSObject hierarchy.
But for the NSProxy hierarchy, I am not 100% confident about the trick.

Can you attach a sample application that contains only the offending part so
I can reproduce and investigate ?

Regards, Laurent Etiemble.

2008/12/23 yoni shalom <silve...@gmail.com>

> I have an application that uses monobjc, embedded under a Cocoa app.
> I have witnessed various timing/threading issues (.net exceptions, SIGSEGV
> | EXC_BAD_ACCESS signals etc) with variouse stacks, for example :
>
> [NSRunloop run]    //beginning
> ...                         //some framework code
> ...
> [NSDistantObject dealloc]
> ??
> ??                       //.net JIT compiled function addresses - the .net
> wrappers for NSObject dealloc, or NSProxy dealloc
> ??
> [NSProxy isKindOfClass]
> ...                       //some native forwarding...
> ...
> [SIGSEGV handler / native exception handler]
>
> I'm attaching a real example at the end of this post.
> some facts :
>
> 1. The object for which the wrapper-dealloc is called on is NOT A .Net
> monobjc NSObject !  Are all objective-c native objects becoming "wrapped"
> just because we are using Monobjc ?
> 2. If the answer to the previous question is Yes (as it seems from my
> debugging session), I personally see it as a major flaw - bugs in monobjc
> shouldn't affect objects which the developer never intended to instanciate
> .Net managed wrappers for.
>
> 3. The code in the dealloc wrapper causes induces the use of Monitor.Enter,
> which in some occasions causes deadlocks (couldn't figure out why, didn't
> bother on debugging)
> 4. The code in the dealloc wrapper may run AFTER the native ptr is no
> longer valid for some reason, causing the native call to [self dealloc] to
> crash and burn with all kinds of nasty signals and shit.
>
> Removing the function "dealloc" in NSObject and NSProxy wrappers problems
> I've been trying to solve for two days.
> This, again, despite the fact that the objects causing the problem in the
> stack are not .net instances related to my managed embedded stack!, they are
> just regular, native, objective-c objects!
>
>
> A real example (crash report), in which u see WebKit (WebView embedded in
> my app) trying to release an object (note the command on line 10):
>
> Thread 0 Crashed:
> 0   libSystem.B.dylib              0x96f45b9e __kill + 10
> 1   libSystem.B.dylib              0x96fbcec2 raise + 26
> 2   libSystem.B.dylib              0x96fcc47f abort + 73
> 3   libmono.0.0.0.dylib            0x0078e999 mono_handle_native_sigsegv +
> 215 (mini-exceptions.c:1366)
> 4   libmono.0.0.0.dylib            0x00730ece sigsegv_signal_handler + 226
> (mini.c:13441)
> 5   libSystem.B.dylib              0x96f4409b _sigtramp + 43
> 6   ???                            0xffffffff 0 + 4294967295
> 7   com.apple.CoreFoundation       0x921156bd ___forwarding___ + 237
> 8   com.apple.CoreFoundation       0x92115a12 _CF_forwarding_prep_0 + 50
> 9   com.apple.Foundation           0x937485a0 -[NSProxy isKindOfClass:] +
> 160
> 10  ???                            0x0304d567 0 + 50648423    // ---->
> somewhere along the ?? functions is Monobjc, trying to execute the managed
> wrapper function NSProxy.Dealloc()!
> 11  ???                            0x16d00436 0 + 382731318
> 12  ???                            0x16d0021e 0 + 382730782
> 13  ???                            0x16d001ac 0 + 382730668
> 14  ???                            0x02ad0bfa 0 + 44895226
> 15  com.apple.Foundation           0x93708695 -[NSDistantObject dealloc] +
> 117
> 16  com.apple.CoreFoundation       0x9202c823 CFBagApplyFunction + 131
> 17  com.apple.Foundation           0x93748094 invalidateConnection + 596
> 18  com.apple.Foundation           0x93747815 -[NSConnection invalidate] +
> 613
> 19  com.apple.Foundation           0x93740238 +[NSConnection
> _portInvalidated:] + 712
> 20  com.apple.Foundation           0x936c91da _nsnote_callback + 106
> 21  com.apple.CoreFoundation       0x92077aba __CFXNotificationPost + 362
> 22  com.apple.CoreFoundation       0x92077d93
> _CFXNotificationPostNotification + 179
> 23  com.apple.Foundation           0x936c6440 -[NSNotificationCenter
> postNotificationName:object:userInfo:] + 128
> 24  com.apple.Foundation           0x93711c7a _NSPortDeathNotify + 106
> 25  com.apple.CoreFoundation       0x920723eb CFMachPortInvalidate + 219
> 26  com.apple.CoreFoundation       0x92072de6 __CFNotifyDeadMachPort + 294
> 27  com.apple.CoreFoundation       0x92072635 __CFMachPortPerform + 117
> 28  com.apple.CoreFoundation       0x92096908 CFRunLoopRunSpecific + 3896
> 29  com.apple.CoreFoundation       0x92096cf8 CFRunLoopRunInMode + 88
> 30  com.apple.Foundation           0x93750ef0 -[NSConcreteTask
> waitUntilExit] + 128
> 31  com.myapp.plugin              0x17207c79 -[plugin waitUntilExit] + 89
> (plugin.m:150)
> 32  com.myapp.plugin              0x17207a31 -[plugin stop] + 93
> (plugin.m:87)
> 33  com.myapp.plugin              0x1720700b -[plugin(scripting)
> stopPlayback] + 164 (plugin.m:47)
> 34  com.myapp.plugin              0x17206eac -[plugin(scripting) url:] +
> 43 (plugin.m:30)
> 35  com.apple.CoreFoundation       0x92115a7d __invoking___ + 29
> 36  com.apple.CoreFoundation       0x92115468 -[NSInvocation invoke] + 136
> 37  com.apple.JavaScriptCore       0x90b70cfd
> KJS::Bindings::ObjcInstance::invokeMethod(KJS::ExecState*,
> WTF::Vector<KJS::Bindings::Method*, 0ul> const&, KJS::List const&) + 397
> 38  com.apple.JavaScriptCore       0x90b66646
> KJS::RuntimeMethod::callAsFunction(KJS::ExecState*, KJS::JSObject*,
> KJS::List const&) + 278
> 39  com.apple.JavaScriptCore       0x90b2ddd6
> KJS::FunctionCallDotNode::evaluate(KJS::ExecState*) + 806
> 40  com.apple.JavaScriptCore       0x90b34329
> KJS::ExprStatementNode::execute(KJS::ExecState*) + 25
> 41  com.apple.JavaScriptCore       0x90b3b340
> KJS::BlockNode::execute(KJS::ExecState*) + 64
> 42  com.apple.JavaScriptCore       0x90b472fa
> KJS::IfElseNode::execute(KJS::ExecState*) + 106
> 43  com.apple.JavaScriptCore       0x90b56490
> KJS::CaseBlockNode::executeBlock(KJS::ExecState*, KJS::JSValue*) + 688
> 44  com.apple.JavaScriptCore       0x90b5618f
> KJS::SwitchNode::execute(KJS::ExecState*) + 79
> 45  com.apple.JavaScriptCore       0x90b34a71
> KJS::FunctionBodyNode::execute(KJS::ExecState*) + 481
> 46  com.apple.JavaScriptCore       0x90b34529
> KJS::FunctionImp::callAsFunction(KJS::ExecState*, KJS::JSObject*, KJS::List
> const&) + 265
> 47  com.apple.JavaScriptCore       0x90b2ddd6
> KJS::FunctionCallDotNode::evaluate(KJS::ExecState*) + 806
> 48  com.apple.JavaScriptCore       0x90b34329
> KJS::ExprStatementNode::execute(KJS::ExecState*) + 25
> 49  com.apple.JavaScriptCore       0x90b3b340
> KJS::BlockNode::execute(KJS::ExecState*) + 64
> 50  com.apple.JavaScriptCore       0x90b342ce
> KJS::IfNode::execute(KJS::ExecState*) + 78
> 51  com.apple.JavaScriptCore       0x90b34a71
> KJS::FunctionBodyNode::execute(KJS::ExecState*) + 481
> 52  com.apple.JavaScriptCore       0x90b34529
> KJS::FunctionImp::callAsFunction(KJS::ExecState*, KJS::JSObject*, KJS::List
> const&) + 265
> 53  com.apple.JavaScriptCore       0x90b2ddd6
> KJS::FunctionCallDotNode::evaluate(KJS::ExecState*) + 806
> 54  com.apple.JavaScriptCore       0x90b34329
> KJS::ExprStatementNode::execute(KJS::ExecState*) + 25
> 55  com.apple.JavaScriptCore       0x90b3b340
> KJS::BlockNode::execute(KJS::ExecState*) + 64
> 56  com.apple.JavaScriptCore       0x90b472fa
> KJS::IfElseNode::execute(KJS::ExecState*) + 106
> 57  com.apple.JavaScriptCore       0x90b34a71
> KJS::FunctionBodyNode::execute(KJS::ExecState*) + 481
> 58  com.apple.JavaScriptCore       0x90b34529
> KJS::FunctionImp::callAsFunction(KJS::ExecState*, KJS::JSObject*, KJS::List
> const&) + 265
> 59  com.apple.JavaScriptCore       0x90b2ddd6
> KJS::FunctionCallDotNode::evaluate(KJS::ExecState*) + 806
> 60  com.apple.JavaScriptCore       0x90b34329
> KJS::ExprStatementNode::execute(KJS::ExecState*) + 25
> 61  com.apple.JavaScriptCore       0x90b34a71
> KJS::FunctionBodyNode::execute(KJS::ExecState*) + 481
> 62  com.apple.JavaScriptCore       0x90b34529
> KJS::FunctionImp::callAsFunction(KJS::ExecState*, KJS::JSObject*, KJS::List
> const&) + 265
> 63  com.apple.JavaScriptCore       0x90b2ddd6
> KJS::FunctionCallDotNode::evaluate(KJS::ExecState*) + 806
> 64  com.apple.JavaScriptCore       0x90b34329
> KJS::ExprStatementNode::execute(KJS::ExecState*) + 25
> 65  com.apple.JavaScriptCore       0x90b34a71
> KJS::FunctionBodyNode::execute(KJS::ExecState*) + 481
> 66  com.apple.JavaScriptCore       0x90b34529
> KJS::FunctionImp::callAsFunction(KJS::ExecState*, KJS::JSObject*, KJS::List
> const&) + 265
> 67  com.apple.JavaScriptCore       0x90b788b7
> KJS::JSObject::call(KJS::ExecState*, KJS::JSObject*, KJS::List const&) + 135
> 68  com.apple.WebCore              0x928474ee
> WebCore::JSAbstractEventListener::handleEvent(WebCore::Event*, bool) + 1390
> 69  com.apple.WebCore              0x927a3846
> WebCore::EventTarget::handleLocalEvents(WebCore::EventTargetNode*,
> WebCore::Event*, bool) + 182
> 70  com.apple.WebCore              0x927a376f
> WebCore::EventTargetNode::handleLocalEvents(WebCore::Event*, bool) + 79
> 71  com.apple.WebCore              0x927a3206
> WebCore::EventTarget::dispatchGenericEvent(WebCore::EventTargetNode*,
> WTF::PassRefPtr<WebCore::Event>, int&, bool) + 454
> 72  com.apple.WebCore              0x927a2f4f
> WebCore::EventTargetNode::dispatchEvent(WTF::PassRefPtr<WebCore::Event>,
> int&, bool) + 255
> 73  com.apple.WebCore              0x92960c1d
> WebCore::EventTargetNode::dispatchMouseEvent(WebCore::AtomicString const&,
> int, int, int, int, int, int, bool, bool, bool, bool, bool, WebCore::Node*,
> WTF::PassRefPtr<WebCore::Event>) + 509
> 74  com.apple.WebCore              0x929609d5
> WebCore::EventTargetNode::dispatchMouseEvent(WebCore::PlatformMouseEvent
> const&, WebCore::AtomicString const&, int, WebCore::Node*) + 165
> 75  com.apple.WebCore              0x929604d5
> WebCore::EventHandler::dispatchMouseEvent(WebCore::AtomicString const&,
> WebCore::Node*, bool, int, WebCore::PlatformMouseEvent const&, bool) + 101
> 76  com.apple.WebCore              0x928d21c2
> WebCore::EventHandler::handleMouseReleaseEvent(WebCore::PlatformMouseEvent
> const&) + 722
> 77  com.apple.WebCore              0x928d1df9
> WebCore::EventHandler::mouseUp(NSEvent*) + 393
> 78  com.apple.WebKit               0x90a698bc -[WebHTMLView mouseUp:] +
> 220
> 79  com.apple.AppKit               0x95e59809 -[NSWindow sendEvent:] +
> 5539
> 80  com.apple.AppKit               0x95e26311 -[NSApplication sendEvent:]
> + 2941
> 81  com.apple.AppKit               0x95d83d0f -[NSApplication run] + 847
> 82  com.apple.AppKit               0x95d50f14 NSApplicationMain + 574
> 83  com.MyApp               0x00002ebb main + 133 (main.m:22)
> 84  com.MyApp                0x00002e0a start + 54
>

Reply via email to