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