Hi David,
Thanks for pointing me in the right direction. Although I've almost lost
hope before finally succeeding. I tried various other approaches on the
way, but finally, what I did was very simple. It could be possible to
create a separate configuration (i.e. LINUX32) with some additional
tweaks to some other scripts (some scripts use the configuration name as
a logic token), but here I present a simpler variant with changes
applied to current LINUX configuration.
In order to cross-compile on 64 bit Ubuntu 14.04 for 32 bit Linux target
you need to patch some makefiles and build scripts:
http://cr.openjdk.java.net/~plevart/openjfx-8u-dev-rt/linux32on64tools/webrev.01/
Besides above changes to build scripts, the following environment
variables have to be defined (in $HOME/.profile):
JAVA_HOME=/path/to/32bit/jdk
PATH=$JAVA_HOME/bin:$PATH
PKG_CONFIG_LIBDIR=/usr/lib/i386-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
QMAKESPEC=linux-g++-32
export JAVA_HOME PATH PKG_CONFIG_LIBDIR QMAKESPEC
You need to install the i386 versions of runtime libraries needed to
execute the 32 bit JVM. I don't have the names at hand, but the list
could quickly be compiled by trying to run some Java GUI program using
32 bit JVM and then using apt-file on the missing library file to
find-out the name of the package. /Wash, rinse, repeat.../ until all
i386 JDK runtime dependencies are installed.
In addition, i386 versions of *-dev packages needed for compiling
openjfx have to be installed. This is the most tricky part to get right,
since installing them pulls-in some i386 runtime library dependencies
which conflict with x86_64 versions of libraries that might already be
installed on 64 bit system. "apt-get install" is clever on Ubuntu 14.04
and *REMOVES* the installed dependency sub-tree of x86_64 packages
before installing a conflicting i386 version of requested package. For
some of *-dev:i386 packages this means that even the tools needed for
building (gcc, binutils) get de-installed, but you can re-install them
later without conflicts (that's strange, but APT packaging seem to work
with at least 3 levels of dependency strengths). The most important part
is that the following packages:
gcc, gcc-4.8, g++, g++-48, binutils (with dependencies)
are kept at x86_64 architecture (that's the whole purpose of
cross-compilation). In addition, you also need to install the following
packages, to be able to produce 32bit binaries with 64bit tools:
gcc-multilib, gcc-4.8-multilib, g++-multilib, g++-4.8-multilib
I think that's all. With this changes I managed to produce 32 bit
libjfxwebkit.so with debugging symbols included (it's nearly 1.7 GiB
!!!). You need at least 10 GiB of free RAM when attempting such build
(the "ld" process grows to about 8 GiB of resident space when collecting
object files into a shared library - no wonder it can't be done with 32
bit "ld").
With 32bit debug build of openjfx I reproduced the crash mentioned in
(https://javafx-jira.kenai.com/browse/RT-33599) and got the following
backtrace from gdb:
...
...
#7 <signal handler called>
#8 0x6591cc7e in WTFCrash () at
../../../../src/main/native/Source/WTF/wtf/Assertions.cpp:345
#9 0x65950c3f in WTF::OSAllocator::reserveUncommitted (bytes=126976,
usage=WTF::OSAllocator::UnknownUsage, writable=true, executable=false,
includesGuardPages=false)
at ../../../../src/main/native/Source/WTF/wtf/OSAllocatorPosix.cpp:58
#10 0x65ac9033 in WTF::PageAllocationAligned::allocate (size=65536,
alignment=65536, usage=WTF::OSAllocator::UnknownUsage, writable=true)
at
../../../../src/main/native/Source/WTF/wtf/PageAllocationAligned.cpp:55
#11 0x65b5bff7 in JSC::DFG::Allocator<JSC::DFG::Node>::allocateSlow
(this=0x70df9f78) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGAllocator.h:204
#12 0x65b5a7c0 in JSC::DFG::Allocator<JSC::DFG::Node>::freeListAllocate
(this=0x70df9f78) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGAllocator.h:190
#13 0x65b58e4a in JSC::DFG::Allocator<JSC::DFG::Node>::allocate
(this=0x70df9f78) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGAllocator.h:109
#14 0x65b53d53 in operator new (size=84, allocator=...) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGNodeAllocator.h:45
#15 0x65b5bbb1 in JSC::DFG::Graph::addNode<JSC::DFG::NodeType,
JSC::CodeOrigin, JSC::DFG::OpInfo> (this=0x68a9effc, type=0,
_DFG_value1=@0x68a9de3c: JSC::DFG::Phi,
_DFG_value2=..., _DFG_value3=...) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGGraph.h:166
#16 0x65ce34a7 in JSC::DFG::CPSRethreadingPhase::addPhiSilently
(this=0x68a9dfd8, block=0x88d5970, codeOrigin=..., variable=0x89501b0)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:133
#17 0x65ce532c in
JSC::DFG::CPSRethreadingPhase::addPhi<(JSC::OperandKind)1>
(this=0x68a9dfd8, block=0x88d5970, codeOrigin=..., variable=0x89501b0,
index=5)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:141
#18 0x65ce5492 in
JSC::DFG::CPSRethreadingPhase::addPhi<(JSC::OperandKind)1>
(this=0x68a9dfd8, codeOrigin=..., variable=0x89501b0, index=5)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:149
#19 0x65ce4c43 in
JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor<(JSC::OperandKind)1>
(this=0x68a9dfd8, node=0x43f389d0, variable=0x89501b0, idx=5)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:213
#20 0x65ce3559 in JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocal
(this=0x68a9dfd8, node=0x43f389d0)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:225
#21 0x65ce373c in
JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock (this=0x68a9dfd8)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:361
#22 0x65ce3828 in
JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlocks (this=0x68a9dfd8)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:392
#23 0x65ce30f4 in JSC::DFG::CPSRethreadingPhase::run (this=0x68a9dfd8)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:52
#24 0x65ce5f5e in JSC::DFG::runAndLog<JSC::DFG::CPSRethreadingPhase>
(phase=...) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGPhase.h:75
#25 0x65ce50bd in JSC::DFG::runPhase<JSC::DFG::CPSRethreadingPhase>
(graph=...) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGPhase.h:85
#26 0x65ce2cfd in JSC::DFG::performCPSRethreading (graph=...) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp:493
#27 0x65b4e08a in JSC::DFG::compile
(compileMode=JSC::DFG::CompileFunction, exec=0x6343bf48,
codeBlock=0x43ce1308, jitCode=..., jitCodeWithArityCheck=0x5f52bb04,
osrEntryBytecodeIndex=0) at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGDriver.cpp:122
#28 0x65b4d983 in JSC::DFG::tryCompileFunction (exec=0x6343bf48,
codeBlock=0x43ce1308, jitCode=..., jitCodeWithArityCheck=...,
bytecodeIndex=0)
at
../../../../src/main/native/Source/JavaScriptCore/dfg/DFGDriver.cpp:182
#29 0x659ee25b in JSC::jitCompileFunctionIfAppropriate (exec=0x6343bf48,
codeBlock=..., jitCode=..., jitCodeWithArityCheck=...,
jitType=JSC::JITCode::DFGJIT, bytecodeIndex=0,
effort=JSC::JITCompilationCanFail) at
../../../../src/main/native/Source/JavaScriptCore/jit/JITDriver.h:95
#30 0x659ee4a4 in JSC::prepareFunctionForExecution (exec=0x6343bf48,
codeBlock=..., jitCode=..., jitCodeWithArityCheck=...,
jitType=JSC::JITCode::DFGJIT, bytecodeIndex=0,
kind=JSC::CodeForCall) at
../../../../src/main/native/Source/JavaScriptCore/runtime/ExecutionHarness.h:68
#31 0x659ebe91 in JSC::FunctionExecutable::compileForCallInternal
(this=0x5f52bad8, exec=0x6343bf48, scope=0x61d5dbf0,
jitType=JSC::JITCode::DFGJIT, bytecodeIndex=0)
at
../../../../src/main/native/Source/JavaScriptCore/runtime/Executable.cpp:539
#32 0x659eb659 in JSC::FunctionExecutable::compileOptimizedForCall
(this=0x5f52bad8, exec=0x6343bf48, scope=0x61d5dbf0, bytecodeIndex=0)
at
../../../../src/main/native/Source/JavaScriptCore/runtime/Executable.cpp:464
#33 0x65ae4398 in JSC::FunctionExecutable::compileOptimizedFor
(this=0x5f52bad8, exec=0x6343bf48, scope=0x61d5dbf0, bytecodeIndex=0,
kind=JSC::CodeForCall)
at
../../../../src/main/native/Source/JavaScriptCore/runtime/Executable.h:679
#34 0x65ae05cf in JSC::FunctionCodeBlock::compileOptimized
(this=0x4b40f818, exec=0x6343bf48, scope=0x61d5dbf0, bytecodeIndex=0)
at
../../../../src/main/native/Source/JavaScriptCore/bytecode/CodeBlock.cpp:2843
#35 0x659a406d in JSC::cti_optimize (args=0x68a9fcc0) at
../../../../src/main/native/Source/JavaScriptCore/jit/JITStubs.cpp:1964
---Type <return> to continue, or q <return> to quit---
#36 0x659a0ce1 in JSC::tryCacheGetByID (callFrame=0x0,
codeBlock=0xfffffffb, returnAddress=..., baseValue=...,
propertyName=..., slot=..., stubInfo=0x0)
at
../../../../src/main/native/Source/JavaScriptCore/jit/JITStubs.cpp:1068
#37 0x6343bad8 in ?? ()
#38 0x65994da7 in JSC::JITCode::execute (this=0x5f5237ac,
stack=0x70df9cf0, callFrame=0x6343a058, vm=0x70df3df8)
at ../../../../src/main/native/Source/JavaScriptCore/jit/JITCode.h:135
#39 0x659922bc in JSC::Interpreter::executeCall (this=0x70df9ce8,
callFrame=0x6253f994, function=0x5eedf618, callType=JSC::CallTypeJS,
callData=..., thisValue=..., args=...)
at
../../../../src/main/native/Source/JavaScriptCore/interpreter/Interpreter.cpp:1052
#40 0x659dc14c in JSC::call (exec=0x6253f994, functionObject=...,
callType=JSC::CallTypeJS, callData=..., thisValue=..., args=...)
at
../../../../src/main/native/Source/JavaScriptCore/runtime/CallData.cpp:40
#41 0x64a34c05 in WebCore::JSMainThreadExecState::call (exec=0x6253f994,
functionObject=..., callType=JSC::CallTypeJS, callData=...,
thisValue=..., args=...)
at
../../../../src/main/native/Source/WebCore/bindings/js/JSMainThreadExecState.h:56
#42 0x64a7e0cb in WebCore::ScheduledAction::executeFunctionInContext
(this=0x524f9388, globalObject=0x6253f838, thisValue=...,
context=0x62c58a50)
at
../../../../src/main/native/Source/WebCore/bindings/js/ScheduledAction.cpp:111
#43 0x64a7e312 in WebCore::ScheduledAction::execute (this=0x524f9388,
document=0x62c589f0) at
../../../../src/main/native/Source/WebCore/bindings/js/ScheduledAction.cpp:132
#44 0x64a7de62 in WebCore::ScheduledAction::execute (this=0x524f9388,
context=0x62c58a50) at
../../../../src/main/native/Source/WebCore/bindings/js/ScheduledAction.cpp:80
#45 0x651930df in WebCore::DOMTimer::fired (this=0x442283f8) at
../../../../src/main/native/Source/WebCore/page/DOMTimer.cpp:140
#46 0x65360730 in WebCore::ThreadTimers::sharedTimerFiredInternal
(this=0x70dd3a50) at
../../../../src/main/native/Source/WebCore/platform/ThreadTimers.cpp:129
#47 0x65360663 in WebCore::ThreadTimers::sharedTimerFired () at
../../../../src/main/native/Source/WebCore/platform/ThreadTimers.cpp:105
#48 0x65303abe in Java_com_sun_webkit_Timer_twkFireTimerEvent
(env=0x6890552c, clazz=0x68aa00c0)
at
../../../../src/main/native/Source/WebCore/platform/java/SharedTimerJava.cpp:63
...
...
...from first look at relevant sources it seems that the crash is a
result of not being able to allocate 64 KiB block with 64 KiB alignment
which means that a 128 KiB block is attempted to be mmap-ed and it
fails. The WebKit Javascript engine's answer to not being able to
allocate memory is simply a CRASH()? It seems so. Compared to HOTSPOT
this is very primitive, but such is the reality of this fast-grown code
unfortunately which is 4-times as big as the HOTSPOT. Anybody venturing
into using WebKit to build and run complex GUI-s should be told that
(and offered Java + JavaFX instead as alternative ;-)...
Regards, Peter
On 05/28/2014 05:17 PM, David Hill wrote:
On 5/28/14, May 28, 9:47 AM, Peter Levart wrote:
Hi Again,
The idea that comes to my mind is the following: would it be possible
to cross-compile the openjfx on the 64 bit Linux using 64 bit tools,
but targeted at 32 bit Linux? What would have to be changed in build
environment to accomplish that? I imagine the environment would have
to have access to headers and development libraries of the 32 bit
Linux system - that's no problem - I would just mount the root of a
32 bit Ubuntu to some directory, but then I would have to force all
tools to use that path instead of the running system one. And the gcc
would have to be given some cross-compiling options too, I guess...
In theory this is easy :-)
We already have a cross compile mechanism in gradle, used for the
Linux arm and Android builds. (see buildSrc/armv* for example).
You would start with one of the build files as a template -
linux.gradle, sed/copy it to linux32.gradle with something like:
cd buildSrc
sed -s 's/LINUX/LINUX32/' linux.gradle > linux32.gradle
After that, it would be a matter of tweaking the cc and ld flags
contained in the file, to tell gcc to be 32bit and to use the right
libraries. Looks like adding -m32 to commonFlags is all it should need:
// A set of common parameters to use for both compiling and linking
def commonFlags = [
"-m32", // <<<<< 32 bit output
"-fno-strict-aliasing", "-fPIC", "-fno-omit-frame-pointer", //
optimization flags
"-W", "-Wall", "-Wno-unused", "-Wno-parentheses",
"-Werror=implicit-function-declaration"] // warning flags
and tweak where the libraries are installed:
// Libraries end up in the sdk/rt/lib/$OS_ARCH directory for Linux
LINUX32.libDest = "lib/i386"
LINUX32.arch = "i386" # << this is an addition not needed in
linux.gradle
You specify the crossbuild like this:
gradle -PUSE_DEPEND=false -PBUILD_NATIVES=true
-PCOMPILE_TARGETS=linux32
But...
looks like we need to disable
LINUX32.compileFXPackager = false;
because build.gradle has some stuff hardcoded in it (would need a jira
for that if people care).
And - you need the i386 development packages installed. I had already
added this to get my cross compilers to work,
apt-get install libstdc++6:i386
but needed to add other to get more of the build to complete and ran
into apt-get telling me all my i386 deps were broken. Perhaps it would
work better if I was on a newer distro (I am on 12.04)
https://wiki.openjdk.java.net/display/OpenJFX/Building+OpenJFX
has the list of packages, in theory, you just need to add :i386 to
each one.
Since I can't get the i386 packages, at this point you are on your own
:-)
Dave
Peter
On 05/28/2014 03:39 PM, Peter Levart wrote:
Hi,
I'm new to this list and I have searched the archives, but haven't
found a discussion about this. If I have missed it, please just
direct me to the archived thread.
I'm trying to debug a crash in a native part of WebKit-JavaFX
bindings (https://javafx-jira.kenai.com/browse/RT-33599). I have
only been able to reproduce it on 32 bit platforms (Windows and
Linux so far). I'm trying to build the WebKit natives with debugging
symbols, so that I can pin-point the location of the crash in code
using gdb. I have managed to do this successfully on 64 bit Linux,
producing 1.7 GB large libjfxwebkit.so. But on 32 bit Linux, where
only I can reproduce the crash, the build fails with linker error:
"memory exhausted" when trying to assemble the libjfxwebkit.so from
object files. So far I have not been successful in my attempts to
circumvent this build error. I fave tried the following:
- added '--no-keep-memory' to linker options. The man page says
about it:
ld normally optimizes for speed over memory usage by
caching the symbol tables of input files in memory. This option
tells ld to instead optimize for memory usage, by
rereading the symbol tables as necessary. This may be
required if ld runs out of memory space while linking a large
executable.
- booted the 64bit Ubuntu system and chrooted into a 32 bit
environment. Some say that with 64 bit kernel, each 32 bit
user-space process has more address space than with 32 bit kernel.
- both of the above
My question to the list is: How do you guys produce 32 bit
libjfxwebkit.so with debugging symbols? Have you been able to? Do
you have any special tricks in your sleeves?
Regards,
Peter