Closed
Bug 824321
Opened 12 years ago
Closed 12 years ago
"Assertion failure: !IsThingPoisoned(thing),"
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
RESOLVED
FIXED
mozilla20
Tracking | Status | |
---|---|---|
firefox17 | --- | unaffected |
firefox18 | --- | unaffected |
firefox19 | --- | unaffected |
firefox20 | --- | fixed |
firefox-esr10 | --- | unaffected |
firefox-esr17 | --- | unaffected |
b2g18 | --- | unaffected |
People
(Reporter: gkw, Assigned: jonco)
References
Details
(Keywords: assertion, regression, testcase, Whiteboard: [jsbugmon:update][fuzzer-lulz])
Attachments
(2 files)
4.59 KB,
text/plain
|
Details | |
8.37 KB,
patch
|
terrence
:
review+
|
Details | Diff | Splinter Review |
x = "\udada\udada"
asserts js debug shell on m-c changeset 84320dffec6e without any CLI arguments at Assertion failure: !IsThingPoisoned(thing), when the testcase is passed in as a CLI argument.
s-s because gc is on the stack.
autoBisect shows this is probably related to the following changeset:
The first bad revision is:
changeset: 116562:54696b3f852b
user: Jon Coppeard
date: Tue Dec 18 13:27:28 2012 +0000
summary: Bug 820186 - Various crashes/assertions with gczeal(10) and random recursion. r=billm
![]() |
Reporter | |
Comment 1•12 years ago
|
||
> s-s because gc is on the stack.
Also assuming sec-critical unless otherwise shown - please feel free to change if necessary.
Keywords: sec-critical
![]() |
Reporter | |
Comment 2•12 years ago
|
||
Jon, does the regressing changeset seem correct?
Flags: needinfo?(jcoppeard)
Comment 3•12 years ago
|
||
"\udada\udada"? Lulz. I will bet money that that assert's complaining that the string characters contain a free pattern, for a perfectly legitimate reason. Which would mean IsThingPoisoned is, um, impossible to write, for string characters. At least not with the current string/character/etc. memory layout.
Comment 4•12 years ago
|
||
Not s-s. It's just looking at the data pointed at by a JSString* (well, halfway through the JSString structure) and seeing the free memory pattern, because the jschars are stored inline. So it's just a DEBUG assert gone wrong. Maybe the best thing is to overload IsPoisonedThing<JSString*> and always return true when storage is inline?
Group: core-security
Comment 5•12 years ago
|
||
er, always return false, that is. :-)
I think the right thing to do is to change the assert so that it looks like this:
JS_ASSERT_IF(object-contains-free-pattern, object-is-not-in-the-free-list);
Jon, does that sound right to you? That will also allow us to remove the unpoisoning business during allocation.
Updated•12 years ago
|
Keywords: sec-critical
Comment 7•12 years ago
|
||
How would that help in this particular case? It's a totally valid live string that happens to contain the free pattern. So object-contains-free-pattern is true, and object-is-not-in-the-free-list is also true.
(In reply to Steve Fink [:sfink] from comment #7)
> How would that help in this particular case? It's a totally valid live
> string that happens to contain the free pattern. So
> object-contains-free-pattern is true, and object-is-not-in-the-free-list is
> also true.
Um, yeah, so it wouldn't assert then :-). Currently the assert is
JS_ASSERT(!(object-contains-free-pattern));
Assignee | ||
Updated•12 years ago
|
Assignee: general → jcoppeard
Assignee | ||
Comment 9•12 years ago
|
||
Fix as suggested, but it turns out we can't always check whether something is on the free list or not, so the assert is not as strong as I'd like.
Flags: needinfo?(jcoppeard)
Assignee | ||
Updated•12 years ago
|
Attachment #697070 -
Flags: review?(terrence)
Comment 10•12 years ago
|
||
Comment on attachment 697070 [details] [diff] [review]
Potential fix
Review of attachment 697070 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/src/gc/Heap.h
@@ +997,5 @@
> + FreeSpan firstSpan(aheader->getFirstFreeSpan());
> + uintptr_t addr = reinterpret_cast<uintptr_t>(thing);
> +
> + for (const FreeSpan *span = &firstSpan;;) {
> + /* If the thing comes fore the current span, it's not free. */
s/fore/before/
@@ +1004,5 @@
> +
> + /*
> + * If we find it inside the span, it's dead. We use here "<=" and not
> + * "<" even for the last span as we know that thing is inside the
> + * arena. Thus for the last span thing < span->end.
I think this needs a ',' after Thus.
::: js/src/jsgc.cpp
@@ +266,5 @@
> * We can be called from the background finalization thread when the free
> * list in the compartment can mutate at any moment. We cannot do any
> * checks in this case.
> */
> + if (IsBackgroundFinalized(getAllocKind()) && !compartment->rt->isHeapBusy())
Good find. I'm guess this isn't directly related, but no need for a separate bug.
::: js/src/jsgcinlines.h
@@ -486,5 @@
> */
>
> -template<typename T>
> -static inline void
> -UnpoisonThing(T *thing)
Nice to see this go.
Attachment #697070 -
Flags: review?(terrence) → review+
Assignee | ||
Comment 11•12 years ago
|
||
Comment 12•12 years ago
|
||
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla20
Updated•12 years ago
|
Comment 13•12 years ago
|
||
A testcase for this bug was automatically identified at js/src/jit-test/tests/gc/bug-824321.js.
Flags: in-testsuite+
Updated•12 years ago
|
Whiteboard: [jsbugmon:update] → [jsbugmon:update][fuzzer-lulz]
You need to log in
before you can comment on or make changes to this bug.
Description
•