Archive for April, 2009

luit -encoding gbk Segmentation Fault

Chinese users have been encountering segmentation faults when they use luit with GBK in for a long time. (It worked perfectly in the good old days.) This is caused by a bug in X.

A simple workaround is as follows:

Open file /usr/share/fonts/encodings/encodings.dir and exchange the following two lines:

gbk-0 large/gbk-0.enc
gbk-0 large/gbk-0.enc.gz

For more details, refer to li2z’s post.
(I believe anybody interested in this problem should be able to read Chinese:) )

Tags: , , ,

Dynamic library symlinks

Happened to be asked – so a chance to write it down.

Take giflib as an example: It installs three .so files in /usr/lib: libgif.so, libgif.so.4, libgif.so.4.1.6.

The third file is the true library, and the first two are both symlinks to the third. It apparently is because that we want to allow multiple versions to coexist in one system that we append the version to the filename.

It is easy to understand why we need libgif.so (otherwise “gcc ... -lgif” is going to fail.)

The number appended to the second symlink, namely 4 here, is the ABI version. It does not have to be part of the full version, though it usually is. (glibc, the most important library in a working Linux system, is an exception.)

When linking a program against the library, we specify -lgif in the command line, and the linker would follow the symlink and find libgif.so.4.1.6. However, the library name recorded in the executable is libgifso.4 instead. (This name is specified by -Wl,-soname when making the library.) Consequently, if we later make a binary-compatible upgrade to the library and remove the older version, the executable still works. But if the upgrade is a major one (potentially binary-incompatible but still source-level compatible), we must either keep the older library or recompile the executable. If we don’t make these symlinks and simply use one file libgif.so, we will have hard-to-debug segmentation faults instead of missing-library error messages in such cases.

Tags: ,

globstar in bash 4 follows directory symlinks

Globstar is a new feature is bash 4, allowing us to traverse a directory more easily.

Unfortunately, it follows directory symlinks and thus can easily cause problems.

(bleeding) desktop t # echo ${BASH_VERSINFO[@]}
4 0 17 2 release x86_64-pc-linux-gnu
(bleeding) desktop t # shopt -s globstar
(bleeding) desktop t # ls -l
total 0
lrwxrwxrwx 1 root root 1 2009-04-16 18:58 t -> .
(bleeding) desktop t # find
.
./t
(bleeding) desktop t # echo **
t t/t t/t/t t/t/t/t t/t/t/t/t t/t/t/t/t/t t/t/t/t/t/t/t t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t/t
(bleeding) desktop t #

Oh no…

If you unfortunately tried something like echo /proc/**/meminfo, it probably would make you wait for minutes before dying with “Insufficient memory.” (In /proc/fd there resides a root symlink.)

If you use GRUB to boot your Linux system, you are likely to find a symlink in /boot also named boot pointing to the directory itself. Yes, this is going to confuse bash, too. And there surely are many more cases.

So let’s continue writing find ... | xargs ...

Tags: ,

[Gentoo] Logrotating emerge.log

It seems the reason why emerge.log is not logrotate‘d is that log analyzers (qlop and genlop) expect a full log. I’m not sure about qlop, but since I use only genlop, it seems okay to add it to /etc/logrotate.dgenlop supports reading logs from multiple files and also from compressed files (gzip and bzip2).

Create a logrotate configuration file. /etc/logrotate.d/emergelog:

/var/log/emerge.log {
    compresscmd /bin/bzip2
    uncompresscmd /bin/bunzip2
    compressext .bz2
    rotate 100
    create 660 portage portage
    delaycompress
    daily
    size 2M
}

I configured my logrotate to compress using lzma by default, but genlop recognizes only gz and bz2, so I need to explicitly specify bzip2 (or gzip) here.

A wrapper for genlop is also necessary. /usr/local/bin/genlop:

#!/bin/bash

f=()
for x in /var/log/emerge.log*; do
    f=("${f[@]}" -f "$x")
done
exec /usr/bin/genlop "${f[@]}" "$@"

Tags: , , ,