stewartsmith / libeatmydata

libeatmydata - because fsync() should be a no-op
https://www.flamingspork.com/projects/libeatmydata/
GNU General Public License v3.0
409 stars 21 forks source link

Chromium / Chrome / Gitkraken does not open any GUI window with libeatmydata #2

Closed divinity76 closed 2 years ago

divinity76 commented 7 years ago

observed on (pre-release) debian 9, on several computers, both on real hardware and in VMWare instances, with xorg/openbox/lightdm/xfce4 combo (aka, what you get if you install a clean debian 9 and run apt-get install xfce4 eatmydata chromium and reboot )

divinity76 commented 7 years ago

i have only checked with debian stretch (9)'s eatmydata up to version 105-5 , but i did manually apply the EBADFS patch ( https://github.com/stewartsmith/libeatmydata/commit/00de90b131fb6b6d92c91ff23e5dae45d1b66cd2 ) to debian's 105-5, ...which seems to make no difference (with Chromium, at least) :(

stewartsmith commented 7 years ago

(sorry for delay in looking at this).

Any hints in an strace of with/without eatmydata?

divinity76 commented 7 years ago

both Gitkraken and Chrome ends up in an infinite loop of nanosleep({tv_sec=0, tv_nsec=2000001}, NULL) = 0 in the end. and chrome sure does a lot of mprotect() calls, in the form of mprotect(0x7fffed71a000, 4096, PROT_READ), i wonder what the assignment operator here does if you try to reassign PROTREAD-protected memory in `libc##name = (libc##name####t)(intptr_t)dlsym(RTLD_NEXT, #name);, that *might* have something to do with it, idk, just a guess. i have attached 2 straces of Chromium,strace_off.txtis strace without libeatmydata , andstrace_eatmydata.txt` is with libeatmydata loaded from /etc/ld.so.preload , maybe you can find some clues in it... i didn't, but maybe i can spend some more time going through them later.

strace_off.txt strace_eatmydata.txt

(it still happens on the now stable released debian 9 btw)

divinity76 commented 6 years ago

Visual Studio Code is also affected

LordVolumeForm commented 6 years ago

Useful information at corresponding chromium bug 536815.

My own observations:

  1. Disabling libeatmydata's override of open64 makes the problem disappear.

  2. Reimplementing libeatmydata to make syscalls directly also works:

int open64(const char *pathname, int flags, ...)
{
    // ...
    return syscall(SYS_open, pathname, flags, mode);
}

(though this code is non-portable, and possibly not correct either.)

  1. Inserting printf logging calls in the above caused it to stop working again.

It seems the problem is libeatmydata's dlsym calling a memory allocation function which is overridden by chromium.

Is it possible to statically link libeatmydata to libc's syscall implementations? It would be portable, only pull in a tiny amount of code, and avoid the need to call any dynamic loading functions. (I'm not sure if that code would be -fPIC, but even if it's not the performance impact in this case must be minimal.)

stewartsmith commented 6 years ago
        /* We simply ignore it because libc is already loaded       */
        if (initing) {
                errno = EFAULT;
                return -1;
        }

This code isn't being hit there by any chance is it?

LordVolumeForm commented 6 years ago

No. Somehow chromium manages to call open64 before libeatmydata_init has run.

LordVolumeForm commented 3 years ago

Vote to close: works fine for me now.

divinity76 commented 3 years ago

@LordVolumeForm that's interesting, any idea what fixed it?

LordVolumeForm commented 3 years ago

@divinity76 Older versions of libeatmydata are now working, so the change must be in chrome/chromium.