Debian amd64: iceweasel with i386 plugins, outside a chroot
Introduction
If you weren't already convinced that closed source sucked before, then surely the experience of trying to browse the net with an amd64 machine will have won you over; I could ponder on how much Microsoft is paying Adobe not to release a 64-bit version of their flash plugin— but why Sun is categorically refusing to address our cry for a 64-bit java plugin for mozilla based browsers for this many years is beyond me.
There are three approaches to work around this conspiracy:
- Install everything in a 32-bit chroot and run the browser there.
- Use the 64-bit version of the browser and use a wrapper for the 32-bit plugins.
- Use a 32-bit version of the browser without chroot (a bi-arch approach).
I used option 1 (the chroot) for a while, but that approach has several annoying disadvantages:
- Every external application started by iceweasel necessarily also runs inside the 32-bit chroot. It is neat that you can assign programs to handle files with certain extensions, but in most cases you want to run those applications in your normal 64-bit environment of course (ie xmms, azureus, mplayer).
- If you download a file, you can only download it to the 32-bit chroot. Of course you can bind mount several directories like your home directory - but not every directory can be shared like that, and all too often I found myself downloading to my home directory just to make the file accessible, having to manually copy it in to it's final destination from a 64-bit shell.
I tried option 2, but it was a horror. Maybe some day that option will mature, but right now it's just not working for me.
That leaves option 3. However, the main disadvantage of that option is that you simply can't install i386 debian packages on an amd64 system. Therefore you have to fall-back to tar-balls and install everything manually. I tried this too, with as result that anti-aliasing didn't work anymore and java simply froze iceweasel.
The Best Of Both Worlds
The approach that I chose in the end is as follows: I installed everything that has to be of i386 architecture in a 32-bit chroot (as in option 1), using apt-get (or aptitude or whatever you like) and used a small wrapper and environment variables to run the browser in the 64-bit environment with a linux32 personality (as in option 3).
This turns out to a simple and painless procedure.
First, create an i386 chroot inside of which we will later install iceweasel. This chroot will be much smaller than that of option 1 above, because we won't need to install libraries that are already available from ia32 packages for the amd64 architecture.
You'll need some packages:
sudo apt-get install debootstrap
Creating the chroot
Choose the root of the chroot and it's handle:
CHROOT="/opt/firefox-chroot"; # The directory of the chroot. CHROOTNAME="firefox"; # The name as listed by schroot -l.
We need these too. You can set them to whatever works for you but the following should set them automatically (as usually, in my HOWTO's, just copy&paste the whole block to your (non-root) shell prompt):
HELPVAR=$(apt-cache policy coreutils | egrep '^[[:space:][:digit:]]*http:' | \ sed -r 's/^[[:space:]]*//;s/[[:space:]]+/,/g' | sort -rn | head -n 1) SUITE=$(echo "$HELPVAR" | cut -d, -f 3 | sed -e 's%/.*%%') DEBIANMIRROR=$(egrep "^deb (\[.*\] )?$(echo "$HELPVAR" | cut -d, -f 2).*$SUITE" /etc/apt/sources.list | \ sed -r 's/^[[:space:]]*//;s/\[.*\]//;s/[[:space:]]+/,/g;s%/,%,%g;s%,%/,%g' | cut -d, -f 2) echo -e "SUITE = \"$SUITE\"\nDEBIANMIRROR = \"$DEBIANMIRROR\""
This should set $SUITE to something like 'lenny' and $DEBIANMIRROR to something like 'http://ftp.debian.org/debian/'.
If SUITE is 'unstable', 'testing' or 'stable' then debootstrap won't work without providing the current codename. Therefore, try to extract that:
CODENAME=$SUITE if test ! -e /usr/share/debootstrap/scripts/$SUITE; then CODENAME=$(sed -ne 's/^Codename: \([a-z]*\)$/\1/p' /var/lib/apt/lists/$(echo "$DEBIANMIRROR" | sed -e "s%http://*%%;s%/%_%g")dists_"$SUITE"_Release) fi echo "CODENAME = $CODENAME"
Create the new directory and install the base system into it:
sudo mkdir "$CHROOT" sudo debootstrap --arch i386 $SUITE "$CHROOT" $DEBIANMIRROR /usr/share/debootstrap/scripts/$CODENAME
This installs about 180 MB in $CHROOT.
Since we won't run iceweasel inside the chroot, there is no need to do (bind) mounts, or install home directories or whatever— but we still need a few more packages to be installed.
Enter the chroot as root:
sudo chroot "$CHROOT"
Before running apt-get, you might want to fix a few things:
In order to get rid of the message
"WARNING: The following packages cannot be authenticated!
",
run the following command:
apt-get update
This will retrieve the missing Release.gpg
.
If you want to get rid of the warnings:
perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = (unset), LC_ALL = (unset), LANG = "en_US.UTF-8" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C"). locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_MESSAGES to default locale: No such file or directory locale: Cannot set LC_ALL to default locale: No such file or directory
then run the following commands (this installs an additional 18 MB)
(on etch /etc/locale.gen
doesn't exist at this point. Assuming
you are using UTF-8 encoding ($LC_CTYPE
contains the string UTF-8),
use instead of the sed command below:
echo "$LC_CTYPE UTF-8" > /etc/locale.gen
):
LANG= apt-get install locales eval `locale 2> /dev/null` sed -ri 's/^([^#].*)/# \1/;s/^# ('$LC_CTYPE'($| .*))/\1/' /etc/locale.gen locale-gen
[ If you don't want that, then you can temporarily suppress these messages by doing instead:
eval `LANG= locale`
but you'd need to do that every time you enter the chroot for maintenance. ]
Next, edit /etc/apt/sources.list
and add a line
for security updates (as usual, just copy&paste the whole block to
the shell prompt (outside the chroot)):
exit # Leave the chroot if ! grep 'security\.debian\.org' $CHROOT/etc/apt/sources.list; then sudo sh -c 'echo "# Security updates." >> '"$CHROOT"'/etc/apt/sources.list; \ echo "deb http://security.debian.org/ '"$SUITE"'/updates main contrib" >> '"$CHROOT"'/etc/apt/sources.list' fi
Also add contrib
and non-free
, as we'll need that for
the plugins later on:
sudo sed -ri 's/^(deb '$(echo $DEBIANMIRROR | sed 's/\/$//;s/\([$/.]\)/\\\1/g')' '$SUITE' main)$/\1 contrib non-free/' $CHROOT/etc/apt/sources.list
and update the chroot
sudo chroot $CHROOT apt-get update sudo chroot $CHROOT apt-get dist-upgrade
A More General chroot
If you are just creating the chroot for running iceweasel, then you can skip this paragraph. However, I can imagine that some people are using this page to set up a more general chroot, for other purposes; therefore I decided to add this paragraph that describes how to finish the chroot so it can be used in general, just to have all information in one place.
First you'll want to bind mount a few directories. Add the (output of) the following to your /etc/fstab (the real one, not the one in the chroot!).
exit # Leave the chroot cat << EOF # $CHROOTNAME chroot /proc $CHROOT/proc none bind 0 0 /dev $CHROOT/dev none rbind 0 0 /tmp $CHROOT/tmp none bind 0 0 /home $CHROOT/home none bind 0 0 EOF
and possibly other directories. Try to avoid any directories that debian installs files in however, or the chroot will overwrite your system files (and vica versa) of course.
WARNING: If you 'rm -rf
' the $CHROOT
directory then everything (still) bind mounted will be deleted as well!
A 'bind mount' is not normally visible with 'df
', you
will need to do 'df -a
' to see it
(I lost my home directory this way, while doing tests in order to write this howto)!
After adding those lines, they are still not mounted until you reboot; so mount them manually this time:
sudo mount $CHROOT/proc sudo mount $CHROOT/dev sudo mount $CHROOT/tmp sudo mount $CHROOT/home
Note that you can also bind mount from the command line without
adding the extra configuration lines to /etc/fstab
.
You'll need --rbind
for /dev
,
because otherwise /dev/pts
isn't included. For example,
sudo mount --bind /proc $CHROOT/proc sudo mount --rbind /dev $CHROOT/dev sudo mount --bind /tmp $CHROOT/tmp
You'll want to use schroot
to switch to the
chroot as a normal user:
sudo apt-get install schroot
Finally, fix your /etc/schroot/schroot.conf
and possibly
setup a little wrapper and symlinks as is described in
Running applications inside a chroot using schroot.
Okay, back to installing iceweasel.
Installing Iceweasel
Enter the chroot and install iceweasel (this drags in another 130 MB)
and fix /usr/lib/iceweasel/iceweasel
not to be anal about
where it's installed:
sudo chroot $CHROOT apt-get --yes install libgconf2-4 apt-get --yes install iceweasel sed -i 's/^MOZ_DIST_BIN=.*/MOZ_DIST_BIN="$(dirname $0)"/' /usr/lib/iceweasel/iceweasel
Setting Up A Wrapper
Leave the chroot and install some needed libraries:
exit # Leave the chroot sudo apt-get install ia32-libs-gtk
Installing iceweasel already dragged in so many libraries into
the chroot, that ia32-libs-gtk
is only really need for
/usr/lib/gtk-2.0/2.10.0/engines/libclearlooks.so
.
I can imagine that it's possible to remove (a lot of) libraries
from the chroot because they are already installed as some ia32
package in your amd64 environment, but at this moment I'm too
lazy to look into that (for the few cents worth of diskspace).
Next, create the wrapper to start iceweasel;
for example, create a file /usr/local/bin/firefox
as follows:
sudo sh -c 'cat > /usr/local/bin/firefox << EOF #!/bin/sh export GTK_PATH="/usr/lib32/gtk-2.0" CHROOT="'$CHROOT'" export LD_LIBRARY_PATH="/lib32:/usr/lib32:\$CHROOT/lib:\$CHROOT/usr/lib" linux32 "\$CHROOT/usr/lib/iceweasel/iceweasel" "\$@" EOF' sudo chmod +x /usr/local/bin/firefox
This should create a file with content like the following:
#!/bin/sh export GTK_PATH="/usr/lib32/gtk-2.0" CHROOT="/opt2/firefox-chroot" export LD_LIBRARY_PATH="/lib32:/usr/lib32:$CHROOT/lib:$CHROOT/usr/lib" linux32 "$CHROOT/usr/lib/iceweasel/iceweasel" "$@"
At this point everything should work except plugins: It's using your
normal home directory, and thus ~/.mozilla
and thus your
bookmarks, preferences, cookies, passwords etc. Also anti-aliasing should
work fine already at this point, as well as "File Type / Download Actions"
(Preferences -> Content -> File Types, Manage...), which will run
your external applications as 64-bit applications now.
Note that the wrapper sets LD_LIBRARY_PATH
to both,
[/usr]/lib32
as well as $CHROOT[/usr]/lib
,
both containing 32-bit libraries. The latter are needed because
not all needed 32-bit libraries are provided by ia32-libs
and ia32-libs-gtk
. But why prepend the path with
the lib32 ones? Surely every needed 32-bit library could be installed
in the chroot? The reason for this is that some of the libraries
contain hardcoded paths, or should I say, one library contains
a hardcoded path... $CHROOT/usr/lib/libgdk_pixbuf-2.0.so.0
contains the hardcoded path /usr/lib/gtk-2.0/2.10.0/loaders
.
This causes it to read the files in /usr/lib/gtk-2.0/2.10.0/loader-files.d
,
which contain libraries paths in /usr/lib
, 64-bit libraries.
Therefore it is needed to load libraries from /usr/lib32
before $CHROOT/usr/lib
.
Installing Plugins
Installing plugins, which are loaded when the browser is already running, should be easy. The only remaining problem might be hard-coded paths for externally run programs (like java_vm). Flash should not give any problems, so lets start with that.
Installing The Flash Plugin
Fonts
Flash applications often use Microsoft core fonts, and simply don't display any text if you don't have them (which can be very confusing). Therefore, you better install them as well (in the amd64 root):
sudo apt-get install msttcorefonts
After you installed the plugin, you can test if that worked
here. Besides TEXT1
,
TEXT2
and TEXT3
, you should see a
TEXT4
.
The whole point of the chroot is to make it easy to install and update the plugins. So, just enter the chroot and install the plugin the debian way:
sudo chroot $CHROOT apt-get install flashplugin-nonfree
Unfortunately the debian "maintainers" decided to remove this plugin from debian as of lenny. The plugin is now only available if you're using etch or when you're using unstable. See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=457291 for their reasons.
If the above didn't work then you'll have to use the package from unstable (codename: sid). Once lenny has become stable, and you are using stable you should use the backport (see below).
If you're using testing— then you might want to create the backport yourself, because backports.org is for 'stable', following the instructions below (adapted from 6.4.10 Port a package to the stable system from the debian reference manual). However, you might want to try to just use the 'stable' backport (hoping your libs are compatible; what they usually should be because 'testing' is newer than 'stable').
In order to compile the backport yourself do the following:
exit # Leave chroot if ! grep '^deb-src.*unstable' $CHROOT/etc/apt/sources.list; then sudo sh -c 'echo "# Sources from unstable." >> '"$CHROOT"'/etc/apt/sources.list; \ echo "deb-src '"$DEBIANMIRROR"' unstable main contrib non-free" >> '"$CHROOT"'/etc/apt/sources.list' fi sudo chroot $CHROOT apt-get update apt-get --yes install build-essential fakeroot devscripts debhelper; # Installs 65 MB. cd /usr/src mkdir flashplugin-nonfree cd flashplugin-nonfree apt-get source flashplugin-nonfree cd flashplugin-nonfree-* apt-get --yes build-dep flashplugin-nonfree dpkg-buildpackage -rfakeroot -us -uc dpkg -i ../flashplugin-nonfree_*_i386.deb apt-get purge build-essential fakeroot devscripts debhelper apt-get autoremove; # Free 65 MB again. cd /usr/src rm -rf flashplugin-nonfree
A disadvantage of this method is that it won't upgrade flash when a new release is available.
In order to use backports.org do the following (adapted from here). I'd urge you to use pinning so that upgrading later on will be automatic.
exit # Leave chroot STABLECODENAME=etch; # Change this if needed! if ! grep '^deb http://www\.backports\.org' $CHROOT/etc/apt/sources.list; then sudo sh -c 'echo "# Stable backports." >> '"$CHROOT"'/etc/apt/sources.list; \ echo "deb http://www.backports.org/debian '"$STABLECODENAME"'-backports main contrib non-free" >> '"$CHROOT"'/etc/apt/sources.list' fi sudo chroot $CHROOT apt-get update wget -O - http://backports.org/debian/archive.key | apt-key add - exit sudo chroot $CHROOT apt-get --yes --force-yes -t '"$STABLECODENAME"'-backports install flashplugin-nonfree
In order to use www.adobe.com do the following.
Since the support from debian is basically gone,
you might also opt for the alternative to download
the flashplayer from Adobe yourself and simply drop
it in ~/.mozilla/plugins/libflashplayer.so
.
Note that flash player 9.0 r115 (which you will get if
you download it now) and later have stricter policy files
which can cause your client to not be able to connect anymore to
certain servers. See for example here and
Adobes article on the matter.
Version 9.0 r48 and r31 work fine for me. You can obtain the version of your
current libflashplayer.so
with:
strings $CHROOT/usr/lib/iceweasel/plugins/libflashplayer.so | grep -e "^Shockwave Flash [.\d+]*" | sed -e "s/Shockwave Flash //g"
The version is also visible in about:plugins
Download install_flash_player_9_linux.tar.gz
from http://www.adobe.com/ and save and extract the tar-ball,
change directory to the extracted content and run as non-root:
linux32 ./flashplayer-installer
to install the plugin in ~/.mozilla/plugins, or run as root
to install system wide (the wrapper must be system wide too then, of course).
In the latter case enter <CHROOT>/usr/lib/iceweasel
as
browser directory, where you should replace <CHROOT>
with the value of your $CHROOT
.
Finally, you want to test it of course. Try this cool site.
Installing An Embedded PDF Viewer Plugin
I wasted two days trying to get acroread to work, but it's broken. Seriously, this is not incompetence; Adobe's acrobat reader really sucks.
Fortunately, there is an open source alternative and that means that if that doesn't work, we can fix it!
Firstly install mozplugger
in the firefox chroot,
and evince on your amd64:
sudo chroot $CHROOT apt-get --yes install mozplugger sudo apt-get install evince
This should immediately allow you to watch movies inside the browser
(provided you have mplayer installed in your amd64 environment); try
to open some .avi from your harddisk with the browser. Also have a look
at about:plugins
again. Wait, ... watching PDF and postscript
works too. It just all works! I love open source.
Installing The Java Plugin
More closed source... Yes, java is open source these days, but the plugin isn't: Sun refuses to release a 64-bit plugin for java, and when that was really open source, it would have been ported long ago.
The following commands will make java work:
sudo chroot $CHROOT apt-get --yes install libnss-mdns export LD_LIBRARY_PATH=/usr/lib/jvm/java-6-sun/jre/lib/i386/jli apt-get --yes --force-yes install sun-java6-bin
The export
is needed as work around for bug #435293
in the Debian bug tracking system. The package libnss-mdns
is needed because otherwise java just hangs firefox with 100% cpu
usage. You don't want to know what I all needed to do to find that
THAT was needed! Unfortunately, I still don't know WHY it is needed,
rather unsatisfactory.
Finally, we need:
exit # Leave chroot sudo update-alternatives --install /usr/lib/mozilla-firefox/plugins/libjavaplugin.so firefox-javaplugin.so $CHROOT/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7/libjavaplugin_oji.so 100 sudo update-alternatives --set firefox-javaplugin.so $CHROOT/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7/libjavaplugin_oji.so
The first update-alternatives
command (see man update-alternatives
) creates (or appends to)
a group firefox-javaplugin.so
with generic name /usr/lib/mozilla-firefox/plugins/libjavaplugin.so
and possible value $CHROOT/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7/libjavaplugin_oji.so
.
The group is created in automatic mode, using the (arbitrarily chosen) priority 100. The second
update-alternatives
command sets the group in manual mode and permanently links it to
the given value. In effect, the result is that a symbolic link /usr/lib/mozilla-firefox/plugins/libjavaplugin.so
points to /etc/alternatives/firefox-javaplugin.so
which in turn points to
$CHROOT/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7/libjavaplugin_oji.so
.
So why is this needed? Well, when run, iceweasel
tries to load
all shared libraries in $CHROOT/usr/lib/mozilla-firefox/plugins
,
the installation of sun-java6-bin
in the chroot created an alternative
with the name /usr/lib/mozilla-firefox/plugins
in the chroot that points to
/etc/alternatives/firefox-javaplugin.so
, exactly as we just did thus (and
even if it didn't do that; firefox simply loads everything from /usr/lib/mozilla-firefox/plugins
in the amd64 root!).
Therefore, either by reading the link $CHROOT/usr/lib/mozilla-firefox/plugins
or
by reading a hardcoded path /usr/lib/mozilla-firefox/plugins
, it
is refered to /etc/alternatives/firefox-javaplugin.so
in the amd64 root!
Hence, we need to add this alternative/symlink and point it back to the correct shared library
in the chroot. There is a minor problem with this however. Suppose one day you run 'apt-get update & apt-get upgrade'
in the chroot, and it changes the symbolic link— then our manually added link will
not change along and java will simply not work anymore. In that case you will have to update
this alternative manually. It is unlikely that it will change however: the name of the package
is sun-java6-bin, containing the '6', so at most the 'ns7' part might change one day
to 'ns8'? Or is it? In fact, even during the few days that I was testing this
these values have been changed! In the beginning, I needed:
sudo update-alternatives --install /usr/lib/iceweasel/plugins/libjavaplugin.so iceweasel-javaplugin.so $CHROOT/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7/libjavaplugin_oji.so 100 sudo update-alternatives --set iceweasel-javaplugin.so $CHROOT/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7/libjavaplugin_oji.so
If this link is wrong then the effect will be that no plugin for java is visible in about:plugins
.
In that case the correct link can be found with the strace
trick described below and looking for
a directory that firefox searches for plugins.
Trouble Shooting
I don't know why— but I decided to add this paragraph; maybe I don't feel too sure about that it will work for everyone, or I just want to show people how cool hacking is (the real meaning of the word, not 'breaking into computers' which is just sad, boring and immature and done by non-hackers). Actually, this is more a do-it-yourself recipe than a trooble-shoot section...
First of all, we realize that knowing the PID of a running process we can see
what libraries it loaded by looking at /proc/PID/maps
.
For example; I kill my xmms and then click on a some .pls file inside the
browser (I have iceweasel configured to start .pls files with xmms).
As this works, I already know that the 64-bit version of xmms is started
because I never installed xmms in the chroot, but suppose we want to check
this. First we find the PID of the running xmms and how it was started:
hikaru:~>ps --forest aux | grep -A3 '[f]irefox' carlo 31887 0.0 0.0 10656 1548 ? S 00:30 0:00 /bin/sh /home/carlo/bin/firefox carlo 31888 0.6 0.9 116536 36884 ? Sl 00:30 0:02 \_ /opt2/firefox-chroot/usr/lib/iceweasel/firefox-bin -a firefox carlo 32066 0.0 0.2 239012 11544 ? Sl 00:34 0:00 \_ /usr/bin/xmms /tmp/goapsy.pls
This shows that the PID of xmms
is 32066 and that is was indeed started by firefox-bin.
Of course, we can use file
to see the type of each of
the two executables involved:
hikaru:~>file /opt2/firefox-chroot/usr/lib/iceweasel/firefox-bin /opt2/firefox-chroot/usr/lib/iceweasel/firefox-bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), stripped hikaru:~>file /usr/bin/xmms /usr/bin/xmms: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), stripped
which shows that firefox-bin is 32-bit and xmms is 64-bit. Of course we could have known by just looking at the path, too. Finally, we can explicitely look at the libraries loaded by xmms (applying a filter to reduce the output a bit):
hikaru:~>cat /proc/32066/maps | grep lib | sed -e 's/.* //' | sort -u /lib/ld-2.7.so /lib/libc-2.7.so /lib/libdl-2.7.so /lib/libm-2.7.so /lib/libnsl-2.7.so /lib/libnss_compat-2.7.so /lib/libnss_dns-2.7.so /lib/libnss_files-2.7.so /lib/libnss_mdns4_minimal.so.2 /lib/libnss_nis-2.7.so /lib/libpthread-2.7.so /lib/libresolv-2.7.so /usr/lib/gconv/gconv-modules.cache /usr/lib/libasound.so.2.0.0 /usr/lib/libaudiofile.so.0.0.2 /usr/lib/libesd.so.0.2.36 /usr/lib/libgdk-1.2.so.0.9.1 /usr/lib/libGLcore.so.100.14.19 /usr/lib/libglib-1.2.so.0.0.10 /usr/lib/libGL.so.100.14.19 /usr/lib/libgmodule-1.2.so.0.0.10 /usr/lib/libgthread-1.2.so.0.0.10 /usr/lib/libgtk-1.2.so.0.9.1 /usr/lib/libICE.so.6.3.0 /usr/lib/libmikmod.so.2.0.4 /usr/lib/libogg.so.0.5.3 /usr/lib/libSM.so.6.0.0 /usr/lib/libvorbisfile.so.3.2.0 /usr/lib/libvorbis.so.0.4.0 /usr/lib/libX11.so.6.2.0 /usr/lib/libXau.so.6.0.0 /usr/lib/libXcursor.so.1.0.2 /usr/lib/libXdmcp.so.6.0.0 /usr/lib/libXext.so.6.4.0 /usr/lib/libXfixes.so.3.1.0 /usr/lib/libXi.so.6.0.0 /usr/lib/libxmms.so.1.3.1 /usr/lib/libXrender.so.1.3.0 /usr/lib/libXxf86vm.so.1.0.0 /usr/lib/libz.so.1.2.3.3 /usr/lib/locale/locale-archive /usr/lib/nvidia/libnvidia-tls.so.100.14.19 /usr/lib/xmms/Effect/libecho.so /usr/lib/xmms/Effect/libstereo.so /usr/lib/xmms/Effect/libvoice.so /usr/lib/xmms/General/libir.so /usr/lib/xmms/General/libjoy.so /usr/lib/xmms/General/libsong_change.so /usr/lib/xmms/Input/libcdaudio.so /usr/lib/xmms/Input/libmikmod.so /usr/lib/xmms/Input/libmpg123.so /usr/lib/xmms/Input/libtonegen.so /usr/lib/xmms/Input/libvorbis.so /usr/lib/xmms/Input/libwav.so /usr/lib/xmms/Output/libALSA.so /usr/lib/xmms/Output/libdisk_writer.so /usr/lib/xmms/Output/libesdout.so /usr/lib/xmms/Output/libOSS.so /usr/lib/xmms/Visualization/libbscope.so /usr/lib/xmms/Visualization/libogl_spectrum.so /usr/lib/xmms/Visualization/libsanalyzer.so
as well as of the running firefox-bin:
hikaru:~>cat /proc/31888/maps | grep lib | sed -e 's/.* //' | sort -u /emul/ia32-linux/lib/ld-2.7.so /emul/ia32-linux/lib/libc-2.7.so /emul/ia32-linux/lib/libdl-2.7.so /emul/ia32-linux/lib/libm-2.7.so /emul/ia32-linux/lib/libnsl-2.7.so /emul/ia32-linux/lib/libnss_compat-2.7.so /emul/ia32-linux/lib/libnss_dns-2.7.so /emul/ia32-linux/lib/libnss_files-2.7.so /emul/ia32-linux/lib/libnss_nis-2.7.so /emul/ia32-linux/lib/libpopt.so.0.0.0 /emul/ia32-linux/lib/libpthread-2.7.so /emul/ia32-linux/lib/libresolv-2.7.so /emul/ia32-linux/lib/librt-2.7.so /emul/ia32-linux/lib/libutil-2.7.so /emul/ia32-linux/usr/lib/gconv/ISO8859-1.so /emul/ia32-linux/usr/lib/gconv/UTF-16.so /emul/ia32-linux/usr/lib/gtk-2.0/2.10.0/engines/libclearlooks.so /emul/ia32-linux/usr/lib/gtk-2.0/2.10.0/loaders/libpixbufloader-xpm.so /emul/ia32-linux/usr/lib/libatk-1.0.so.0.2009.1 /emul/ia32-linux/usr/lib/libaudiofile.so.0.0.2 /emul/ia32-linux/usr/lib/libbonobo-2.so.0.0.0 /emul/ia32-linux/usr/lib/libbonobo-activation.so.4.0.0 /emul/ia32-linux/usr/lib/libcairo.so.2.11.5 /emul/ia32-linux/usr/lib/libdbus-1.so.3.3.0 /emul/ia32-linux/usr/lib/libesd.so.0.2.36 /emul/ia32-linux/usr/lib/libexpat.so.1.0.0 /emul/ia32-linux/usr/lib/libfontconfig.so.1.2.0 /emul/ia32-linux/usr/lib/libfreetype.so.6.3.16 /emul/ia32-linux/usr/lib/libgcc_s.so.1 /emul/ia32-linux/usr/lib/libgconf-2.so.4.1.2 /emul/ia32-linux/usr/lib/libgcrypt.so.11.2.3 /emul/ia32-linux/usr/lib/libgdk_pixbuf-2.0.so.0.1000.13 /emul/ia32-linux/usr/lib/libgdk-x11-2.0.so.0.1000.13 /emul/ia32-linux/usr/lib/libglib-2.0.so.0.1400.1 /emul/ia32-linux/usr/lib/libgmodule-2.0.so.0.1400.1 /emul/ia32-linux/usr/lib/libgnutls.so.13.8.4 /emul/ia32-linux/usr/lib/libgobject-2.0.so.0.1400.1 /emul/ia32-linux/usr/lib/libgpg-error.so.0.3.0 /emul/ia32-linux/usr/lib/libgthread-2.0.so.0.1400.1 /emul/ia32-linux/usr/lib/libgtk-x11-2.0.so.0.1000.13 /emul/ia32-linux/usr/lib/libICE.so.6.3.0 /emul/ia32-linux/usr/lib/libjpeg.so.62.0.0 /emul/ia32-linux/usr/lib/libORBit-2.so.0.1.0 /emul/ia32-linux/usr/lib/libORBitCosNaming-2.so.0.1.0 /emul/ia32-linux/usr/lib/libpango-1.0.so.0.1800.2 /emul/ia32-linux/usr/lib/libpangocairo-1.0.so.0.1800.2 /emul/ia32-linux/usr/lib/libpangoft2-1.0.so.0.1800.2 /emul/ia32-linux/usr/lib/libpcre.so.3.12.0 /emul/ia32-linux/usr/lib/libpng12.so.0.15.0 /emul/ia32-linux/usr/lib/libSM.so.6.0.0 /emul/ia32-linux/usr/lib/libstdc++.so.6.0.10 /emul/ia32-linux/usr/lib/libtasn1.so.3.0.10 /emul/ia32-linux/usr/lib/libX11.so.6.2.0 /emul/ia32-linux/usr/lib/libXau.so.6.0.0 /emul/ia32-linux/usr/lib/libXcursor.so.1.0.2 /emul/ia32-linux/usr/lib/libXdmcp.so.6.0.0 /emul/ia32-linux/usr/lib/libXext.so.6.4.0 /emul/ia32-linux/usr/lib/libXfixes.so.3.1.0 /emul/ia32-linux/usr/lib/libXft.so.2.1.2 /emul/ia32-linux/usr/lib/libXinerama.so.1.0.0 /emul/ia32-linux/usr/lib/libXi.so.6.0.0 /emul/ia32-linux/usr/lib/libxml2.so.2.6.30 /emul/ia32-linux/usr/lib/libXp.so.6.2.0 /emul/ia32-linux/usr/lib/libXrandr.so.2.1.0 /emul/ia32-linux/usr/lib/libXrender.so.1.3.0 /emul/ia32-linux/usr/lib/libXt.so.6.0.0 /emul/ia32-linux/usr/lib/libz.so.1.2.3.3 /emul/ia32-linux/usr/lib/pango/1.6.0/modules/pango-basic-fc.so /opt2/firefox-chroot/lib/libnss_mdns4_minimal.so.2 /opt2/firefox-chroot/usr/lib/iceweasel/components/libmyspell.so /opt2/firefox-chroot/usr/lib/iceweasel/components/libspellchecker.so /opt2/firefox-chroot/usr/lib/iceweasel/firefox-bin /opt2/firefox-chroot/usr/lib/iceweasel/libmozjs.so /opt2/firefox-chroot/usr/lib/iceweasel/libxpcom_compat.so /opt2/firefox-chroot/usr/lib/iceweasel/libxpcom_core.so /opt2/firefox-chroot/usr/lib/iceweasel/libxpcom.so /opt2/firefox-chroot/usr/lib/iceweasel/plugins/libunixprintplugin.so /opt2/firefox-chroot/usr/lib/libavahi-client.so.3.2.4 /opt2/firefox-chroot/usr/lib/libavahi-common.so.3.5.0 /opt2/firefox-chroot/usr/lib/libavahi-glib.so.1.0.1 /opt2/firefox-chroot/usr/lib/libdbus-glib-1.so.2.1.0 /opt2/firefox-chroot/usr/lib/libgnome-2.so.0.1999.2 /opt2/firefox-chroot/usr/lib/libgnomevfs-2.so.0.2000.1 /opt2/firefox-chroot/usr/lib/libhunspell-1.1.so.0.0.0 /opt2/firefox-chroot/usr/lib/libnspr4.so.0d /opt2/firefox-chroot/usr/lib/libnss3.so.1d /opt2/firefox-chroot/usr/lib/libplc4.so.0d /opt2/firefox-chroot/usr/lib/libplds4.so.0d /opt2/firefox-chroot/usr/lib/libsmime3.so.1d /opt2/firefox-chroot/usr/lib/libsqlite3.so.0.8.6 /opt2/firefox-chroot/usr/lib/libssl3.so.1d /opt2/firefox-chroot/usr/lib/nss/libfreebl3.so /opt2/firefox-chroot/usr/lib/nss/libnssckbi.so /opt2/firefox-chroot/usr/lib/nss/libnssdbm3.so /opt2/firefox-chroot/usr/lib/nss/libsoftokn3.so /usr/lib/locale/locale-archive
Each of the libraries should be either in /emul/ia32-linux
or in /opt2/firefox-chroot
, of course. We see one mapped
file that is from the 64-bit install: /usr/lib/locale/locale-archive
.
But that file is neither 32-bit nor 64-bit architecture. Nevertheless, since it
resides in /usr/lib
it is probably related to some
library. I used the following rather brute force way to find out which:
hikaru:~>for f in $(cat /proc/985/maps | grep lib | sed -e 's/.* //' | sort -u); do if strings $f | grep 'locale-archive'; then echo $f; fi; done /usr/lib/locale/locale-archive /opt2/firefox-chroot/lib/libc-2.7.so
This shows that /opt2/firefox-chroot/lib/libc-2.7.so
is the library that has this filename hard-coded. That's a good
thing because libc won't suddenly drastically change; as long as
we are using the same suite in the chroot as well as in the normal
file system, the version of the library should be the same enough
to be able to use each others files. In fact, although not installed
by the libc6 package but rather generated, the file has the exact
same size in each of the roots:
hikaru:~>ls -l /usr/lib/locale/locale-archive $CHROOT/usr/lib/locale/locale-archive -rw-r--r-- 1 root root 1282816 2008-02-03 20:25 /opt2/firefox-chroot/usr/lib/locale/locale-archive -rw-r--r-- 1 root root 1282816 2008-01-28 00:49 /usr/lib/locale/locale-archive
I made a diff of the hexdump-- and I don't think this is something we have to worry about.
Another issue is the mixture of libraries from /emul/ia32-linux
and /opt2/firefox-chroot
respectively. Again, although both
are the same suite, it might happen that libraries the i386 architecture
get out of sync with those in the ia32 libs of the amd64 suite, especially
if you don't run 'apt-get update/upgrade' in both roots at the same time.
The question is therefore: can this cause problems? I don't think so,
but if you HAVE problems and you suspect that this might be the cause,
then you might want to try to get rid of the libraries loaded from
/emul/ia32-linux
. You would have to remove the [/usr]/lib32
paths from LD_LIBRARY_PATH
and install packages
in the chroot for any remaining library that is missing. You'd also need
to find a solution for the hardcoded path in libgdk_pixbuf-2.0.so.0
.
Those extra packages would be (I tried that):
gtk2-engines
(libclearlooks.so
), libgconf2-4
(libgconf-2.so.4.1.2
),
liborbit2
(libORBit-2.so.0.1.0
) and libpango1.0-0
(
pango-basic-fc.so).
Now that is weird: libpango1.0-0
is already installed in the chroot!
Apparently we should tell pango where to look for it's modules. This would be possible
by setting the environment variable PANGO_RC_FILE and have it point to a file
with a section [Pango]
containing ModuleFiles=/path/to/libpango1.0-0.modules
,
where the paths in that libpango1.0-0.modules files are fixed to incorporate the
chroot offset. Neither, /emul/ia32-linux/usr/lib/pango/1.6.0/module-files.d/libpango1.0-0.modules
nor $CHROOT/usr/lib/pango/1.6.0/module-files.d/libpango1.0-0.modules
could be used,
because they contain absolute paths. Anyway, so far I have not seen this to cause
any problems so I see no need to do this.
With all these hard-coded paths, it would be a wild guess how and where iceweasel looks for plugin files, or how it tries to start the java virtual machine. Therefore I'll conclude this paragraph with a way to strace iceweasel.
Iceweasel has provisions to run it inside a debugger. We can hijack that and start it through strace.
First, install strace
in the chroot:
sudo chroot $CHROOT apt-get install strace exit
Please make sure you use at least version 4.5.15 of strace (also on your amd64), or
you'll likely to run into the umovestr I/O errors on 32-binaries bug.
Version 4.5.15 is at the moment of writing only in unstable, hence, if you still have 4.5.14 or earlier, use:
apt-get -t unstable install strace
, which worked fine for me on lenny (actually,
I still get 'umovestr I/O errors' when running (32-bit) firefox inside (64-bit) strace
which subsequently starts a 64-bit external application again. In the case that you
need to strace an external application, you'll have to run firefox without strace
and insert the strace at the right place in some script).
Then run
firefox --debugger "$CHROOT/usr/bin/strace -f -o output -e trace=file" "about:plugins"
where firefox
is our little wrapper.
This will write every system call involving a file- or directory name to the file output
.