Kir Kolyshkin (k001) wrote,
Kir Kolyshkin

the amazing story of fedora bug #638477

It's pretty amazing. A guy reported to Fedora bugzilla that his Fedora 14 have problems playing music via Adobe Flash -- "strange sound" as he puts it. He added that it works fine on Fedora 13, so it must be a regression. I would say such reports are going nowhere, for a number of reasons -- such bugs are hard to debug, Adobe Flash is closed-source hated piece of software, and there are way too many other bugs in Fedora to care about.

Fortunately, some other people have the same problem, among them is a guy named Linus Torvalds, who adds: "I see this as well. Sounds like clipping or some really bad sample rate frequency conversion". They tracked it down to a combination of Fedora 14 and 64-bit flash plugin. Then they tracked it down to glibc (old verions works fine, new one causes that "strange sounds"), and also found out (using valgrind) that flash plugin is doing memcpy() for the overlapping regions. In such case, memmove() should be used instead, as memcpy() behavior is undefined.

Anyway, to make a long story short, recent glibc version (the one shipped in F14) includes an optimization from Intel guys that speeds up memcpy() for Core 2 Duo, Atom and Core i7 CPUs. Apparently the part of optimization is that memory copying is now done backwards (from upper addresses to lower addresses) which manifestates the bug.

Now what is the solution? Fix Adobe Flash to use memmove(). It should take quite a lot of time, given the fact that the bug report to Adobe was only filed 4 days ago, i.e. this Monday.

What is the workaround? To use own implementation of memcpy() for the browser (and thus the flash plugin) by LD_PRELOADing it. A simple memcpy() implementation and details come from the same Torvalds guy.

Here are cut-n-paste instructions for Fedora 14/x86_64/Firefox users, tested on two F14 boxes by me.

cat << EOF > mymemcpy.c
#include <sys/types.h>

void *memcpy(void *dst, const void *src, size_t size)
void *orig = dst;
asm volatile("rep ; movsq"
:"=D" (dst), "=S" (src)
:"0" (dst), "1" (src), "c" (size >> 3)
asm volatile("rep ; movsb"
:"=D" (dst), "=S" (src)
:"0" (dst), "1" (src), "c" (size & 7)
return orig;

# Compile and link
gcc -O2 -c mymemcpy.c
ld -G mymemcpy.o -o
# Install
sudo cp /usr/local/lib64/
# chcon is for SELinux users
sudo chcon --reference=/lib64/ /usr/local/lib64/
# Patch the script that runs Firefox
sudo sed -i 's,\(^[[:space:]]*\)\("$prog" ${1+"$@"}\),\1LD_PRELOAD=/usr/local/lib64/ \2,' /usr/lib64/firefox-3.6/
# Same for newer Firefox versions
sudo sed -i 's,\(^[[:space:]]*\)\(exec "$prog" ${1+"$@"}\),\1LD_PRELOAD=/usr/local/lib64/ \2,' /usr/lib64/firefox-3.6/
# Same for Firefox 5:
sudo sed -i 's,\(^[[:space:]]*\)\(exec "$prog" ${1+"$@"}\),\1LD_PRELOAD=/usr/local/lib64/ \2,' /usr/lib64/firefox-5/

Tags: fedora, firefox, howto, linux, wow
  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded