Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts

Tuesday, December 28, 2021

Google Chrome with taskbar entry but no actual window - how to fix

I recently got a new laptop - Lenovo X1 Yoga Gen 6 and thought that it's now-or-ever opportunity to head-dive into NixOS which was something I cherished for a long time. Anyhow, I have different DPI displays and hence need to run Wayland. Things are still a bit shaky with Wayland, at least on NixOS with KDE but it's getting better every week! - that's why I'm running on the unstable channel.

Every now and then after upgrade it happens that Chromium (and Chrome) open up but don't show a window. There is a taskbar entry, they respond to right-click, show recent docs in the right-click pop-up, etc., but not matter what I do, there is no window shown which makes unusable of course. This is how it looks:

How to fix it?

TL;DR;


cd ~/.config/chromium/Default
cat Preferences |jq 'del(.browser.window_placement, .browser.app_window_placement)' |sponge Preferences

How did I figure it out? I'm no Chrome dev so I did it a CLI way:

  1. Copied my profile ~/.config/chromium aside, removed the original and checked that Chromium starts. I.e. it's a configuration issue
  2. Used binary search to determine which files in the profile cause the issue - namely, each time I rsync -av ~/.config/chromium{.old,}/Default/, removed some files, and checked if it helped. Eventually I figured out that Preferences file is the offender
  3. Now all was left is to compare the original and newly generated Preferences files. It's a single-line JSON file and I had to format it with jq tool first. Looking at the (huge) diff I was lucky to notice that .browser.window_placement configuration is different; and after copying Prefences from my original backup and dropping this attribute my Chromimum came back to life. Since I use Chromium web apps I had to reset .browser.app_window_placement as well
A bit of patience, a bit of luck and here we are! The same cure worked for Google Chrome. Hope this will help someone who stumbles on the similar matter. Of course if you have several Chrome/Chromium profiles you need to patch their Preferences too.

Update Jan 2022: Apparently the above hack works only partially and the issue kept triggering until Chromimum 97 landed in NixOS and it never happened since.

Thursday, February 25, 2016

Patching binaries

My friend asked for help - he has a legacy system that he wants to migrate to new hardware. His Linux OS is 10 years old and it becomes more and more challenging to find hardware to run it on. Long story short, I was asked to make his ten years old binaries to run on a modern Ubuntu.

Fortunately Linux has very impressive ABI compatibility, so my job was down to arranging executables and their dependent libraries. Well, almost.

There three ways of telling an executable (or actually ld.so interpreter) where to search for its libraries

  • Setting rpath on the executable itself.
  • Setting LD_LIBRARY_PATH environment variable.
  • Changing system wide configuration for ld.so to look into additional directories.

The binaries were setuid, and thus LD_LIBRARY_PATH was ruled out.

Next, I've tried to overcome it by putting libraries in /opt/old-stuff/lib and adding it to /etc/ld.so.conf.d/z-old-stuff.conf. This gave me some progress, but I hit the wall with naming collisions - my oldy binary was relying on older libreadline and I had two libreadline.so.5 libs - one in /lib and one in /opt/old-stuff/lib. The latter was obviously further down the search path, since otherwise it would break practically every command-line tool in the system.

So I needed to make my binary to use its own specific version of libreadline and to leave others using the default one. The only way to go was using rpath. Fortunately there is nifty utility out there called patchelf:

patchelf --set-rpath /opt/old-stuff/lib /opt/old-stuff/bin/foo
That almost did the trick. The caveat was that foo was using other library and only that library itself utilized libreadline. So the solution was to set rpath on all libraries as well:
for file in /opt/old-stuff/lib/*; do
    patchelf --set-rpath /opt/old-stuff/lib "$file"
done
Overall that was quite a shift from my current daily programming routine. I did not have to think about linkers for quite a lot of time by now and it was fun to have a taste of this stuff back again.