-
Notifications
You must be signed in to change notification settings - Fork 42
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
node-gtk leaks boxed object created through <Type>.new*() (as opposed to new <Type>()) #302
Comments
Got it. I've been swamped by work at my new job so I'm unfortunately out of time to look into this more in details or to debug this. Did you progress any further here? Anything I can do to help that isn't too much involved? |
I've made some initial implementation in my repo: I've made Interesting note is that it seems like Gjs always make a copy of the return value and then free the interim copy afterwards. I guess it works, but seems a bit wasteful. |
Any updates since your last comment? If we can avoid copies on return it would be better. I have a bit more time to take a look these days. |
No code update from the last time. For the return value's copy, I forgot to mention that it's copied only when the return value's transfer is not let p: Gst.Promise = an_operation();
// https://gstreamer.freedesktop.org/documentation/gstreamer/gstpromise.html?gi-language=c#gst_promise_get_reply
// Returns ( [transfer: none][nullable]) – The reply set on promise
let s: Gst.Structure = p.getReply();
p = null; global.gc(); // s is gone with the GstPromise.
s.isEqual(s); // Use-after-free! Unless we can find a way to detect this kind of thing and neuter the Also, maybe I should rename the type to |
GObjects memory management is supposed to be fully handled by refcounting plus V8 GC's weakref callbacks (aka deallocation callbacks), so it shouldn't require it. |
Well, in this case it's a boxed object (I have to put it the title...) |
I'm not sure if this is the best way to reproduce/detect it, but please bear with me.
libgstreamer1.0-0-dbg
).valgrind --vgdb=yes node --expose-gc
.gdb
. Then, connect to valgrind using:gst_buffer_new()
this way, so that the return value gets print automatically:Unfortunately, we cannot set it to also automatically continue after finishing. So we have to do it manually.
7. On terminal 1, run the following code:
While running this, GDB should break 2 times, with a line for each value returned. Take note of these addresses.
8. After
global.gc()
finishes, press Ctrl+C on terminal 2 to bring up the prompt. Then, run:There will be a long output, but the most important part is the first line. It should be
Address <address 1> is 0 bytes inside a block of size 280 free'd
, which indicate that this address is freed.9. Do the same with address 2 (except Ctrl+C). Now, the first line will change to
Address <address 2> is 0 bytes inside a block of size 280 alloc'd
. This means the address is not freed.10. Just in case something else is actually holding to the second GstBuffer, run:
The only output should be
Searching for pointers to <address 2>
. This means nothing can refer to it now; this GstBuffer is now leaked.GstBuffer
is aGstMiniObject
, which in itself is a boxed type. I've looked intoBoxedConstructor()
insideboxed.cc
; it seems to only either make a copy to itself or assume that the memory is managed elsewhere. The condition (mustCopy
) differs in different code paths that lead to it, which I'm unable to follow. So, I'm not sure where to start.The text was updated successfully, but these errors were encountered: