Open Bug 1236085 Opened 8 years ago Updated 1 year ago

Segfault in mozilla::HashBytes() when trying to embed SpiderMonkey

Categories

(Core :: MFBT, defect)

defect

Tracking

()

UNCONFIRMED

People

(Reporter: cal, Unassigned)

References

Details

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0
Build ID: 20151001175956

Steps to reproduce:

This issue is also described in the dev-tech-js-engine mailing list, subject "Segfault in JS_NewContext()"  I started out with working through the SM embedder's guide using the latest SM46 trunk source.  A call to JS_NewContext() in a simple test app would segfault deep in a stack when constructing the global function prototype for the self hosted stuff.

After debugging further, I was able to round it down to this simple program:

#include <js-confdefs.h>
#include <mozilla/HashFunctions.h>

int main(int argc, const char *argv[])
{
    int hash = mozilla::HashBytes("1234", 4);
    fprintf(stderr, "hash test: %d\n", hash);
    return 0;
}

Toolchain is:
* Ubuntu 14.04 Trusty
* Kernel 3.13.0
* gcc 4.8.4


Actual results:

The call to HashBytes() smashes the stack, and I end up with a backtrace that looks like this:

(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00000000004005ea in main (argc=1, argv=0x7fffffffd6c8) at js7.c:6

Note that the call to JS_NewContext() is the same thing, just with 20 extra frames on the stack.



Expected results:

If I comment out the inclusion of js-confdefs.h, it works.  I tried various different build options, including
* configuring SM directly with the js/src/configure script (both optimized and debug)
* configuring the whole mozilla mach build (both optimized and debug)

All permutations still result in the segfault.  

If I add my own test function at the bottom of HashFunctions.cpp and call it before HashBytes() then it does not segfault.  

I managed to trial-and-error determine the macro define in js-confdefs.h that causes the segfault:  *MOZ_GLUE_IN_PROGRAM*

If I remove that, it does not segfault.  Compiling my app with gcc -E, I see that the HashBytes() definition after preprocessing is different:

----  WITH MOZ_GLUE_IN_PROGRAM 1 defined ------
__attribute__ ((warn_unused_result)) extern __attribute__((weak)) __attribute__((visibility("default"))) uint32_t
HashBytes(const void* bytes, size_t aLength);
--------------------------------------------------

---- WITHOUT MOZ_GLUE_IN_PROGRAM defined ------
__attribute__ ((warn_unused_result)) extern __attribute__((visibility("default"))) uint32_t
HashBytes(const void* bytes, size_t aLength);
--------------------------------------------------

It seems that without the __attribute__((weak)) definition, the function does not segfault.
How are you linking this test program you're writing?

According to [1], MOZ_GLUE_IN_PROGRAM triggers weak imports, which IIUC mean that undefined symbols won't be detected until runtime. Are you sure you're properly linking against mozglue?

[1] http://mxr.mozilla.org/mozilla-central/source/memory/build/mozmemory.h#37
I've been messing around a lot with my compile options, but for the most part I'm either dynamically linking to libmozjs-46a1.so, or statically linking to libjs_static.a.  What library file contains HashBytes?  ... I'm looking through all of the .a files created, and I'm guessing mozglue/build/libmozglue.a?

What other static libraries should I be including in my app, and, is it possible to create a single shared library file that has everything I need?  

(As I look through the deps for js.cpp, is there an easy way in the build system to include all of the .o files into the libmozjs shared library, like Unified_cpp_memory_mozalloc0.o, jemalloc.o, mozmemory_wrap.o, etc)

Thanks!
I believe mozglue is the library that contains the stuff that needs to be statically linked in both gecko and spidermonkey.

Sean, are there instructions somewhere on how to link standalone spidermonkey?
Flags: needinfo?(sstangl)
Yes, you'll need to link against libmozglue as well. Use the linker options "--whole-archive -lmozglue --no-whole-archive".
Flags: needinfo?(sstangl)
Got the same issue in JS::InitSelfHostedCode(). The function pointer mozilla::HashBytes points to a 0x0. The following command works for me:

g++ -I dist/include -g jsapi_guide.cpp -Wl,--whole-archive mozglue/build/libmozglue.a -Wl,--no-whole-archive -L js/src -lmozjs-51a1 -pthread

I built mozjs from mozilla-central's default branch. Maybe this bug can be closed?
See Also: → 1317020
This should not be closed.  The needed archive is not available in (for instance) the mozjs-devel package installed on my Fedora 24 system, nor is it in the `.pc` file.

Yes, I know that it isn't needed at runtime, but it should be installed in the `-devel` packages.  I guess that is really a downstream packaging bug?
I'm the maintainer of unofficial Arch Linux user package js45. In that package I manually install libmozglue.a and patch js.pc: https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=js45, line 31 and 74

@demiobenour is right. It would be great if my patches can be upstreamed. Before that you may want to ask Fedora developers update their packages.
Summary: Segfault in mozilla::HashBytes() → Segfault in mozilla::HashBytes() when trying to embed SpiderMonkey
By the way, I have a question: on Mac mozglue is built as libmozglue.dylib. Why not build it as libmozglue.so on Linux? -Wl,--whole-archive and -Wl,--no-whole-archive would be a headache. For example I can't use it with ease in CMakeLists.txt.
See Also: → 1330472
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.