Hi Ben,
It's a super bad idea to copy an ExternalAddress.
It's common knowledge in C++ copy operator & copy constructors...

But it's not obvious to me that you'll have double freeing (unless you explicitely free the pointer by yourself).
If you use gcallocate: then only the original is registered for magical auto-deallocation at garbage collection...

What you will have is more somthing like dangling pointer: continue to use pointer xa2->a1 when a1 was already freed.

FFI is great, it introduces the problem of C in Smalltalk, augmented with the problems of wrapping C in Smalltalk.

2017-11-06 4:23 GMT+01:00 Ben Coman <btc@openinworld.com>:
My current employment work hours and roster have severely curtailed the time I have hacking Pharo, so I've not dug enough to be sure of my observations a few months ago, and this is from memory, but I was starting to develop a suspicion about the uniqueness of ExternalAddress(s).

A while ago, in order to fix some stability issues on Windows, a guard was added somewhere that slowed down some operations.�� Looking into this and experimenting with removing the guard I seem to remember VM crashes due to a double-free() of an address, due to there being two ExternalAddresses holding the same external address.����

My intuition is that that somewhere an ExternalAddress(a1) pointing at a particular external resource address "xa1" was being copied, so we end up with ExternalAddress(a2) also pointing at "xa1", with��and object b1 holding a1 and object b2 holding a2.�� During finalization of b1, ExternalAddress a1 free()d xa1, and a1 was flagged to avoid double-free()ing.�� But that didn't help when b2 was finalized, since a2 had no indication that xa1 had been free()d.��

That is...
b1-->a1-->xa1
b2 := b1 copy.
b2-->a2-->xa1
b1 finalize a1 --> free(xa1)
b2 finalize a2 --> free(xa1) --> General Protection Fault

It was hard to follow this through and I didn't succeed in tracking down where such a copy might have been made, but the idea simmering in my mind since then is to propose that...��

�� �� ExternalAddresses be unique in the image and behave like Symbols,��
�� �� such that trying to copy one returns the identical object.����

The idea being that when b2 is finalized, a1 would notice that xa1 had already been free()d and raise a Smalltalk exception rather than a general protection fault.
b1-->a1-->xa1
b2 := b1 copy.
b2-->a1-->xa1
�� �� �� �� ��^^
b1 finalize a1 --> free(xa1)
b2 finalize a1 --> Smalltalk exception


I write now in response to Stef since I vaguely remember it being Freetype related.�� But I also remember the issue being FFI related and Freetype is a plugin not FFI.�� So I'm not sure my memory is clear and perhaps I have the "wrong end of the stick" but anyway, rather than hold back longer because of that, perhaps this can stimulate some discussion and at least I learn something to clarify my understanding here.

cheers -ben��


On Sat, Oct 28, 2017 at 4:48 PM, Stephane Ducasse <stepharo.self@gmail.com> wrote:
>
> Hi all
>
> I'm and I guess many of you are fedup about the instability that the
> FreeType plugin��produces.
>
> So we need help because clement and esteban are fully booked.
>
> We have three options:
>
> - drop Freetype alltogether
> - rewrite the plugin
> - create a binding using raffaillac sketch
>
> Now we need help. Who is willing to help us?
> Should we try to set up a bounty?
>
> Stef