Last Comment Bug 694594 - Crashes with gcc 4.4.3
: Crashes with gcc 4.4.3
Status: RESOLVED FIXED
: crash, reproducible
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: unspecified
: x86_64 Linux
: -- critical with 8 votes (vote)
: mozilla16
Assigned To: Dave Hylands [:dhylands]
:
: Jason Orendorff [:jorendorff]
Mentors:
: 723900 725619 (view as bug list)
Depends on:
Blocks: 648801
  Show dependency treegraph
 
Reported: 2011-10-14 10:04 PDT by Mihai Sucan [:msucan]
Modified: 2012-06-13 05:59 PDT (History)
29 users (show)
ryanvm: in‑testsuite-
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
gdb stacktrace 1 (376.79 KB, text/plain)
2011-10-14 10:07 PDT, Mihai Sucan [:msucan]
no flags Details
gdb stacktrace 2 (229.44 KB, text/plain)
2011-10-14 10:09 PDT, Mihai Sucan [:msucan]
no flags Details
js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy() assembly with gcc-4.4 (5.70 KB, text/plain)
2012-02-16 12:30 PST, Chris Coulson
no flags Details
js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy() assembly with gcc-4.6 (6.55 KB, text/plain)
2012-02-16 12:30 PST, Chris Coulson
no flags Details
workaround based on comment 15 (734 bytes, patch)
2012-02-23 23:53 PST, Martin Stránský
no flags Details | Diff | Splinter Review
Workaround which only affects DEBUG builds (939 bytes, patch)
2012-06-11 16:15 PDT, Dave Hylands [:dhylands]
luke: review+
Details | Diff | Splinter Review
Workaround which only affects DEBUG builds v2 (871 bytes, patch)
2012-06-11 23:27 PDT, Dave Hylands [:dhylands]
dhylands: review+
Details | Diff | Splinter Review

Description Mihai Sucan [:msucan] 2011-10-14 10:04:40 PDT
I get semi-random crashes while running the Firefox developer tools mochitests on my machine.

This started happening since I pulled https://tbpl.mozilla.org/?tree=Fx-Team&rev=9d697ecaf161 ... and it still happens, even with the latest fx-team code.

Tests from the Style Inspector, Source Editor and from the Web Console cause crashes, in opt and dbg builds.

I am not sure if the component I picked is correct, I just saw the crasher is related to js/Vector.h and jscntxt.h, etc.

Going to attach gdb stacktraces.
Comment 1 Mihai Sucan [:msucan] 2011-10-14 10:07:16 PDT
Created attachment 567125 [details]
gdb stacktrace 1

Generated debug output and stacktrace as suggested in:
https://wiki.ubuntu.com/MozillaTeam/Bugs

This is the result of running the mochitest-browser-chrome tests from browser/devtools (all our tests).
Comment 2 Mihai Sucan [:msucan] 2011-10-14 10:09:25 PDT
Created attachment 567127 [details]
gdb stacktrace 2

Another stacktrace.

I would really appreciate a fix for this crash ... it breaks daily work on my machine. Please let me know if further information is needed. Thank you!
Comment 3 Jason Orendorff [:jorendorff] 2011-10-14 12:53:08 PDT
Both stacks are assertion failures in Vector.

msucan says you can trigger this like so:

  - build with --enable-debug on Linux x86-64
  - start the browser
  - open the console (Ctrl+Shift+K)
  - type w

The console's auto-complete feature triggers the assertion.

gkw, could you please reproduce this and bisect if possible?
Comment 4 Mihai Sucan [:msucan] 2011-10-16 07:50:56 PDT
This crasher started since bug 648801 landed.

Peter, can you please look into this? I haven't seen anyone who can repro the crasher. I can't even repro the crasher with tinderbox builds. This happens only on my own local builds.

if I set pref("dom.new_bindings", false) I still get the crash.

I have Ubuntu 10.04 LTS (amd64), gcc 4.4.3 (from official repos), everything up-to-date. Please let me know if you need any additional technical info about my build setup.


Thank you!
Comment 5 Mihai Sucan [:msucan] 2011-10-16 12:44:31 PDT
Bisected into the patches pushed for bug 648801. The first changeset that causes crashes is 0b6fe35629ae:

https://hg.mozilla.org/mozilla-central/rev/0b6fe35629ae
Comment 6 Peter Van der Beken [:peterv] 2011-10-17 04:56:07 PDT
I can't reproduce this on Ubuntu 11.04 (tried running the tests and using autocomplete in the console).

(In reply to Mihai Sucan [:msucan] from comment #5)
> Bisected into the patches pushed for bug 648801. The first changeset that
> causes crashes is 0b6fe35629ae:
> 
> https://hg.mozilla.org/mozilla-central/rev/0b6fe35629ae

That'd be very surprising, that changeset adds code that isn't actually used (later patches cause it to be used).
Comment 7 Mihai Sucan [:msucan] 2011-10-17 05:17:52 PDT
(In reply to Peter Van der Beken [:peterv] from comment #6)
> I can't reproduce this on Ubuntu 11.04 (tried running the tests and using
> autocomplete in the console).

Even nightly builds I get from mozilla.org work fine. It's certainly a problem (only?) on my machine. Only my local builds crash...


> (In reply to Mihai Sucan [:msucan] from comment #5)
> > Bisected into the patches pushed for bug 648801. The first changeset that
> > causes crashes is 0b6fe35629ae:
> > 
> > https://hg.mozilla.org/mozilla-central/rev/0b6fe35629ae
> 
> That'd be very surprising, that changeset adds code that isn't actually used
> (later patches cause it to be used).

Heh, surprising indeed. Unfortunately, that's what I found yesterday...


Are you on IRC, by any chance? I can try things live, as you see fit.

Anything I can help with debugging this crasher? Are the gdb stack traces of any help?

Thank you!
Comment 8 Peter Van der Beken [:peterv] 2011-10-17 06:37:15 PDT
The gdb traces are in JS engine code that's unrelated to that changeset. Are you saying that without that changeset you can't reproduce at all and with it you can 100% of the time? If so, can you try removing just the change in qsgen.py from that changeset?
If that's the changeset that causes it this looks more like a compiler bug.
Comment 9 Mihai Sucan [:msucan] 2011-10-17 10:34:49 PDT
(In reply to Peter Van der Beken [:peterv] from comment #8)
> The gdb traces are in JS engine code that's unrelated to that changeset. Are
> you saying that without that changeset you can't reproduce at all and with
> it you can 100% of the time? If so, can you try removing just the change in
> qsgen.py from that changeset?
> If that's the changeset that causes it this looks more like a compiler bug.

If I take out the qsgen.py change I get no crash. I can always reproduce this.

Can you please try with Ubuntu 10.04 on your machine? Compile Firefox and run the tests. Please make sure the OS is up-to-date (gcc 4.4.3).

Thank you!
Comment 10 Mihai Sucan [:msucan] 2011-10-18 10:50:07 PDT
Downloaded the latest clang and llvm sources, built them, then built the latest Firefox from fx-team. No crashes.

It looks like, yes, we can blame gcc 4.4.3 having a bug.
Comment 11 Peter Van der Beken [:peterv] 2011-10-19 01:58:54 PDT
CC'ing blake, he might have the same OS/compiler combo.
Comment 12 Nigel Babu [:nigelb] 2011-12-05 19:15:33 PST
Hi, I have the same OS/compiler combo and started faced this crash from a few days ago (I was working with an older tree and then updated)
Comment 13 Jan Horak 2012-02-08 02:06:45 PST
*** Bug 723900 has been marked as a duplicate of this bug. ***
Comment 14 Chris Coulson 2012-02-14 11:44:51 PST
On a build with gcc 4.4.3 (with --disable-jemalloc --enable-valgrind), I see these quite consistently in valgrind after typing in the Web Console:

==1460== Invalid write of size 8
==1460==    at 0x8B3349E: js::CrossCompartmentWrapper::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (jscntxt.h:2220)
==1460==    by 0x8ADEBF4: js::Proxy::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (jsproxy.cpp:860)
==1460==    by 0x8AA4971: js::GetIterator(JSContext*, JSObject*, unsigned int, JS::Value*) (jsiter.cpp:655)
==1460==    by 0x8AA4D1C: js_ValueToIterator(JSContext*, unsigned int, JS::Value*) (jsiter.cpp:789)
==1460==    by 0x8A9282C: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:2465)
==1460==    by 0x8A8F33B: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jsinterp.cpp:647)
==1460==    by 0x8A5E244: js::CallOrConstructBoundFunction(JSContext*, unsigned int, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A8F1B6: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jscntxtinlines.h:297)
==1460==    by 0x8A8F8C5: js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A16B9B: JS_CallFunctionValue (jsapi.cpp:5199)
==1460==    by 0x851673F: nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) (XPCWrappedJSClass.cpp:1530)
==1460==    by 0x851140E: nsXPCWrappedJS::CallMethod(unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) (XPCWrappedJS.cpp:611)
==1460==  Address 0x1ead2338 is 0 bytes after a block of size 8 alloc'd
==1460==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==1460==    by 0x857D3D5: js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long) (Utility.h:166)
==1460==    by 0x8B335A2: js::CrossCompartmentWrapper::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (Vector.h:675)
==1460==    by 0x8ADEBF4: js::Proxy::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (jsproxy.cpp:860)
==1460==    by 0x8AA4971: js::GetIterator(JSContext*, JSObject*, unsigned int, JS::Value*) (jsiter.cpp:655)
==1460==    by 0x8AA4D1C: js_ValueToIterator(JSContext*, unsigned int, JS::Value*) (jsiter.cpp:789)
==1460==    by 0x8A9282C: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:2465)
==1460==    by 0x8A8F33B: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jsinterp.cpp:647)
==1460==    by 0x8A5E244: js::CallOrConstructBoundFunction(JSContext*, unsigned int, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A8F1B6: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jscntxtinlines.h:297)
==1460==    by 0x8A8F8C5: js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A16B9B: JS_CallFunctionValue (jsapi.cpp:5199)
==1460== 
==1460== Invalid write of size 8
==1460==    at 0x8B334B0: js::CrossCompartmentWrapper::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (jscntxt.h:2220)
==1460==    by 0x8ADEBF4: js::Proxy::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (jsproxy.cpp:860)
==1460==    by 0x8AA4971: js::GetIterator(JSContext*, JSObject*, unsigned int, JS::Value*) (jsiter.cpp:655)
==1460==    by 0x8AA4D1C: js_ValueToIterator(JSContext*, unsigned int, JS::Value*) (jsiter.cpp:789)
==1460==    by 0x8A9282C: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:2465)
==1460==    by 0x8A8F33B: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jsinterp.cpp:647)
==1460==    by 0x8A5E244: js::CallOrConstructBoundFunction(JSContext*, unsigned int, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A8F1B6: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jscntxtinlines.h:297)
==1460==    by 0x8A8F8C5: js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A16B9B: JS_CallFunctionValue (jsapi.cpp:5199)
==1460==    by 0x851673F: nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) (XPCWrappedJSClass.cpp:1530)
==1460==    by 0x851140E: nsXPCWrappedJS::CallMethod(unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) (XPCWrappedJS.cpp:611)
==1460==  Address 0x1ead28c0 is not stack'd, malloc'd or (recently) free'd
==1460== 
==1460== Invalid write of size 8
==1460==    at 0x8B334FC: js::CrossCompartmentWrapper::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (jswrapper.cpp:679)
==1460==    by 0x8ADEBF4: js::Proxy::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (jsproxy.cpp:860)
==1460==    by 0x8AA4971: js::GetIterator(JSContext*, JSObject*, unsigned int, JS::Value*) (jsiter.cpp:655)
==1460==    by 0x8AA4D1C: js_ValueToIterator(JSContext*, unsigned int, JS::Value*) (jsiter.cpp:789)
==1460==    by 0x8A9282C: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:2465)
==1460==    by 0x8A8F33B: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jsinterp.cpp:647)
==1460==    by 0x8A5E244: js::CallOrConstructBoundFunction(JSContext*, unsigned int, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A8F1B6: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jscntxtinlines.h:297)
==1460==    by 0x8A8F8C5: js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A16B9B: JS_CallFunctionValue (jsapi.cpp:5199)
==1460==    by 0x851673F: nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) (XPCWrappedJSClass.cpp:1530)
==1460==    by 0x851140E: nsXPCWrappedJS::CallMethod(unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) (XPCWrappedJS.cpp:611)
==1460==  Address 0x1ead2338 is 0 bytes after a block of size 8 alloc'd
==1460==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==1460==    by 0x857D3D5: js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long) (Utility.h:166)
==1460==    by 0x8B335A2: js::CrossCompartmentWrapper::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (Vector.h:675)
==1460==    by 0x8ADEBF4: js::Proxy::iterate(JSContext*, JSObject*, unsigned int, JS::Value*) (jsproxy.cpp:860)
==1460==    by 0x8AA4971: js::GetIterator(JSContext*, JSObject*, unsigned int, JS::Value*) (jsiter.cpp:655)
==1460==    by 0x8AA4D1C: js_ValueToIterator(JSContext*, unsigned int, JS::Value*) (jsiter.cpp:789)
==1460==    by 0x8A9282C: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:2465)
==1460==    by 0x8A8F33B: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jsinterp.cpp:647)
==1460==    by 0x8A5E244: js::CallOrConstructBoundFunction(JSContext*, unsigned int, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A8F1B6: js::InvokeKernel(JSContext*, js::CallArgs, js::MaybeConstruct) (jscntxtinlines.h:297)
==1460==    by 0x8A8F8C5: js::Invoke(JSContext*, JS::Value const&, JS::Value const&, unsigned int, JS::Value*, JS::Value*) (jsinterp.h:148)
==1460==    by 0x8A16B9B: JS_CallFunctionValue (jsapi.cpp:5199)

And this in a debug build, I get this before it crashes too:

Assertion failure: mLength + incr <= mCapacity, at ./../../dist/include/js/Vector.h:678
Comment 15 Chris Coulson 2012-02-14 14:34:46 PST
Uninlining js::Vector<T,N,AP>::calculateNewCapacity() makes the problem go away, but how come we've only started seeing this issue in Firefox 10? :(
Comment 16 Kai Engert (:kaie) 2012-02-15 06:00:39 PST
Would you be able to locally build a gcc-4.4.6, and rebuild Firefox with 4.4.6, to see if the bug has already been fixed on the gcc 4.4.x branch?
Comment 17 Chris Coulson 2012-02-15 11:22:25 PST
*** Bug 725619 has been marked as a duplicate of this bug. ***
Comment 18 Chris Coulson 2012-02-15 11:45:41 PST
Hello Kai,

Yes, the problem still occurs in gcc-4.4.6 too
Comment 19 Chris Coulson 2012-02-16 12:28:56 PST
I did some more debugging of this this morning, and here is a summary of what I found:

- js::Vector<long, 8ul, js::TempAllocPolicy>::calculateNewCapacity() doesn't actually appear to be inlined by the compiler in both the working / non-working cases.

- Using JS_NEVER_INLINE for js::Vector<T,N,AP>::calculateNewCapacity() makes the problem go away.

- In the non-working case with gcc-4.4, js::Vector<long, 8ul, js::TempAllocPolicy>::calculateNewCapacity() appears to be completely optimized for the append() case (ie, it completely ignores lengthInc, and just assumes this is always 1). This can be seen by looking at the generated code:

0000000000da3b9a <js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long)>:
  da3b9a:    41 54                    push   %r12
  da3b9c:    48 8d 47 20              lea    0x20(%rdi),%rax
  da3ba0:    55                       push   %rbp
  da3ba1:    53                       push   %rbx
  da3ba2:    48 89 fb                 mov    %rdi,%rbx
  da3ba5:    48 83 ec 10              sub    $0x10,%rsp
  da3ba9:    48 39 47 08              cmp    %rax,0x8(%rdi)

Up until here, %rdi contains our instance pointer, and %rsi contains "incr". 0x8(%rdi) is the pointer to "mBegin" and 0x20(%rdi) is "storage". The last instruction is usingInlineStorage().

  da3bad:    48 8b 77 10              mov    0x10(%rdi),%rsi

Y'ouch. This overwrites "incr" with "mLength", which then gets passed to calculateNewCapacity() here:

  da3bb1:    48 8d 54 24 08           lea    0x8(%rsp),%rdx
  da3bb6:    75 68                    jne    da3c20 <js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long)+0x86>
  da3bb8:    e8 85 ff ff ff           callq  da3b42 <T.2961>

%rdx now contains the address of where calculateNewCapacity() will store "newCap"

I'm not sure what this is doing, but it seems to pretty much boil down to "move 0x1 to (%rdx):

0000000000da3b42 <T.2961>:
  da3b42:    48 89 f0                 mov    %rsi,%rax
  da3b45:    48 83 ec 08              sub    $0x8,%rsp
  da3b49:    48 83 c0 01              add    $0x1,%rax
  da3b4d:    72 42                    jb     da3b91 <T.2961+0x4f>
  da3b4f:    48 b9 00 00 00 00 00     movabs $0xf000000000000000,%rcx
  da3b56:    00 00 f0
  da3b59:    48 85 c8                 test   %rcx,%rax
  da3b5c:    75 33                    jne    da3b91 <T.2961+0x4f>
  da3b5e:    48 83 f8 01              cmp    $0x1,%rax
  da3b62:    41 b8 01 00 00 00        mov    $0x1,%r8d
  da3b68:    76 13                    jbe    da3b7d <T.2961+0x3b>
  da3b6a:    48 0f bd f6              bsr    %rsi,%rsi
  da3b6e:    b9 3f 00 00 00           mov    $0x3f,%ecx
  da3b73:    83 f6 3f                 xor    $0x3f,%esi
  da3b76:    29 f1                    sub    %esi,%ecx
  da3b78:    ff c1                    inc    %ecx
  da3b7a:    49 d3 e0                 shl    %cl,%r8
  da3b7d:    4c 89 02                 mov    %r8,(%rdx)
  da3b80:    48 ba 00 00 00 00 00     movabs $0xf000000000000000,%rdx
  da3b87:    00 00 f0
  da3b8a:    b0 01                    mov    $0x1,%al
  da3b8c:    49 85 d0                 test   %rdx,%r8
  da3b8f:    74 07                    je     da3b98 <T.2961+0x56>
  da3b91:    e8 aa 01 87 ff           callq  613d40 <js::TempAllocPolicy::reportAllocOverflow() const@plt>
  da3b96:    31 c0                    xor    %eax,%eax
  da3b98:    5a                       pop    %rdx
  da3b99:    c3                       retq

Now, we call malloc with 0x1 * 8:

  da3bbd:    84 c0                    test   %al,%al
  da3bbf:    0f 84 a0 00 00 00        je     da3c65 <js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long)+0xcb>
  da3bc5:    48 8b 6c 24 08           mov    0x8(%rsp),%rbp
  da3bca:    48 c1 e5 03              shl    $0x3,%rbp
  da3bce:    48 89 ef                 mov    %rbp,%rdi
  da3bd1:    e8 aa 6f 87 ff           callq  61ab80 <malloc@plt>

And so, growStorageBy() appears to succeed, yet it has allocated a lot less than the caller thinks. mLength gets incremented by the value of "incr", and then MakeRangeGCSafe() (from js::AutoVectorRooter<long>::growBy()) tramples all over the end of the buffer.
Comment 20 Chris Coulson 2012-02-16 12:30:11 PST
Created attachment 597962 [details]
js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy() assembly with gcc-4.4
Comment 21 Chris Coulson 2012-02-16 12:30:51 PST
Created attachment 597963 [details]
js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy() assembly with gcc-4.6
Comment 22 Kai Engert (:kaie) 2012-02-17 08:12:48 PST
If you were able to come up with a minimal testcase, you could report it as a bug at http://gcc.gnu.org/bugzilla/enter_bug.cgi?product=gcc
Comment 23 Chris Coulson 2012-02-20 15:14:07 PST
I'm not convinced this is a compiler bug at all now. The implementation of js::Vector<long, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long) in jswrapper.o looks correct, and is actually perfectly ok. The issue is that another implementation of this is getting linked in to the final .so instead (from js/xpconnect/src/dombindings.o, which is also using js::AutoIdVector - see dombindings.cpp). This implementation is optimized differently because it only uses js::AutoIdVector::append(), which explains my finding in comment 19.

This also explains comment 5.

I imagine that it's just pure luck that this works with newer gcc versions...
Comment 24 Martin Stránský 2012-02-22 02:52:49 PST
Actually it may be a gcc bug after all, because the growStorageBy() from dombindings.cpp are hidden/local so they should not be linked to final .so:

$objdump -t dombindings.o | grep growStorageBy | c++filt
0000000000000000 l    d  .text._ZN2js6VectorI4jsidLm8ENS_15TempAllocPolicyEE13growStorageByEm	0000000000000000 .text._ZN2js6VectorI4jsidLm8ENS_15TempAllocPolicyEE13growStorageByEm

0000000000000000  w    F .text._ZN2js6VectorI4jsidLm8ENS_15TempAllocPolicyEE13growStorageByEm	00000000000001d1 .hidden js::Vector<jsid, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long)
Comment 25 Chris Coulson 2012-02-22 03:36:02 PST
Actually, that is showing that it is a weak symbol rather than a local symbol (which is what I see).
Comment 26 Martin Stránský 2012-02-22 03:54:21 PST
(In reply to Chris Coulson from comment #25)
> Actually, that is showing that it is a weak symbol rather than a local
> symbol (which is what I see).

Yeah, but the weak symbol is .hidden so it should be ignored by linker.
Comment 27 Chris Coulson 2012-02-22 04:07:56 PST
Not quite. hidden just means that the symbol isn't exported in the public API of libxul
Comment 28 Martin Stránský 2012-02-22 04:14:37 PST
Yeah. BTW. with gcc-4.4.x, the js::Vector<jsid, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long) is linked in libxul.so (RHEL6)

$ objdump -t libxul.so | grep _ZN2js6VectorI4jsidLm8ENS_15TempAllocPolicyEE13growStorageByEm

0000000001094d9a l     F .text	00000000000001d1
js::Vector<jsid, 8ul, js::TempAllocPolicy>::growStorageBy(unsigned long)

but with gcc 4.6.1 it's completely optimized away (Fedora15):

$ objdump -t /usr/lib64/xulrunner-2/libxul.so | grep _ZN2js6VectorI4jsidLm8ENS_15TempAllocPolicyEE13growStorageByEm
Comment 29 Martin Stránský 2012-02-23 23:53:42 PST
Created attachment 600326 [details] [diff] [review]
workaround based on comment 15
Comment 30 Martin Stránský 2012-02-29 04:00:18 PST
Confirmed as a gcc 4.4 bug:

http://gcc.gnu.org/PR52430
https://bugzilla.redhat.com/show_bug.cgi?id=784048#c9

the latter contains a workaround.
Comment 31 Mike Hommey [:glandium] 2012-02-29 04:03:01 PST
 (In reply to Martin Stránský from comment #30)
> Confirmed as a gcc 4.4 bug:
> 
> http://gcc.gnu.org/PR52430
> https://bugzilla.redhat.com/show_bug.cgi?id=784048#c9
> 
> the latter contains a workaround.

You are not authorized to access bug #784048. To see this bug, you must first log in to an account with the appropriate permissions.
Comment 32 mdinger.bugzilla@gmail.com 2012-03-15 18:31:07 PDT
Gcc states this is fixed for 4.4.7 and launchpad also states fixed because of gcc's fix but I still see the crash with firefox 11 in ubuntu.  Is anyone else still seeing this?  I expected it would be fixed with the gcc fix.

See bug 725619 for context regarding ubuntu and this crash.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52430
https://bugs.launchpad.net/ubuntu/+source/firefox/+bug/931637
Comment 33 Micah Gersten 2012-03-15 20:13:02 PDT
Which version of Firefox 11 on Ubuntu are you seeing this with?  We've already had a report of someone experiencing a crash that's now fixed.
Comment 34 mdinger.bugzilla@gmail.com 2012-03-17 16:56:48 PDT
Yes but apparently it is not fixed for everyone.  Oddly, I see the crash on all web pages ("www.google.com") except some built in pages such as "about:crashes".

I did successfully build a standard firefox build from hg tip locally and it did not crash.  I used gcc 4.4.4-14ubuntu5.1 which had the gcc fix included so I am not sure why the mozillateam build does not work properly.

I was going to check further but my computer overheats when compiling so I will leave it as is.

Firefox 11
Ubuntu 10.10 
mozillateam
firefox-stable
Comment 35 Dave Hylands [:dhylands] 2012-04-19 11:10:07 PDT
I'm seeing the same problem with the 4.4.3 ARM compiler. I only see the problem in debug builds. I'm seeing the problem in B2G, and its 100% reproducible.

The following JavaScript triggers the JS_ASSERT(mLength <= mReserved); in the Vector<T,N,AP>::reserve(size_t request) function.

<pre>
28:  function getSdkVersion() {
29:    Cu.import("resource://gre/modules/ctypes.jsm");
30:    try {
31:      let cutils = ctypes.open("libcutils.so");
32:      let cbuf = ctypes.char.array(4096)();
33:      let c_property_get = cutils.declare("property_get", ctypes.default_abi,
34:                                          ctypes.int,       // return value: length
35:                                          ctypes.char.ptr,  // key
36:                                          ctypes.char.ptr,  // value
37:                                          ctypes.char.ptr); // default
38:      let property_get = function (key, defaultValue) {
39:        if (defaultValue === undefined) {
40:          defaultValue = null;
41:        }
42:        c_property_get(key, cbuf, defaultValue);
43:        return cbuf.readString();
44:      }
45:      return parseInt(property_get("ro.build.version.sdk"));
46:    } catch(e) {
47:      // Eat it.  Hopefully we're on a non-Gonk system ...
48:      // 
49:      // XXX we should check that
50:      return 0;
51:    }
52:  }
</pre>

and the JSStack looks like:

<pre>
(gdb) call DumpJSStack()
0 getSdkVersion() ["jar:file:///system/b2g/omni.ja!/components/WifiWorker.js":37]
    this = undefined
1 anonymous() ["jar:file:///system/b2g/omni.ja!/components/WifiWorker.js":54]
    this = undefined
2 <TOP LEVEL> ["jar:file:///system/b2g/omni.ja!/components/WifiWorker.js":27]
    this = [object BackstagePass @ 0x41b11200 (native @ 0x40a62fc4)]
</pre>
Comment 36 Dave Hylands [:dhylands] 2012-06-11 16:15:11 PDT
Created attachment 632053 [details] [diff] [review]
Workaround which only affects DEBUG builds

This is a slightly different workaround which only affects DEBUG builds.
Comment 37 Luke Wagner [:luke] 2012-06-11 16:32:58 PDT
Comment on attachment 632053 [details] [diff] [review]
Workaround which only affects DEBUG builds

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

::: js/public/Vector.h
@@ +565,5 @@
>  STATIC_POSTCONDITION(!return || newCap >= curLength + lengthInc)
> +#ifdef DEBUG
> +// By making this method not inline for debug builds, it sidesteps
> +// the compiler generating incorrect code. See bug 694594.
> +JS_NEVER_INLINE bool

Surrounding comments use /* */.  Also, I think you could say, more succinctly:

/* ARM compiler bug workaround, see bug 694594. */
Comment 38 Dave Hylands [:dhylands] 2012-06-11 23:27:31 PDT
Created attachment 632144 [details] [diff] [review]
Workaround which only affects DEBUG builds v2

Redid comment. The problem actually affects both ARM and x86
Comment 39 Ryan VanderMeulen [:RyanVM] 2012-06-12 14:08:53 PDT
https://hg.mozilla.org/integration/mozilla-inbound/rev/b9cf42e0e76d
Comment 40 Ed Morley [:emorley] 2012-06-13 05:59:24 PDT
https://hg.mozilla.org/mozilla-central/rev/b9cf42e0e76d

Note You need to log in before you can comment on or make changes to this bug.