Skip to content
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) #2836

Closed
vicuna opened this issue Jul 13, 2001 · 1 comment
Closed

camlidl: problem with GC (2) #2836

vicuna opened this issue Jul 13, 2001 · 1 comment

Comments

@vicuna
Copy link

vicuna commented Jul 13, 2001

Original bug ID: 434
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:

Unfortunately I cannot create small test example that demonstrates the bug.
But
I can suppose that it happens because GC moves in memory the caml object
representing the interface, which obviously is not acceptable. Can this be
true?
If yes, could you fix it?

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 ...)

@vicuna
Copy link
Author

vicuna commented Jul 30, 2001

Comment author: administrator

See #2835

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant