finalizer calling guarantee

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

finalizer calling guarantee

vfoltz
Hi,

I have a very weird situation when finalizer for exposed object may not be called (sporadically). I was able to reproduce it in a test using 1000-iteration loop where JSRuntime/JSContext were created and released. It seemed like for the first 279 iterations everything was fine (finalizer was called on JSContext destruction) and then for 721 times finalizer was not called. The reproduce and these numbers were constant from run to run about ~7 times while I was trying to figure out what is going on. And then it ceased to reproduce - all 1000 times finalizers began to be called. I reverted the code to the original state and still it is not reproducing.

What can be done to guarantee finalizer calling? It is crucial for my application not only because of memory leaks but also because of cleanup logic placed in finalizers. I cannot trace exposed objects lifetime separately because they are created dynamically in JavaScript and there may be _a lot_ of them.
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

vfoltz
Yes, the behavior is not depending on the source code. I just run the same .exe again and got different results: 1000 finalizers calls (OK), 984 and 729.
Please advice!

On Friday, March 15, 2013 5:46:55 PM UTC-5, [hidden email] wrote:
> Hi,
>
>
>
> I have a very weird situation when finalizer for exposed object may not be called (sporadically). I was able to reproduce it in a test using 1000-iteration loop where JSRuntime/JSContext were created and released. It seemed like for the first 279 iterations everything was fine (finalizer was called on JSContext destruction) and then for 721 times finalizer was not called. The reproduce and these numbers were constant from run to run about ~7 times while I was trying to figure out what is going on. And then it ceased to reproduce - all 1000 times finalizers began to be called. I reverted the code to the original state and still it is not reproducing.
>
>
>
> What can be done to guarantee finalizer calling? It is crucial for my application not only because of memory leaks but also because of cleanup logic placed in finalizers. I cannot trace exposed objects lifetime separately because they are created dynamically in JavaScript and there may be _a lot_ of them.
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

Wes Garland
Try removing the global object root, call JS_GC, destroy the context,
then destroy the runtime.

What version of JSAPI are you working with?

Wes

On 18 March 2013 16:53,  <[hidden email]> wrote:

> Yes, the behavior is not depending on the source code. I just run the same .exe again and got different results: 1000 finalizers calls (OK), 984 and 729.
> Please advice!
>
> On Friday, March 15, 2013 5:46:55 PM UTC-5, [hidden email] wrote:
>> Hi,
>>
>>
>>
>> I have a very weird situation when finalizer for exposed object may not be called (sporadically). I was able to reproduce it in a test using 1000-iteration loop where JSRuntime/JSContext were created and released. It seemed like for the first 279 iterations everything was fine (finalizer was called on JSContext destruction) and then for 721 times finalizer was not called. The reproduce and these numbers were constant from run to run about ~7 times while I was trying to figure out what is going on. And then it ceased to reproduce - all 1000 times finalizers began to be called. I reverted the code to the original state and still it is not reproducing.
>>
>>
>>
>> What can be done to guarantee finalizer calling? It is crucial for my application not only because of memory leaks but also because of cleanup logic placed in finalizers. I cannot trace exposed objects lifetime separately because they are created dynamically in JavaScript and there may be _a lot_ of them.
> _______________________________________________
> dev-tech-js-engine mailing list
> [hidden email]
> https://lists.mozilla.org/listinfo/dev-tech-js-engine



--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

vfoltz
In reply to this post by vfoltz
Isn't it supposed to be done by JS_DestryContext? I will try this when I get reliable reproduce. For now the reproduce is very inconsistent - it may many times in row work fine and then many times fail.

I'm using (porting to) current release: http://hg.mozilla.org/releases/mozilla-release/
Not sure where to find corresponding JSAPI version.

P.S. I found that finalizer is not called when there is a rooted object (JS_AddNamedObjectRoot). But this is not my case. Still it would be nice to have some diagnostic (at least for debug version) for such situations.

On Monday, March 18, 2013 4:43:06 PM UTC-5, Wes Garland wrote:

> Try removing the global object root, call JS_GC, destroy the context,
>
> then destroy the runtime.
>
>
>
> What version of JSAPI are you working with?
>
>
>
> Wes
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

vfoltz
In reply to this post by vfoltz
BTW, could it be related to conservative nature of used GC? E.g. there is some garbage on the stack which happens to match existing JS objects so they are not GC'ed and finalizers are not called. This could explain the sporadic nature of observed behavior.
In my understanding on JS_ContextDestroy all JS objects must be finalized unconditionally without any checks for reachability. Am I wrong?
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

Wes Garland
I haven't done this with modern JSAPI, but I'm fairly certain when I
looked at this a couple of years ago that there were situations where
my finalizers were not being called if I just chose to destroy the
context, rather than pulling the root and running the collector in
advance. Remember that the cx hides a reference to the global which is
a root, I think in cx->glob, that you can set with
JS_SetGlobalObject()   (IIRC - it's been a long time).

It's also possible that the conservative collector is playing funny
games with you, but ISTR that the conservative marking is not done
during the GC that happens in JS_DestroyContext, so hopefully that
will save you.

At once point I was also putting my main JS code in a useless function
to try and slide the stack pointer around to make sure the
conservative collector was not interfering, but that is a bad plan as
you cannot easily guarantee that the function will not be optimized
away anyhow.  I also make sure that I don't keep any JS objects on the
top-level C stack.

If you find the precise solution to your problem, I would appreciate a
follow-up, as it is bound to be of concern to me in the future.

Wes

On 19 March 2013 10:08,  <[hidden email]> wrote:
> BTW, could it be related to conservative nature of used GC? E.g. there is some garbage on the stack which happens to match existing JS objects so they are not GC'ed and finalizers are not called. This could explain the sporadic nature of observed behavior.
> In my understanding on JS_ContextDestroy all JS objects must be finalized unconditionally without any checks for reachability. Am I wrong?
> _______________________________________________
> dev-tech-js-engine mailing list
> [hidden email]
> https://lists.mozilla.org/listinfo/dev-tech-js-engine



--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

Jeff Walden-2
In reply to this post by vfoltz
On 03/19/2013 06:56 AM, [hidden email] wrote:
> P.S. I found that finalizer is not called when there is a rooted object (JS_AddNamedObjectRoot). But this is not my case. Still it would be nice to have some diagnostic (at least for debug version) for such situations.

If it's not actually the case now -- I'm not sure -- there's a reasonable argument that this should be a JSAPI error.  I imagine we could assert in cases like this pretty easily.  There might be a concern for embeddings that weren't careful about removing all their roots prior to shutdown, tho, who might have relied on this behavior.  So it could be a semi-tricky thing to start asserting.

Jeff
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

vfoltz
In reply to this post by vfoltz
> If you find the precise solution to your problem, I would appreciate a
>
> follow-up, as it is bound to be of concern to me in the future.

OK! I found a very old bug (in my code) responsible for this sporadic behavior. So far test is passed now. Thank you anyway :)
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

Wes Garland
In reply to this post by Jeff Walden-2
On 19 March 2013 12:17, Jeff Walden <[hidden email]> wrote:
> On 03/19/2013 06:56 AM, [hidden email] wrote:
>> P.S. I found that finalizer is not called when there is a rooted object (JS_AddNamedObjectRoot). But this is not my case. Still it would be nice to have some diagnostic (at least for debug version) for such situations.
>
> If it's not actually the case now -- I'm not sure -- there's a reasonable argument that this should be a JSAPI error.  I imagine we could assert in cases like this pretty easily.  There might be a concern for embeddings that weren't careful about removing all their roots prior to shutdown, tho, who might have relied on this behavior.  So it could be a semi-tricky thing to start asserting.

Each new version of JSAPI requires embedding changes these days anyhow
-- I don't think preserving "wrong" functionality is a significant
concern any more.

And embedders should always be checking their rooting as part of the
debug process anyhow, IMO -- JS_DumpNamedRoots() is an excellent tool
for this.

Wes
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

Boris Zbarsky
In reply to this post by vfoltz
On 3/19/13 10:08 AM, [hidden email] wrote:
> In my understanding on JS_ContextDestroy all JS objects must be finalized unconditionally without any checks for reachability. Am I wrong?

You're wrong, luckily: this behavior would cause exploitable security
bugs on the web.

-Boris

P.S. The key is that objects are not tied to a particular JSContext, so
JSContext lifetimes have little bearing on object lifetimes per se.
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

vfoltz
> P.S. The key is that objects are not tied to a particular JSContext, so
>
> JSContext lifetimes have little bearing on object lifetimes per se.

Wow! How can I transfer JSObject from one JSContext to another JSContext then?
And could you please be more specific about security issues?
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

Anthony Catel-4
There is a talk about this here :

https://bugzilla.mozilla.org/show_bug.cgi?id=716981

Le 2013-03-19 18:00, [hidden email] a écrit :

>> P.S. The key is that objects are not tied to a particular JSContext,
>> so
>>
>> JSContext lifetimes have little bearing on object lifetimes per se.
>
> Wow! How can I transfer JSObject from one JSContext to another
> JSContext then?
> And could you please be more specific about security issues?
> _______________________________________________
> dev-tech-js-engine mailing list
> [hidden email]
> https://lists.mozilla.org/listinfo/dev-tech-js-engine

_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: finalizer calling guarantee

Boris Zbarsky
In reply to this post by vfoltz
On 3/19/13 1:00 PM, [hidden email] wrote:
>> P.S. The key is that objects are not tied to a particular JSContext, so
>>
>> JSContext lifetimes have little bearing on object lifetimes per se.
>
> Wow! How can I transfer JSObject from one JSContext to another JSContext then?

What do you mean?  JSObjects are just not tied to a particular JSContext
in any way.  I mean... you can't get to a JSContext from a typical
JSObject.  That's because they're unrelated at this point.

> And could you please be more specific about security issues?

If you finalize things that are reachable, that means that whatever can
reach them (e.g. web page script that happens to be holding on to them)
can then cause accesses to freed memory, no?

-Boris

_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine