Sunday, December 30, 2007

Visual C++/Studio: Application configuration incorrect?

If you have just written a program in Microsoft Visual C++ or Visual Studio (2005 and above, I believe), try to run it on another machine, and get the error message “This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.” then you want to read on. If you just want to see me rant at Microsoft, read on as well.

The problem is really simple. If you write a C++ program, it links dynamically to the C Runtime Library, or CRT for short. This library contains your printf, your malloc, your strtok, etcetera. The library is contained in the file called MSVCR80.DLL. This file is not by default installed on a Windows system, hence the application cannot run.

The solution? Either install the DLL on the target machine through VCREDIST.EXE (the Visual C++ Redistributable Package), or link to the CRT statically (plug the actual code for the used functions straight into your EXE).

Distributing and installing VCREDIST along with a simple application is a pain in the arse, so I went for the second option: static linking. It's really easy: go to your project's properties, unfold C/C++, click Code Generation, and set the Runtime Library to one of the non-DLL options. That's all there is to it.

Now comes the rant part: how much effort it took me to figure all this out. You have been warned.

  1. “This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.” What kind of error message is that? It's like saying “sorry, your car does not work, because the engine won't start; please buy a new car.”
    In the very least, you could tell me that I'm missing a DLL. Preferably also tell me which particular DLL.
  2. Reinstalling the application, like the error message suggested, did of course not fix my problem. But the message also does not give a hint where to go looking for the error. It took some web searching to figure that out: the Event Log. Itself hidden quite well inside Windows, it told me which particular DLL was missing on the system. The Dependency Walker, that also comes with Visual Studio, told me that MSVCR80.DLL was indeed the culprit.
    The error message should at least point toward the more useful information: “See the Event Log for details.”
  3. I searched around on the web for MSVCR80.DLL and found its purpose. It turned out to be possibly the most basic library any C programmer could wish for. So why the heck is it not installed on any Windows system? It turns out that some older versions of the CRT are installed with Windows, but these are really ancient and buggy, and I honestly wouldn't know how to make Visual Studio link against them.
    So why, in these days of automatically updating systems and always-on internet connections, is this small (612 kB) but very essential DLL not included in service packs, or in Windows Update?
  4. Now, to fix the problem, I had to install the DLL on the target system. Simply dropping it alongside my application didn't work, because nowadays DLLs actually need to be installed. This is because modern DLLs are what Microsoft calls Side-by-side (SxS) Assemblies, which have been introduced in a brave attempt to diminish DLL hell. I don't know the gory details; it's something to do with manifests, and probably lots of candles, pentagrams and holy water as well.
    Anyway, you cannot download the VCREDIST installer straight from the Microsoft website, because there's only an old version there. Or is there? A newer page does give you what you want, and there's a 2008 version too.
  5. Thinking that it must be possible to link statically to the C Runtime Library, I looked into the project options in Visual Studio. I could not find the option there. Not very surprising, considering its name: “Runtime Library.” What runtime library? The Grand Unified DLL of Making Coffee? Or is this just a general option relating to runtime libraries in general? The default value (“Multi-threaded DLL”) seems to suggest this. I dared not touch this option for fear of breaking my application. It's a common problem with Microsoft: they often use a very generic-sounding name for something very specific.
    Had the thing been called “C Runtime Library linkage” instead, I would immediately have grasped its meaning.

On a not completely unrelated note, I'm pleased to announce that this bug in Taekwindow has finally been resolved.

Sunday, December 16, 2007

My ideal filesystem

I have a file server. It has multiple disks of various sizes. Some are old and likely to fail soon, others are brand new and will hopefully fail less soon. The file server contains nearly half a terabyte of data. Some data are big, others are small. Some are important, others I could do without.

The problem: it takes a lot of manual labour to manage all this. I need to decide which data goes where, keep an eye on the free space of each drive, make sure backups are made regularly, shuffle around data when I add a new disk, etcetera. Highly inconvenient.

The solution: My Ideal Filesystem, MIFS for short. Unlike other filesystems, MIFS is not stored on a single disk (or partition, if you like): it is spread out over multiple partitions. Unlike filesystems on a RAID or LVM array, MIFS actually has knowledge of the underlying structure of its disks (or partitions) and uses this knowledge to its advantage.

MIFS presents itself to the operating system simply as one filesystem. You can therefore mount it at a single mount point. There is only one small extension to the interface that normal filesystems expose to the OS: you can tag a file with a number that indicates the ‘importance’ of the file. This number indicates how bad it is if the file gets lost. So I can tag, for example, a thesis that I'm working on as very important, whereas a television series that I downloaded can easily be downloaded again and is therefore less important. There is also a number which specifies a ‘minimum redundancy’ for the file. If no number is specified, it is inherited from the parent directory.

Additionally, the disks comprising the filesystem each have a tag with their relative reliability, so you can indicate which disks are likely to fail soon. This number might be extracted from the SMART data that the disk itself presents, combined with a database of reliabilities of different disk models, if it is possible to build a database like that.

Now when I write a file to this filesystem, MIFS will decide what to do with it, depending on its importance. When the array is mostly empty, MIFS can afford to write files to each and every of the disks, achieving maximum redundancy and complete recovery even if all disks but one fail. When the array fills up, the files that are less important will be erased from some of the disks to make room for more important files. The ‘minimum redundancy’ tag ensures that my important thesis will always be on at least three of the disks. The filesystem is only full when all files are at their minimum redundancy level.

One could even go a step further, and put some of the disks in a machine across a network or even the internet. That would essentially give you automatic, real-time backups in case one of the machines gets fried along with all of its disks.

MIFS has only one huge drawback: it does not exist. Of course there are many technical difficulties to be overcome when implementing MIFS; I am not blind to that. But I think it should be possbile. Anyone who writes this filesystem will earn my eternal gratitude.

Friday, December 14, 2007

Using MS Word – the right way

It's been quite some time since I last used Microsoft Word for any serious document. Nowadays I mostly use LaTeX. Which of the two is “better” is not a discussion I want to get into: each has its own pros and cons and is suitable for a different purpose.

For those who are for some reason stuck with Word, I've been wanting to write an article on “proper Word usage” which takes much of the pain of the program away. However, I just discovered that this article already exists (and how couldn't it?): Living with Microsoft Word: Tips for survival.

No Word user, frequent or occasional, should be without the knowledge in this article. Spread the word! — Erm… sorry.

Thursday, December 6, 2007

A case against student presentations

For my master's in computing science, I am currently following two courses which largely consist of presentations given by the students themselves. The idea is that students research one topic in-depth, and learn about the other topics from others.

I've attended four such presentations today. One was quite good, one was mediocre and two were downright embarrassing. In view of my past experiences with such presentations, I found this a decent score.

Why doesn't this system work?

Firstly, students often don't know the material well enough. The presentation can then go one of two ways. Either the material that is not understood is skimmed over, or it is left out. If the hard stuff is only skimmed, we see slides with many complicated formulas, algorithms, graphs and numbers, but the presenter hardly touches upon them. Upon asking a question to dig up more information, only stutters come out. Equally bad, if the hard stuff is completely left out, we end up with a presentation so shallow that it is nearly without content. When we ask more detail, it turns out that the presenter knows no more than he told.

Secondly, most people cannot teach. Understandable, because teaching and explaining is hard. Why else would teachers have to go through years of training before they are allowed in front of a full classroom? And even then, most teachers are mediocre. University professors, despite knowing their subject very well, have received hardly any training at all, and are usually worse. Therefore students cannot be expected to be able to explain something properly. Those who can are the exception, not the rule.

It is already hard enough to get complicated material into your own mind. To get it into someone else's is much, much harder. Forcing people to attempt both at the same time is a recipe for failure.