Add static analysis to find XPCOM classes with duplicate mRefCnt members.

RESOLVED FIXED in Firefox 42

Status

()

defect
RESOLVED FIXED
9 years ago
3 years ago

People

(Reporter: jst, Assigned: Nika)

Tracking

Trunk
mozilla42
x86_64
Linux
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(firefox42 fixed)

Details

Attachments

(2 attachments, 2 obsolete attachments)

Reporter

Description

9 years ago
We've found a few of these already, where we have a class that implements some interface and thus gets a reference count member. Then some other class inherits from that class, and some other interfaces, and forgets to use the _INHERITED macros and ends up with its own reference count member. This should be all safe as long as all accesses to the reference count goes through virtual functions etc, but it's a waste of space and a potential hazard in cases where code uses the reference count for other reasons.
I got bored & took a shot at implementing this static analysis. Right now this patch emits warning level messages for any classes which it finds with duplicate mRefCnt members due to inheritance. I'm currently running a build to get a list of classes which this analysis detects. I'll post it in this bug when I find it.
Attachment #8624935 - Flags: feedback?(ehsan)
These are the duplicate mRefCnt members which the analysis detected, in the form ClassName => SuperClassName:
nsSVGFilterReference     => nsSVGRenderingObserver
MultipartImage           => ImageWrapper
PromiseWorkerProxy       => PromiseNativeHandler
AllResolveHandler        => PromiseNativeHandler
ChildPledge<T>           => Pledge<T>
DataChannelChild         => nsHashPropertyBag
FetchHandler             => PromiseNativeHandler
CompareCache             => PromiseNativeHandler
RegisterDebuggerRunnable => nsRunnable
DelayedResolveOrReject   => nsRunnable

I've also attached the parts of the log which contained the warnings emitted by the analysis.
I haven't confirmed yet whether these warnings are correct, but based on my testing I imagine that they are.
Duplicate of this bug: 895502
You can look at the bugs blocking bug 895502 if you want some examples of what fixes to this might look like.
Assignee

Updated

4 years ago
Assignee: nobody → michael

Comment 5

4 years ago
Comment on attachment 8624942 [details]
The warnings from a run of the analysis

Do you think you can try to fix them?  :-)

Comment 6

4 years ago
Comment on attachment 8624935 [details] [diff] [review]
Add a static analysis to find XPCOM classes with duplicate mRefCnt members

Review of attachment 8624935 [details] [diff] [review]:
-----------------------------------------------------------------

This is really great!

I think we can land it as it (with the possible build issues fixed, of course!) unless if you know of a reason not to!

::: build/clang-plugin/clang-plugin.cpp
@@ +481,5 @@
>  
> +bool classHasRefCntMember(const CXXRecordDecl *D) {
> +  for (RecordDecl::field_iterator field = D->field_begin(), e = D->field_end();
> +       field != e; ++field) {
> +    if (field->getName() == "mRefCnt") {

It seems like mRefCnt is such a prevalent idiom that we can get away with this!  We can of course extend it in the future.

@@ +1038,5 @@
> +void DiagnosticsMatcher::NoDuplicateRefCntMemberChecker::run(
> +    const MatchFinder::MatchResult &Result) {
> +  DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
> +  unsigned warningID = Diag.getDiagnosticIDs()->getCustomDiagID(
> +      DiagnosticIDs::Warning, "Refcounted record %0 has multiple mRefCnt members");

Given that we warn with this, can you please see if we can build with this on builds with --enable-warnings-as-errors?  As in the try server builds for example?

Thanks!
Attachment #8624935 - Flags: feedback?(ehsan) → review+
(In reply to Ehsan Akhgari (not reviewing patches, not reading bugmail, needinfo? me!) from comment #6)
> Given that we warn with this, can you please see if we can build with this
> on builds with --enable-warnings-as-errors?  As in the try server builds for
> example?

My plan was to get the warnings fixed locally, and then promote the warning to an error before landing it in central. It was just a warning because that way it's easier to run over the entire mozilla codebase (I just ran the static analysis and grepped for the warning text). Probably should've made it an error before I attached the patch to the bug, but hey, what's done is done!

Fixing the mRefCnt uses may be a bit complicated. The worst example I've seen so far is PromiseNativeHandler. PromiseWorkerProxy overrides PromiseNativeHandler's default ref count mechanism to have threadsafe reference counting, and AllResolveHandler overrides it to have cycle collecting.

This is problematic, as cycle collection and threadsafe reference counting are, as far as I can tell, mutually exclusive, which means that we can't simply choose an implementation and make PromiseNativeHandler implement that one. I'm really not sure what to do with that :(
Flags: needinfo?(ehsan)
That sounds like the issue with nsArray. Basically, you need a base class that does not implement refcount (nsArrayBase for nsArray), then you have subclasses that implement each kind of refcounting you want. Then the other subclasses inherit from whichever refcounting subclass.
I did that in bug 1008420.
(In reply to Andrew McCreight [:mccr8] from comment #8)
> That sounds like the issue with nsArray. Basically, you need a base class
> that does not implement refcount (nsArrayBase for nsArray), then you have
> subclasses that implement each kind of refcounting you want. Then the other
> subclasses inherit from whichever refcounting subclass.

Ah, that makes sense :), I'll try to do that for PromiseNativeHandler tomorrow.
Flags: needinfo?(ehsan)
I've gotten the build to run on my local computer - but I probably butchered the reference counting :)

try: https://treeherder.mozilla.org/#/jobs?repo=try&revision=b7968eea9872
You should probably file bugs for each of the issues you are fixing.

Also, the argument that NS_INLINE_DECL_THREADSAFE_REFCOUNTING that seems to be only used for overriding refcounting looks like a bad idea. You should probably remove that... Are you detecting all of these as errors?
Well, the override thing is used in at least one place (NrSocketIpc) just to override an abstract method which I guess is okay, so it isn't all bad.
Fancier error messages & warning => error
Attachment #8624935 - Attachment is obsolete: true
Assignee

Updated

4 years ago
Depends on: 1181318
Assignee

Updated

4 years ago
Depends on: 1181319
Assignee

Updated

4 years ago
Depends on: 1181321
Assignee

Updated

4 years ago
Depends on: 1181323
Assignee

Updated

4 years ago
Depends on: 1181324
Depends on: 1185527

Comment 16

4 years ago
Is this ready to go?
I'm pretty sure it can't land right now due to bug 1185527.

Comment 18

4 years ago
Heh, yes, hopefully!
(In reply to Andrew McCreight [:mccr8] from comment #17)
> I'm pretty sure it can't land right now due to bug 1185527.

I've confirmed on a local build that this patch does in fact error due to that bug.

Comment 21

4 years ago
I landed this but it bounced: <https://treeherder.mozilla.org/#/jobs?repo=mozilla-inbound&revision=6d94504b602d>

Michael, do you mind taking a look when you get a chance?  Thanks!
Flags: needinfo?(michael)
This should get rid of the diagnostic which clang was emitting (I think). 

try: https://treeherder.mozilla.org/#/jobs?repo=try&revision=51331a93b1e4
Attachment #8630692 - Attachment is obsolete: true
Assignee

Updated

4 years ago
Flags: needinfo?(michael)

Comment 24

4 years ago
That didn't work!
(In reply to Ehsan Akhgari (not reviewing patches, not reading bugmail, needinfo? me!) from comment #24)
> That didn't work!

That's unfortunate. I'm out of the house right now but I'll try something else tonight.
Assignee

Updated

4 years ago
Depends on: 1189090

Comment 26

4 years ago
This, with the fix for bug 1189090 on top of latest inbound: <https://treeherder.mozilla.org/#/jobs?repo=try&revision=1a1400a7a2ed>
https://hg.mozilla.org/mozilla-central/rev/ea041b07a51b
Status: NEW → RESOLVED
Last Resolved: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla42
Depends on: 1244825
You need to log in before you can comment on or make changes to this bug.