Programming Topics + Design of applications and programs + Overload Journal #99 - October 2010
Browse in : All > Topics > Programming
All > Topics > Design
All > Journals > Overload > 99
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: To DLL or Not To DLL

Author: webeditor

Date: 10 October 2010 13:57:00 +01:00 or Sun, 10 October 2010 13:57:00 +01:00

Summary: Shared libraries provide both benefits and problems. Sergey Ignatchenko introduces a rabbit's-eye view.

Body: 

Hi all! Let me introduce myself. My name is 'No Bugs' Bunny. I've appeared in two previous issues of Overload as a main character in articles about multithreading [Ignatchenko10], and now I've decided to start a writing career of my own. All opinions in my articles are my own, and don't necessarily coincide with opinion of the translator, let alone the editors of the journal. Most of the time, I will be thinking aloud on more or less controversial issues, so please always take my words with a good pinch of salt. I do not aim to tell absolute truths, but rather to raise questions and invite readers to think about their own answers.

Today I will think aloud about a rather contentious DLL issue. Please keep in mind that for the purposes of this article (unless it is specified explicitly) I will use term 'DLL' both for Windows DLLs and for .so libraries in Linux/*nix.

DLL hell

Whenever I need to link a DLL to my application, the very first thing that comes to my mind is 'DLL Hell'. Dependency problems and crashes caused by DLLs are extremely common, and the more installations an application has, the more likely the problems are to appear on some machine.

I will not elaborate on 'DLL Hell' theory, but will provide a few examples from my personal experience. My very first encounter with DLLs was many years ago, when I was a cute little bunny and the very term 'DLL Hell' hadn't even been coined. I had a third-party application which worked perfectly for me for months, and then I installed another application on my system (I think it was electronic dictionary application). Bang! The first application started to crash every time I tried to perform some simple operation. Being a curious little bunny with lots of time to spare, I started to research the problem, and eventually found out that the electronic dictionary I'd just installed had replaced the file MFC42.DLL with a 'customized' version; obviously it wasn't 100% compatible and it was the reason for my first application crashes. It was my very first practical lesson about DLLs.

During my career I've seen many applications which had millions of installations, and can tell you that when dealing with DLLs, the famous Murphy's law ('Anything that can go wrong, will go wrong') is not an exaggeration but an understatement. Not only have I seen when one very specific build of IE5.5 crashed an application which used it merely to show a fancy HTML-based splash-screen (how was QA supposed to test it? By trying all builds of IE in existence? And the ones that don't exist yet?), and situations where a faulty video card driver (obviously, a DLL too) caused the infamous 'Blue Screen of Death' only when also running a very specific application on a very specific laptop model (the bug has since been fixed by the laptop manufacturer), and bugs in no less a widely used file than MSVCRT.DLL. But IMHO the most convincing case was when an application with a few million installations started to use the function SetDIBits() to load Windows bitmaps (replacing the hand-written BMP file parsing + CreateBitmap() calls to simplify code); the result was that about 2% of installations just stopped working (and 2% meant 20000 frustrated users per million of installations, and resulted in many hundreds of complaints to the support department). Investigation revealed that while this function is a system one, some video drivers tried to optimize it and this 'optimized' version simply crashed for a certain BMP format (which was a perfectly valid, though not the most common, bitmap variation). This was the last straw for me, and I came to the conclusion: 'if you want your application to run reliably, avoid DLLs for as long as they're possible to avoid'.

It might not be your fault, but it is your problem

To make things even worse, if your application crashes the end-user doesn't care if it happened because some ill-behaved 3rd-party application replaced MFC42.DLL, or if it happened because of a faulty version of Internet Explorer which is installed on their system: for the end-user it is your application which crashes, your application s/he will blame, your support department s/he will call/write to, and it is you who will eventually need to deal with it. When the problem with the ill-behaved application installing faulty MFC42.DLL occurs, 99.99% of the users will not go into lengthy investigations of the reasons, they will just blame the application that crashes. An application is perceived as a single product, and DLL dependencies are implementation details which the end-user doesn't care about at all. And if the application crashes because I am using a DLL without a good reason, it is indeed my fault; my job is to deliver a product which should work in the best possible way for the end-user, and if that doesn't happen then I didn't do my job properly.

Pro-DLL

Now I hope that I've described the most compelling disadvantages of DLLs (there are more - I haven't mentioned technical issues like more complicated memory management or messy name mangling), I will try to describe reasons why one may want to use DLLs despite these disadvantages. Reasons for implemeting DLLs are traditionally numerous, but IMHO many of them are not valid on closer inspection.

Reasons which are usually used to justify using DLLs are the following:

Mitigation

With the 'DLL Hell' problem being so ubiquitous, numerous ways have been proposed to deal with it:

.so/RPM hell

While most of this article was written about DLLs, it would be a big mistake not to mention that *nix, and especially the Linux world, aren't free of similar problems. In particular, on Linux systems, specifying the exact version of an .so library is traditionally much more common than on Windows, making the hunt for the right version a particularly annoying exercise. Even if it is handled automagically by a package manager it still causes a horrible mess in installation directories and for deployment/maintenance purposes. In particular, incompatibilities between versions required by different subcomponents of the same executable abound (as just one such example, you can see the discussion about including OpenSSL v1.0 on the Apache mailing list [Apache]).

I don't want to say that Linux or Windows is better in regard of DLLs/.so's, I think that both are a horrible mess, and what I'm really surprised about is that both Windows and Linux/*nix are borrowing the very worst features from each other! *nix was the first to do it, borrowing the whole concept of DLLs as opposed to static linking from Windows - to the best of my knowledge, full support for .so's appeared in *nix as late as SVR4 in 1990 while Windows has had DLLs since Windows 1.0 in 1985. On the other hand, recent Windows 'side-by-side assemblies' seem to borrow from Linux a concept of explicit library version requirement for DLLs/.so's, which has been characterized in [Worthmuller10] as 'We were needing a solution, but we created a monster'.

Bottom line

I know for sure that hardcore fans of neither Windows nor Linux will be fascinated by this article, but that wasn't among my goals (as stated above, my goal was to invite people to think, and whoever can think critically is not a 'hardcore fan' in my book). What I've tried to say is that DLLs (or .so's) are full of inherent dangers, and the decision to use them is not to be taken lightly.

Personally I try to avoid them as long as possible, but the question 'how long is "as long as possible"?' still needs to be solved on case-by-case basis.

Good luck to everybody who needs to tackle DLLs, you'll definitely need it.

References

[Adams] http://en.wikipedia.org/wiki/Lapine_language

[Anderson00] 'The End of DLL Hell', Rick Anderson, Microsoft Corporation, 2000

[Apache] Apache HTTP Server Development Main Discussion List, http://mailarchives.apache.org/mod_mbox/httpd-dev/

[Ignatchenko10] 'Single-Threading: Back to the Future?', Sergey Ignatchenko, Overload #97/#98 (June/August 2010)

[Microsoft] http://msdn.microsoft.com/en-us/library/ms229072%28VS.80%29.aspx

[Worthmuller10] 'No End to DLL Hell!', Stefan Worthmuller, Dr. Dobb's Journal, September 2010, http://www.drdobbs.com/web-development/227300037

Notes: 

More fields may be available via dynamicdata ..