Closed
Bug 1439470
Opened 7 years ago
Closed 7 years ago
Crash in RedBlackTree<T>::Remove at rb.h:520, rb.h:462
Categories
(Core :: Memory Allocator, enhancement)
Core
Memory Allocator
Tracking
()
RESOLVED
FIXED
mozilla60
Tracking | Status | |
---|---|---|
firefox60 | --- | fixed |
People
(Reporter: glandium, Assigned: glandium)
References
Details
Attachments
(3 files)
There are other classes of crashes in RedBlackTree<T>::Remove, which I'm sure existed before bug 1412722 (most of them are double-free of huge allocations), but there are at least two kinds that I could find that are related to something I spotted while translating the current rb.h code to rust:
https://crash-stats.mozilla.com/report/index/26ceeaa3-db9f-4641-a46b-dc68d0180220
https://crash-stats.mozilla.com/report/index/c59942ce-cede-4d8b-8e1a-b25b50180219
Those are null derefs caused by the absence of the sentinel.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Comment 4•7 years ago
|
||
(In reply to Mike Hommey [:glandium] from comment #0)
> There are other classes of crashes in RedBlackTree<T>::Remove, which I'm
> sure existed before bug 1412722 (most of them are double-free of huge
> allocations)
I failed to mention: those are bug 1405062.
> We additionally ensure that nothing in the calling code will be trying
> to change the color or left/right pointers on the sentinel, which is an
> extra safe net compared to the code before bug 1412722.
Another advantage of this change is that it should separate those crash signatures from those related to double-free, although I'm also going to file another bug to make those separate too.
Comment 5•7 years ago
|
||
mozreview-review |
Comment on attachment 8952276 [details]
Bug 1439470 - Turn TreeNode into a smart pointer-like type.
https://reviewboard.mozilla.org/r/221518/#review227314
Code analysis found 1 defect in this patch:
- 1 defect found by clang-tidy
You can run this analysis locally with:
- `./mach static-analysis check path/to/file.cpp` (C/C++)
If you see a problem in this automated review, please report it here: http://bit.ly/2y9N9Vx
::: memory/build/rb.h:194
(Diff revision 1)
> - Trait::GetTreeNode(this).SetColor(aColor);
> + Trait::GetTreeNode(mNode).SetColor(aColor);
> }
> +
> + T* Get() { return mNode; }
> +
> + operator bool() { return mNode; }
Error: Bad implicit conversion operator for 'treenode' [clang-tidy: mozilla-explicit-operator-bool]
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
![]() |
||
Comment 9•7 years ago
|
||
mozreview-review |
Comment on attachment 8952276 [details]
Bug 1439470 - Turn TreeNode into a smart pointer-like type.
https://reviewboard.mozilla.org/r/221518/#review227326
::: memory/build/rb.h:194
(Diff revision 2)
> - Trait::GetTreeNode(this).SetColor(aColor);
> + Trait::GetTreeNode(mNode).SetColor(aColor);
> }
> +
> + T* Get() { return mNode; }
> +
> + MOZ_IMPLICIT operator bool() { return mNode; }
`return !!mNode` is clearer?
Attachment #8952276 -
Flags: review?(n.nethercote) → review+
![]() |
||
Comment 10•7 years ago
|
||
mozreview-review |
Comment on attachment 8952277 [details]
Bug 1439470 - Turn TreeNode(nullptr) into a "virtual" sentinel.
https://reviewboard.mozilla.org/r/221520/#review227328
::: memory/build/rb.h:192
(Diff revision 2)
> }
>
> - NodeColor Color() { return Trait::GetTreeNode(mNode).Color(); }
> + NodeColor Color()
> + {
> + return mNode ? Trait::GetTreeNode(mNode).Color() : NodeColor::Black;
> + }
I don't see any comments in rb.h about sentinels. It feels like there should be some...
Attachment #8952277 -
Flags: review?(n.nethercote) → review+
![]() |
||
Comment 11•7 years ago
|
||
mozreview-review |
Comment on attachment 8952277 [details]
Bug 1439470 - Turn TreeNode(nullptr) into a "virtual" sentinel.
https://reviewboard.mozilla.org/r/221520/#review227332
::: memory/build/rb.h:167
(Diff revision 2)
> {
> mNode = aOther.mNode;
> return *this;
> }
>
> - TreeNode Left() { return TreeNode(Trait::GetTreeNode(mNode).Left()); }
> + TreeNode Left()
Comments about how Left() and Right() work would probably also be useful.
![]() |
||
Comment 12•7 years ago
|
||
mozreview-review |
Comment on attachment 8952278 [details]
Bug 1439470 - Remove some now unnecessary checks.
https://reviewboard.mozilla.org/r/221522/#review227330
::: commit-message-17af0:1
(Diff revision 2)
> +Bug 1439470 - Remove some not unnecessary checks. r?njn
Remove the "not"?
Attachment #8952278 -
Flags: review?(n.nethercote) → review+
Assignee | ||
Comment 13•7 years ago
|
||
(In reply to Nicholas Nethercote [:njn] from comment #12)
> Comment on attachment 8952278 [details]
> Bug 1439470 - Remove some not unnecessary checks.
>
> https://reviewboard.mozilla.org/r/221522/#review227330
>
> ::: commit-message-17af0:1
> (Diff revision 2)
> > +Bug 1439470 - Remove some not unnecessary checks. r?njn
>
> Remove the "not"?
Hah, it was meant to be spelled "now".
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Comment 17•7 years ago
|
||
Comment on attachment 8952277 [details]
Bug 1439470 - Turn TreeNode(nullptr) into a "virtual" sentinel.
Does this satisfy your comments?
Attachment #8952277 -
Flags: review+ → review?(n.nethercote)
![]() |
||
Comment 18•7 years ago
|
||
mozreview-review |
Comment on attachment 8952277 [details]
Bug 1439470 - Turn TreeNode(nullptr) into a "virtual" sentinel.
https://reviewboard.mozilla.org/r/221520/#review227342
Looks good, thank you.
Attachment #8952277 -
Flags: review?(n.nethercote) → review+
Comment 19•7 years ago
|
||
Pushed by mh@glandium.org:
https://hg.mozilla.org/integration/autoland/rev/f95559ae3134
Turn TreeNode into a smart pointer-like type. r=njn
https://hg.mozilla.org/integration/autoland/rev/cf9d00862149
Turn TreeNode(nullptr) into a "virtual" sentinel. r=njn
https://hg.mozilla.org/integration/autoland/rev/c43ee00c3e6b
Remove some now unnecessary checks. r=njn
Comment 20•7 years ago
|
||
Backed out for failing automation.py
Push that caused the failures: https://treeherder.mozilla.org/#/jobs?repo=autoland&revision=c43ee00c3e6b611b21f6a51db79f5f86df110e91
Failure log: https://treeherder.mozilla.org/logviewer.html#?job_id=163133604&repo=autoland&lineNumber=6924
Backout: https://hg.mozilla.org/integration/autoland/rev/be033090d62ad73cb15da9993f855c91c8bdc78c
Flags: needinfo?(mh+mozilla)
Assignee | ||
Comment 21•7 years ago
|
||
Thank you GCC for creating stupid code for constexpr constructors:
0000000000406170 <_GLOBAL__sub_I_Unified_cpp_memory_build0.cpp>:
406170: 55 push %rbp
406171: 48 c7 05 fc e4 22 00 movq $0x0,0x22e4fc(%rip) # 634678 <_ZL7gArenas+0x38>
406178: 00 00 00 00
40617c: 48 c7 05 f9 e4 22 00 movq $0x0,0x22e4f9(%rip) # 634680 <_ZL7gArenas+0x40>
406183: 00 00 00 00
406187: 48 89 e5 mov %rsp,%rbp
40618a: 5d pop %rbp
40618b: c3 retq
40618c: 0f 1f 40 00 nopl 0x0(%rax)
Best part? _ZL7gArenas is in .bss:
0000000000634640 l O .bss 0000000000000048 _ZL7gArenas
The funny part? The static initializer above runs *after* malloc_init_hard, so those movq's overwrite gArenas.mArenas.mRoot, which, at that time, contains mDefaultArena.
So when iterating the arenas in the atfork handler after a fork(), the default arena is not forcefully unlocked, and if the default arena lock happens to be held before the fork, the child process ends up dead-locked when something else tries to get the default arena lock.
I thought adding a constexpr (non-default) constructor on RedBlackTree might help, but it doesn't. Removing the constexpr constructor on TreeNode doesn't work either because of the other constructor that takes a T* that needs to exist, so I'm afraid the only workaround to GCC's stupidity here is to turn mRoot into a T*.
Flags: needinfo?(mh+mozilla)
Assignee | ||
Comment 22•7 years ago
|
||
Adding a constexpr constructor to RedBlackTree *and* ArenaCollection makes the static initializer go away.
Assignee | ||
Comment 23•7 years ago
|
||
Well, MSVC can also do funny things with constexpr:
https://bugs.chromium.org/p/chromium/issues/detail?id=660967
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Updated•7 years ago
|
Attachment #8952276 -
Flags: review+ → review?(n.nethercote)
![]() |
||
Comment 27•7 years ago
|
||
mozreview-review |
Comment on attachment 8952276 [details]
Bug 1439470 - Turn TreeNode into a smart pointer-like type.
https://reviewboard.mozilla.org/r/221518/#review228104
::: memory/build/rb.h:204
(Diff revisions 2 - 4)
> T* mNode;
> };
>
> private:
> - TreeNode mRoot;
> + // Ideally we'd use a TreeNode for mRoot, but we need RedBlackTree to stay
> + // a POD to avoid a static initializer for gArenas.
"a POD type"?
Attachment #8952276 -
Flags: review?(n.nethercote) → review+
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 31•7 years ago
|
||
Pushed by mh@glandium.org:
https://hg.mozilla.org/integration/autoland/rev/f56735818e28
Turn TreeNode into a smart pointer-like type. r=njn
https://hg.mozilla.org/integration/autoland/rev/31f9d7d3f703
Turn TreeNode(nullptr) into a "virtual" sentinel. r=njn
https://hg.mozilla.org/integration/autoland/rev/9665d7248cc5
Remove some now unnecessary checks. r=njn
Comment 32•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/f56735818e28
https://hg.mozilla.org/mozilla-central/rev/31f9d7d3f703
https://hg.mozilla.org/mozilla-central/rev/9665d7248cc5
Status: NEW → RESOLVED
Closed: 7 years ago
status-firefox60:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla60
You need to log in
before you can comment on or make changes to this bug.
Description
•