New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
camlidl: problem with GC (2) #2835
Comments
Comment author: administrator
I don't think it's a bug. The GC calls camlidl_finalize_interface() In other terms, if your C++ code still accesses the COM object after
I'm not in the office right now, and therefore cannot check in the COM
|
Comment author: administrator Xavier Leroy Xavier.Leroy@inria.fr writes:
Well, it just means that I did not understand some GC basics (now I hope I Caml DLL side: let _ = C++ side: caml object gets finalized inside method1() and method2() just crashes.
As you see I don't play with refcount myself.
I think now I know (finally :-)) where is the bug. [runtime/cfactory.cpp] Hope to hear from you soon, |
Comment author: administrator Dmitry Bely dbely@mail.ru writes:
Oh. Seems I was wrong again. I definitely should not bother you with my The problem is possibly why caml tries to GC an object that is still Hope to hear from you soon, |
Comment author: administrator
No problem. It seems like refcount handling is broken somewhere in Best wishes,
|
Comment author: administrator Xavier Leroy Xavier.Leroy@inria.fr writes:
I think no (although as usual I may be wrong :-). The bug is in the runtime value camlidl_com_combine(value vintf1, value vintf2) i1 = camlidl_unpack_interface(vintf1, NULL); value camlidl_pack_interface(void * intf, camlidl_ctx ctx) camlidl_com_combine() returns new interface value, but GC does not know
No problem. I've just modified your test example a bit: [---cut---]
|
Comment author: administrator I finally got time to look at the CamlIDL problem you mentioned.
You are very correct that the refcount must be incremented, otherwise I will fix this as suggested in your comment. Apart from this, I looked at the implementation of Com.combine more Thanks again for your solid testing of Camlidl.
|
Comment author: administrator Fixed by XL 2001-07-30 |
Original bug ID: 433
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: -for CamlIDL use https://github.com/xavierleroy/camlidl/issues
Bug description
Full_Name: Dmitry Bely
Version: camlidl current cvs
OS: Windows NT 4.0
Submission from: d207.p3.col.ru (195.210.132.207)
From my #2833:
Of course moving caml object in memory by GC is very correct (I was wrong), and
is traced via register_global_root(), but nonetheless the bug exists there. I've
managed to isolate it myself. comintf.c from camlidl's runtime contains he
following code:
[---cut---]
static void camlidl_finalize_interface(value intf)
{
interface IUnknown * i = (interface IUnknown *) Field(intf, 1);
i->lpVtbl->Release(i);
}
value camlidl_pack_interface(void * intf, camlidl_ctx ctx)
{
value res = alloc_final(2, camlidl_finalize_interface, 0, 1);
Field(res, 1) = (value) intf;
if (ctx != NULL && (ctx->flags & CAMLIDL_ADDREF)) {
struct IUnknown * i = (struct IUnknown *) intf;
i->lpVtbl->AddRef(i);
}
return res;
}
...
ULONG STDMETHODCALLTYPE camlidl_Release(struct camlidl_intf * this)
{
struct camlidl_component * comp = this->comp;
ULONG newrefcount = InterlockedDecrement(&(comp->refcount));
int i;
if (newrefcount == 0) {
for (i = 0; i < comp->numintfs; i++) {
struct camlidl_intf * intf = &(comp->intf[i]);
remove_global_root(&(intf->caml_object));
if (intf->typeinfo != NULL) {
struct IUnknown * i = (struct IUnknown *) intf->typeinfo;
i->lpVtbl->Release(i);
}
}
stat_free(comp);
InterlockedDecrement(&camlidl_num_components);
}
return newrefcount;
}
[---cut---]
The problem is that camlidl_finalize_interface() may be invoked when GC moves
object in memory, calling i->lpVtbl->Release(i) (in fact camlidl_Release()) and
decrementing reference counter. It becomes equal to zero and the memory,
occupied by the interface, is incorrectly reclaimed via stat_free(comp). That's
the bug.
I temporarily removed i->lpVtbl->Release(i) from camlidl_finalize_interface()
and the crash disappeared (memory leak is better than the crash :-)). Now I am
waiting for the correct fix from you :-) (BTW, why both
camlidl_pack_interface() and camlidl_unpack_interface() increment reference
counter via AddRef()? I cannot understand that ...)
The text was updated successfully, but these errors were encountered: