Evince installation documentation

I just upgraded Evince on my system. Initial attempts were unsuccessful; I got the following message when trying to start it:

(evince:22841): GLib-GIO-CRITICAL **: Settings schema ‘org.gnome.Evince.Default’ is not installed

I have no idea what this means so in the interim I try upgrading ‘glib’. This mostly goes without hiccups (except that newer versions of glib apparently have a dependency on libffi, for reasons which are tentatively explained in the glib README), however, I get the same error message when I try to start Evince. After some Googling, I discover the necessity of ‘compiling the schemas’:

# glib-compile-schemas /usr/share/glib-2.0/schemas

No mention at all of this in Evince build documentation. It looks like the schema might be compiled automatically if you “make install” Evince without setting DESTDIR, but frankly the necessity of compiling the schema should be documented.

Advertisements

Crappy g++ documentation on template instantiation

The g++ documentation says on template instantiation:

G++ has extended the template instantiation syntax given in the ISO standard to allow forward declaration of explicit instantiations (with extern), instantiation of the compiler support data for a template class (i.e. the vtable) without instantiating any of its members (with inline), and instantiation of only the static data members of a template class, without the support data or member functions (with (static):

extern template int max (int, int);
inline template class Foo<int>;
static template class Foo<int>;

The one I’m interested in is “extern”. The docs as quoted above say that it “allows forward declaration of explicit instantiations”, but that’s useless; explicit template instantiations don’t need forward declarations, you may as well just do the instantiation. Of course, the documentation is actually incorrect by omission: the “extern” keyword in front of an explicit template instantiation (as in the example above) actually causes gcc not to emit the instantiated template (even when it would otherwise do so because of implicit instantiation). This means that we can use this syntax to avoid emitting a template instantiation which we know is already emitted in another module.

Avoiding the emission of a template instantiation in many cases has only limited practical value – it might reduce compilation and linkage time ever so slightly, and likewise reduce the disk space used by object files ever so slightly. It would also allow for removing the emitted instantiation from a shared library or executable if the same instantiation was known to be present in another library that we were linking against.

The point is, there’s a potentially useful feature which isn’t documented, yet the syntax is documented – with an incorrect description of what it does.

MySql 5.1 build documentation – utter crap

I’m currently experiencing the joy of upgrading from MySql 5.0 to 5.1 on our server. After building MySql with the same “configure” options as used previously, then installing it, I run the “mysql_upgrade” command, which gives me some alarming output, basically along the lines of:

mygame.scenarios_tags
Error : Unknown table engine 'InnoDB'
error : Corrupt
mygame.schema_migrations
Error : Unknown table engine 'InnoDB'
error : Corrupt
mygame.screenshot_attachments
Error : Unknown table engine 'InnoDB'
error : Corrupt

Unknown table engine? what the… Corrupt?

So, I go do some googling and reading of manuals (which I suppose I should have done beforehand, sure) and it turns out that in 5.1, the “InnoDB” storage engine (the only one worth actually using, as it actually supports locking and transactions) is now a “plugin” and you need a configuration option to enable it:

[mysqld]
plugin-load=innodb=ha_innodb_plugin.so

Ok, so, problem solved, right? Wrong. I then get the following output in the mysqld log:

111212 14:27:37 [ERROR] Can’t open shared library ‘/u1/overflow/usr/local/mysql-5.1.60/lib/mysql/plugin/ha_innodb_plugin.so’ (errno: 2 ld.so.1: mysqld: fatal: relocation error: file /u1/overflow/usr/local/mysql-5.1.60/lib/mysql/plugin/ha_innodb_plugin.so: symbol )
111212 14:27:37 [ERROR] Couldn’t load plugin named ‘innodb’ with soname ‘ha_innodb_plugin.so’.

Hmm, not what I call an extremely useful error message. There seems to be some symbol resolution problem, but I don’t even know what particular symbol it’s having trouble with. Rather than mess around and trying to debug this, I go back to the build options. When I run “configure –help” I see, amongst other things:

  --with-plugin-PLUGIN    Forces the named plugin to be linked into mysqld
                          statically.

Err, what the… so, if say “–with-plugin-innodb” or something similar, it will link the plugin statically into mysqld? Weird. But hey, it’s a worth a shot. I try adding that to my “configure” options, and it immediately spews out a message saying that it doesn’t recognize the “–with-plugin-innodb” option! What the hell? I try a few variations but no joy. Getting quite frustrated by now. Ok, the “configure –help” output doesn’t match what “configure” actually accepts, maybe the manual will be more update? Hmm, not really; it’s a bit of a confusing mess actually, and it claims that “–with-plugin-PLUGIN” should work. It does suggest however that no plugins are built by default, and therefore I decide to try the alternative “–with-plugins=innodb_plugin,innobase”. I’m not really sure if I need “innobase” but it seems like it can’t hurt. Waiting for compilation to finish now…

Success!

So, compiling without InnoDB support still produced a file called “ha_innodb_plugin.so”, which I can’t actually use? What the?

Be Careful with Simplistic Locking

(or: Re-entrant mutexes considered harmful)

A common method of protecting data from race conditions in an object-oriented system is to use a simple mutex. The pattern goes something like this:

  1. Call some access or modification method on an object
  2. On entry to the method, mutex (associated with the object) is obtained
  3. … method does its stuff
  4. Mutex is released
  5. Method returns

Java, for instance, provides built-in support for this particular sequence with the “synchronized” keyword. A method tagged as “synchronized” automatically obtains the mutex on entry and releases it on return, which removes a lot of the burden from the programmer who otherwise has to make sure that the mutex is properly released on every code path (including exceptions). This works fine in a lot of cases. Java’s mutexes are also re-entrant meaning that one synchronized method can call another one in the same object without causing instant deadlock, even though they share the same mutex (the mutex is associated with the object, not the method). However, “synchronized” is not suitable as a general purpose mutex, and in fact its re-entrancy can lead to bad design.

Consider a design which uses the listener pattern. That is, some class has a modifier method which modifies data and notifies a number of listeners of the change (via some listener interface). How could such a design be made thread-safe? it might be tempting to mark the modifier method as synchronized, and in many cases this would work fine. If a listener needs to access or modify data, it can do so, and the re-entrant nature of “synchronized” means no deadlock will occur. However, this approach is a bad design, for subtle reasons, which basically boil down to this: a mutex should not necessarily prevent data access or modification by threads which do not hold the mutex.

Huh, you may be thinking, what’s this guy smoking? That’s precisely what a mutex is for. But that’s not exactly what a mutex is for; a mutex is a mechanism to allow threads to co-ordinate access to data (or some resource) in order to avoid race conditions, but it is not specifically meant to limit resource access to the single thread holding the mutex. In particular, if the thread holding the mutex is waiting on a mutex held by a second thread, and the second thread is operating under the assumption that this is the case, then it should be fine for that thread to access the resource that is protected by the mutex – clearly there can be no race condition, since the only other thread that otherwise has any right to access the resource (i.e., the thread that holds the mutex) is blocked.

If you think this argument is absurd, consider two cases in Java where this situation can come about:

  1. An arbitrary thread needs to modify the data (the “model”) of a Swing component, and needs to do so synchronously, from within a listener callback which is called with a mutex protecting an object “O” held. To modify the model safely the listener needs to use EventQueue.invokeAndWait() or equivalent. The code invoked on the dispatch thread also attempts to access the object “O”. Bang – deadlock.
  2. Again, a listener callback is called with a mutex held. This time the listener calls a method on a remote object (in a second Java VM) via RMI. The remote invocation calls back in to the first VM and attempts to obtain the (supposedly re-entrant) mutex, however, due to the RMI implementation, is now running on a different thread in the first VM. Bang – deadlock.

The obvious workaround – invoking the listener callback(s) outside of a synchronized block, i.e. without the mutex held, does work; but it leaves the possibility that the data is modified between the modification event and the listener being notified, which can be undesirable. The best solution from a design point-of-view is to move the acquisition and release of the mutex outside of the responsibility of the object being protected by it. Thus the sequence at the start of the would be changed to:

  1. Acquire mutex
  2. Invoke method
  3. … method does its thing
  4. Method returns
  5. Release mutex

Also, it should be assumed (even enforced) that the mutex is not re-entrant, to allow for the case where the executing thread is not the one which actually acquired the mutex. This is more complicated, and places more burden on the programmer – which is not desirable, especially when dealing with concurrency – but it is a better overall design. For one thing, it allows a solution for the two problems outlined above; secondly, it separates concerns – why should an object worry about synchronising if it may or may not be used in a multi-threaded system?

Ideally there’d be some language support for this sort of design too. It would be nice if there was a way to tag that a specific object should only be touched when an associated mutex was held, and have static analysis to determine when such a rule was being broken. Unfortunately such things are not yet readily available/usable, at least not as far as I’m aware.

In conclusion: be careful when using “synchronized” or re-entrant mutexes; consider using non-re-entrant mutexes instead.

X keyboard crap

I’m getting this in my log when I try to start X:

[  7780.894] (EE) Error compiling keymap (server-0)
[  7780.894] (EE) XKB: Couldn’t compile keymap
[  7780.894] XKB: Failed to compile keymap
[  7780.894] Keyboard initialization failed. This could be a missing or incorrect setup of xkeyboard-config.
[  7780.894]
Fatal server error:
[  7780.894] Failed to activate core devices.

What’s going on? “Couldn’t compile keymap” has to be one of the most useless error messages ever. Why can’t you compile the keymap??!

Update:

I renamed the “xkbcomp” executable and replaced it with a script which logged options and output before executing the original. I’m seeing this output:

The XKEYBOARD keymap compiler (xkbcomp) reports:
> Error:            Cannot open “/tmp/server-0.xkm” to write keyboard descriptio
>                   Exiting

… However, I don’t understand why it’s unable to create a file in /tmp. I’ve verified the file doesn’t already exist before xkbcomp is run, and that all users can create files in /tmp (the “t” bit is set).

Once again, the error message is bad: please tell my why you can’t open the file. (Hint: it’s called perror).

Update: (Solved!):

Turns out the permissions were the problem. They were:  rwxr-xrwt, i.e. the group was denied write permission. I didn’t think this was a problem seeing as “other” users are allowed to write files, but apparently that’s not how Linux permission checking works.

Sakura 2.4.0 build failure

I was just trying to build the Sakura terminal emulator. More-or-less following the instructions exactly, after running “cmake .”, I then ran “make” at which point I got the following:

Unknown option: u
make[2]: *** [CMakeFiles/man] Error 1
make[1]: *** [CMakeFiles/man.dir/all] Error 2
make: *** [all] Error 2

Yeah, it’s not exactly the most helpful output, is it? This is what I hate about CMake and non-standard build systems in general. Eventually I figured out the problem is in the file “CMakeFiles/man.dir/build.make” where the target “CMakeFiles/man:” calls the “pod2man” utility (from that almighty piece-of-crap scripting language, perl) with a “-u” argument which “pod2man” doesn’t seem to recognize (perl 5.8.8). Removing that makes the build complete.

 

Trac is super crap

A couple of projects I work on use Trac (0.12.1, the latest at time of writing) for bug/issue tracking. I recently got an email from a user of our Trac system, saying that she couldn’t seem to reset her password – that is, the system told her that it had reset her password and sent her an email with the new password, but in fact the email with the new password never arrived.

I went to scan the trac logs, but it turns out they were disabled by default (first problem). I enabled the logs and reset my own password, but no joy – nothing untoward appears in the logs. I checked and double-checked the mail settings, but they all looked ok. I then altered the configuration, switching from SMTP to sendmail and specifying a freshly-crafted wrapper script which logs when it’s called as the “sendmail” executable. With this I can verify that the mail is not sent – the script doesn’t appear to be being executed, and the mail server logs show no activity.

Finally I stumble on another setting:

acct_mgr.notification.accountchangelistener = enabled

And with this, finally, finally, Trac starts sending the new password emails when I do a password reset. Now, this is a documented setting, but really, I mean really, couldn’t there have been some warning in the logs? Or could maybe the setting to allow users to reset their password also enable the “account change listener” (whatever that is)? Is it too much to ask that an obviously broken configuration be either made redundant or at least identified as such by the software?

Well, I’ve solved the original problem. It’s at this point, though, that I realise a much more significant problem exists: The Trac AccountManagerPlugin password reset functionality allows anyone to reset anyone else’s password, and, get this, this is where it gets good, they can have the new password sent to any email address. [Update: no, this is wrong; once you actually enable the acountchangelistener setting as described above, you get an error if the specified email address doesn’t match the account. However, if you don’t enable that setting, then anyone can reset your password; however they won’t receive the new password at the email address they specify].

When the password reset functionality is enabled, if you register as a new Trac user you will see text telling you that providing your email address is optional, but if you do provide it you will be able to “reset your password if you ever forget it”. That’s clearly bollocks [if accountmanagerlistener isn’t enabled], since the password reset function doesn’t verify that the email address is correct for the user [in that case].

The real problem, I guess, is that Trac doesn’t provide any decent built-in account management. I mean, should the account manager – a most basic piece of functionality – really be a plugin? I don’t think so. (Worse than that, to use the plugin with Trac 0.12, you have to use a subversion pull of the plugin rather than a released version!).

And that is why Trac is super crap.