20 November 2012

Understand and Prevent Deadlocks


Can you explain a typical C# deadlock in a few words? Do you know the simple rules that help you to write deadlock free code? Yes? Then stop reading and do something more useful.

If several threads have read/write access to the same data it is often often necessary to limit access to only on thread. This can be done with C# lock statement. Only one thread can execute code that is protected by a lock statement and a lock object. It is important to understand that not the lock statement protects the code, but the object given as an argument to the lock statement. If you don't know how the lock statement works, please read the msdn documentation before continuing. Using a lock statement is better than directly using a Mutex or EventWaitHandle because it protects you from stale locks that can occur if you forget to release your lock when an exception happens.

A deadlock can occur only if you use more than one lock object and the locks are acquired by each thread in a different order. Look at the following sequence diagram:



There are two threads A and B and two resources X and Y. Each resource is protected by a lock object.
Thread A acquires a lock for Resource X and continues. Then Thread B acquires a lock for Y and continues. Now Thread A tries to acquire a lock for Y. But Y is already locked by Thread B. This means Thread A is blocked now and waits until Y is released. Meanwhile Thread B continues and now needs a lock for X. But X is already locked by Thread B. Now Thread A is waiting for Thread B and Thread B is waiting for Thread A both threads will wait forever. Deadlock!

The corresponding code could look like this.

public class Deadlock
{
    static readonly object X = new object();
    static readonly object Y = new object();
   
    public void ThreadA()
    {
        lock(X)
        {           
            lock(Y)
            {
                // do something
            }
        }
    }

    public void ThreadB()
    {
        lock(Y)
        {
            lock(X)
            {
                // do something
            }
        }
    }
}

Normally nobody will write code as above with obvious deadlocks. But look at the following code, which is deadlock free:


public class Deadlock
{
    static readonly object X = new object();
    static readonly object Y = new object();
    static object _resourceX;
    static object _resourceY;

    public object ResourceX
    {
        get { lock (X) return _resourceX; }
    }

    public object ResourceY
    {
        get
        {
            lock (Y)
            {
                return _resourceY ?? (_resourceY = "Y");
            }
        }
    }

    public void ThreadA()
    {
        Console.WriteLine(ResourceX);
    }

    public void ThreadB()
    {
        lock(Y)
        {
            _resourceY = "TEST";
            Console.WriteLine(ResourceX);
        }
    }
}


But after re-factoring the getter for ResourceX to this

get { lock (X) return _resourceX ?? ResourceY; }

you have the same deadlock as in the first code sample!

Deadlock prevention rules


  1. Don't use static fields. Without static fields there is no need for locks.
  2. Don't reinvent the wheel. Use thread safe data structures from System.Collections.Concurrent or System.Threading.Interlocked before pouring lock statements over your code.
  3. A lock statement must be short in code and time. The lock should last nanoseconds not milliseconds.
  4. Don't call external code inside a lock block. Try to move this code outside the lock block. Only the manipulation of known private data should be protected. You don't know if external code contains locks now or in future (think of refactoring).

If you are following these rules you have a good chance to never introduce a deadlock in your whole career.



14 November 2012

How to find deadlocks in an ASP.NET application almost automatically


This is a quick how-to for finding deadlocks in an IIS/ASP.NET application running on a production server with .NET4 or .NET 4.5.

A deadlock bug inside your ASP.NET application is very ugly. And if it manifests only on some random production server of your web farm, maybe you feel like doom is immediately ahead. But with some simple tools you can catch and analyze those bugs.

These are the tools you need:
  • ProcDump from SysInternals   
  • WinDbg from Microsoft (Available as part of the Windows SDK (here is even more info)) 
  • sos.dll (part of the .NET framework)
  • sosext from STEVE'S TECHSPOT (Copy it into your WinDbg binaries folder)
ProcDump will be needed on the server where the deadlock occurs. All the other tools are only needed on your developer machine. Because WinDbg doesn't need any installation you can also prepare an emergency USB stick (or file share) with all the necessary tools.

If you think a deadlock occurred do the following:
  1. Connect to the Server
  2. Open IIS Manager 
  3. Open Worker Processes 
  4. Select the application pool that is suspected to be deadlocked
  5. Verify that you indeed have a deadlock, see the screenshot below
  6. Notice the <Process-ID> (see screenshot)
  7. Create a dump with procdump <Process-ID> -ma
    There are other tools, like Task Manager or Process Explorer, that could dump but only ProcDump is smart enough to create 32bit dumps for 32bit processes on a 64bit OS.
  8. Copy the dump and any available .pdb (symbol) files to your developer machine. 
  9. Depending on the bitness of your dump start either WinDbg (X86) or WinDbg (X64)
  10. Init the symbol path (File->Symbol File Path ...)
    SRV*c:\temp\symbols*http://msdl.microsoft.com/download/symbols
  11. File->Open Crash Dump
  12. Enter the following commands in the WinDbg Command Prompt and wait
  13. .loadby sos clr
  14. !load sosex
  15. !dlk
You should now see something like this:

0:000> .loadby sos clr
0:000> !load sosex
This dump has no SOSEX heap index.
The heap index makes searching for references and roots much faster.
To create a heap index, run !bhi
0:000> !dlk
Examining SyncBlocks...
Scanning for ReaderWriterLock instances...
Scanning for holders of ReaderWriterLock locks...
Scanning for ReaderWriterLockSlim instances...
Scanning for holders of ReaderWriterLockSlim locks...
Examining CriticalSections...
Scanning for threads waiting on SyncBlocks...
*** WARNING: Unable to verify checksum for mscorlib.ni.dll
Scanning for threads waiting on ReaderWriterLock locks...
Scanning for threads waiting on ReaderWriterLocksSlim locks...
*** WARNING: Unable to verify checksum for System.Web.Mvc.ni.dll
*** ERROR: Module load completed but symbols could not be loaded for System.Web.Mvc.ni.dll
Scanning for threads waiting on CriticalSections...
*** WARNING: Unable to verify checksum for System.Web.ni.dll
*DEADLOCK DETECTED*
CLR thread 0x5 holds the lock on SyncBlock 0126fa70 OBJ:103a5878[System.Object]
...and is waiting for the lock on SyncBlock 0126fb0c OBJ:103a58d0[System.Object]
CLR thread 0xa holds the lock on SyncBlock 0126fb0c OBJ:103a58d0[System.Object]
...and is waiting for the lock on SyncBlock 0126fa70 OBJ:103a5878[System.Object]
CLR Thread 0x5 is waiting at System.Threading.Monitor.Enter(System.Object, Boolean ByRef)(+0x17 Native)
CLR Thread 0xa is waiting at System.Threading.Monitor.Enter(System.Object, Boolean ByRef)(+0x17 Native)


1 deadlock detected.


Now you know that the managed threads 0x5 and 0xa are waiting on each other. With the !threads command you get a list of all threads. The Id Column (in decimal) is the managed thread id. To the left the WinDbg number is written. With  ~[5]e!clrstack command you can see the stacktrace of CLR thread 0x5. Or just use ~e*!clrstack to see all stacktraces. With this information you should immediately see the reason for the deadlock and start fixing the problem..


Deadlocked Requests visible in IIS Worker Process

Automate the Deadlock Detection

If you are smart, create a little script that automates step 2 to 7. We use this powershell script for checking every minute for a deadlock situation:


param($elapsedTimeThreshold, $requestCountThreshold)
Import-Module WebAd*
$i = 1
$appPools = Get-Item IIS:\AppPools\*
while ($i -le 5) {
ForEach ($appPool in $appPools){
 $count = ($appPool | Get-WebRequest | ? { $_.timeElapsed -gt $elapsedTimeThreshold }).count
 if($count -gt $requestCountThreshold){
$id = dir IIS:\AppPools\$($appPool.Name)\WorkerProcesses\ | Select-Object -expand processId
$filename = "id_" +$id +".dmp"
$options = "-ma"
$allArgs = @($options,$id, $filename)
procdump.exe $allArgs
 }
}
Start-Sleep -s 60
}


07 November 2012

Cooperative Thread Abort in .NET


Did you know that .NET uses a cooperative thread abort mechanism?

As someone coming from a C++ background I always thought that killing a thread is bad behavior and should be prevented at all costs. When you terminate a Win32 thread it can interrupt the thread in any state at every machine instruction so it may leave corrupted data structures behind.
A .NET thread cannot be terminated. Instead you can abort it. This is not just a naming issue, it is indeed a different behavior. If you call Abort() on a thread it will throw a ThreadAbortException in the aborted thread. All active catch and finally blocks will be executed before the thread gets terminated eventually. In theory, this allows the thread to do a proper cleanup. In reality this works only if every line of code is programmed in a way that it can handle a ThreadAbortException
in a proper way. And the first time you call 3rd-party code not under your control you are doomed.

Too make the situation more complex there are situations where throwing the ThreadAbortException is delayed. In versions prior to .NET 4.5 this was poorly documented but in the brand new documentation of the Thread.Abort method is very explicit about this. A thread cannot be aborted inside a catch or finally block or a static constructor (and probably not the initialization of static fields also) or any other constrained execution region.


Why is this important to you?

Well, if you are working in an ASP.NET/IIS environment the framework itself will call Abort() on threads which are executing too long. In this way the IIS can heal itself if some requests hit bad blocking code like endless loops, deadlocks or waiting on external requests. But if you were unlucky enough to implement your blocking code inside static constructors, catch or finally blocks your requests will hang forever in your worker process. It will look like the httpRuntime executionTimeout is not working and only a iisreset will cure the situation.

Download the CooperativeThreadAbortDemo sample application.

27 September 2012

Embed Url Links in TeamCity Build Logs

We at AutoScout24 are using TeamCity for our Continous Integration and Delivery. One step in our  Release Pipeline is integration testing in different browsers. If our test framework detects a problems it will create a screenshot of the breaking page. This screenshot contains valuable information that helps our developers to quickly analyze the issue. As an example, our test servers are configured to send stack traces which are visible in the screenshots.

But it seams that there is no way to include links in TeamCity build logs. TeamCity correctly escapes all the output from test and build tools so it is not possible to get some html into the log. So I investigated TeamCity extension points. Writing a complete custom html report seemed to be overkill because the test reporting tab worked really well. Writing a UI plugin means to learn Java, JSP and so on and as a .NET company we don't want to fumble around with the Java technology stack. But as a web company we know how to hack javascript ;-)

There is already a TeamCity plugin called StaticUIExtensions that allows you to embedd static html fragments in TeamCity pages. And because a script tag is a valid html fragment we could inject javascript into TeamCity. So I wrote a few lines of javascript that scan the dom for urls and transforms them into links. With this technique you get clickable links in all the build logs.


What you need to do:
  1. Install StaticUIExtensions 
  2. On your TeamCity server, open your "server\config\_static_ui_extensions" folder
  3. Open static-ui-extensions.xml
  4. Add a new rule that inserts "show-link.html" into every page that starts with "viewLog.html"
      <rule html-file="show-link.html" place-id="BEFORE_CONTENT">
        <url starts="viewLog.html" />
      </rule>
  5. Create a new file "show-link.html" with this content:
    <script>
      (function ($) {
        var regex = /url\((.*)\)/g
     
        function createLinksFromUrls() {
          $("div .fullStacktrace, div .msg").each(function () {
            var div = $(this);
            var oldHtml = div.html();
            var newHtml = oldHtml.replace(regex, "<a href='$1' target='_blank'>$1</a>");
            if (oldHtml !== newHtml) div.html(newHtml);
          });
        }
     
        $(document).ready(createLinksFromUrls);
        $(document).click(function () {
            window.setTimeout(createLinksFromUrls, 50);
            window.setTimeout(createLinksFromUrls, 100);
            window.setTimeout(createLinksFromUrls, 500);
        });
    })(window.jQuery); 
    
    </script>
    
This javascript searches for the url(*) pattern and replaces it with <a> tags.  Because TeamCity uses ajax to load the stacktraces when you expand a tree node, I used timers to delay the dom processing until the ajax call suceeded. Now you can log something like "url(http://www.autoscout24.de)" and this will be transformed to <a href="http://www.autoscout24.de">http://www.autoscout24.de</a>.

Voila, Mission completed.

10 August 2012

"Right" vs "Simple"

Compare these two Software Design philosophies:

MIT

Simplicity
The design must be simple, both in implementation and interface. It is more important for the interface to be simple than the implementation.
Correctness
Correctness-the design must be correct in all observable aspects. Incorrectness is simply not allowed.
Consistency
The design must not be inconsistent. A design is allowed to be slightly less simple and less complete to avoid inconsistency. Consistency is as important as correctness.
Completeness
The design must cover as many important situations as is practical. All reasonably expected cases must be covered. Simplicity is not allowed to overly reduce completeness.

New Jersey

Simplicity
The design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design.
Correctness
The design must be correct in all observable aspects. It is slightly better to be simple than correct.
Consistency
The design must not be overly inconsistent. Consistency can be sacrificed for simplicity in some cases, but it is better to drop those parts of the design that deal with less common circumstances than to introduce either implementational complexity or inconsistency.
Completeness
The design must cover as many important situations as is practical. All reasonably expected cases should be covered. Completeness can be sacrificed in favor of any other quality. In fact, completeness must sacrificed whenever implementation simplicity is jeopardized. Consistency can be sacrificed to achieve completeness if simplicity is retained; especially worthless is consistency of interface.
These philosophies are formulated by Richard Gabriel in "Worse is Better". Please read his article. I followed the first philosophy for many years before I learned the hard way the the second philosophy has a much higher success rate and if you programmed the right thing it will improve incrementally until it is much more right than anything designed with the first philosophy in mind. One last quote: "The right thing takes forever to design, but it is quite small at every point along the way. To implement it to run fast is either impossible or beyond the capabilities of most implementors."

17 June 2012

Visualizing a code repository with Bubble Charts and Circle Packing


German Version - English Version
Vor einiger Zeit bin ich über die freie Javascript Library d3.js gestolpert, die zur Visualisierung und Animation von  Daten in Webseiten dient. Da Datenvisualisierung eines meiner Hobbies ist und ich mich beruflich auch etwas mit Javascript beschäftige, lag es nahe sich dieses d3 etwas näher anzuschauen. Und es sollte sich lohnen, d3 rockt! Wirklich! Mit sehr wenig Aufwand, etwas Svg und Javascript hatte ich in einigen Stunden eine beeindruckende Visualisierung der Struktur eines sehr großen Source Code Repositories. Das Layouting und Rendering erledigt ein moderner Browser (IE9, Chrome, Safari oder Firefox) in wenigen Millisekunden. Ähnliches mit z.B. Graphviz und WPF als Rendering Engine zu implementieren wäre sehr viel aufwendiger, langsamer und unansehnlicher gewesen. Und da d3 im Browser läuft, ist die Visualisierung gleich plattformübergreifend verfügbar. Begeistert von den ersten Ergebnissen habe ich ausgehend von der ersten Spielerei gleich einige reale Probleme visualisiert. So sieht's heute aus:

Mein Arbeitgeber betreibt eine Website auf Basis von .NET und C#, an deren Entwicklung und Wartung sieben Teams seit einigen Jahren beteiligt sind. Dementsprechend viele Projekte gibt es im Repository. Große Projekte, kleine Projekte, wiederverwendete Projekte, exotische Projekte, tote Projekte, Jobs, Services und Web Anwendungen. Im Laufe der Zeit ging irgendwann die Übersicht verloren, welche Projekte wo benutzt werden, welches Team für welches Projekt zuständig ist, gegen welches Framework ein Projekt kompiliert, was eine gemeinsam genutzte  Komponente ist und was eine eigenständige Applikation sein sollte.
Mein Ziel war es, eine stark komprimierte Übersicht über die Projektstruktur zu geben und dabei die erwähnten Attribute zu visualisieren. Ursprünglich wollte ich dazu Treemaps verwenden, doch bei der Durchsicht der d3 Beispiele stieß ich auf Bubble Charts und Circle Packing die ich visuell ansprechender fand und die nach eigener Beschreibung "can pack hundreds of values into a small space" and "circle packing is not as space-efficient as a treemap, but it better reveals the hierarchy".
In der von mir verwendeten Variante wird jedes Projekt als ein Kreis ("Bubble") dargestellt. Jeder Kreis hat einen Namen, eine Größe (Durchmesser) und eine Farbe. Die Position der Bubbles innerhalb der Grafik ist durch den Packing Algorithmus bestimmt und kann nur in engen Grenzen (Sortierung) beeinflusst werden. Dies ist jedoch nicht schlimm, weil die Projekte innerhalb einer hierarchischen Verzeichnisstruktur liegen. Verzeichnisse werden ebenfalls als Kreise dargestellt, wobei geschachtelte Verzeichnisse und Projekte im übergeordneten Kreis angeordnet werden (siehe Bild). Damit werden in der Hierarchie zusammengehörende Projekte auch räumlich nahe beieinander dargestellt. Im obigen Beispiel sind die Verzeichnisse blau gefärbt, je tiefer die Verschachtelung, desto tiefer der Farbton. Die Bubble Attribute Größe und Farbe können dynamisch zur Visualisierung jeweils zweier Projekteigenschaften verwendet werden. Die Größe des Kreises kann beispielsweise die Größe des Projekts (in Bytes), die Anzahl der Abhängigkeiten oder die Anzahl der Verwender visualisieren. Jedes numerische Attribut kann auf den Durchmesser gemappt werden. Diskrete Werte wie z.B. Team Zugehörigkeit, .NET Version oder Projekttyp können besser durch Farben visualisiert werden.
Nun gibt es noch die Abhängigkeitsbeziehungen zwischen den Projekten. Das Managen dieser Abhängigkeiten ist eine 'viel geliebte' Aufgabe aller Architekten und wird häufig als Dependency Graph oder Dependency Matrix visualisiert. Die Visualisierung der Abhängigkeiten war nicht mein Primärziel, aber oft ist diese Information sehr nützlich. Ich experimentierte daher mit Animationen um diese Beziehungen parallel darzustellen. Ein Klick auf ein Projekt lässt alle Projekte blinken, die von dem angeklickten Projekt verwendet werden. Hält man beim Klicken die Strg Taste gedrückt, blinken alle Projekte die das angeklickte Projekt verwenden. 

Warum eigentlich ...

mache ich mir die Mühe dieser Visualisierung? Nun, ich kann alle Projekte und mehrere Eigenschaften gleichzeitig sehen. Durch geschickte Farbgebung, z.B. rot für ungesunde Eigenschaften, stechen selbst kleine Probleme optisch heraus. So kann ich jeden Tag mit einem Blick Änderungen in der Projektstruktur feststellen. Ein anderer Anwendungsfall war die Umstellung auf .NET4: alte Projekte sind rot, umgestellte sind grün. So lässt sich der Fortschritt leicht beobachten, und wenn alle Projekte umgestellt gibt es nur noch grüne Kreise. Neue hinzugekommene Projekte, die mit einem alten Framework angelegte wurden, lassen sich so sofort erkennen. Insbesondere für die interaktive Erforschung der Projektstruktur und dem Finden von nicht offensichtlichen Abhängigkeiten ist die Verbildlichung für mich als visuell denkenden Menschen sehr hilfreich. Dazu müssen natürlich auch ad hoc neue Eigenschaften visualisiert werden können, und dafür ist Flexibilität von d3 im Zusammenspiel mit Web Standards außerordentlich hilfreich.

Die Technik

Ein kleines C# Programm analysiert die Projektdateien (*.csproj files) und erstellt ein json Datenobjekt, dass die Verzeichnisstruktur, den Abhängigkeitsgraph sowie die Projekteigenschaften enthält (Größe, Typ, Team, .NET Version). Einige redundante Informationen wie leere Verzeichnisse oder Namens Prefixe werden in diesem Schritt entfernt. Das Datenobjekt misst unkomprimiert ca 120KB, und wird in ca 3s aus den Sourcen extrahiert. Dieses Objekt wird einmal pro Tag erzeugt und in eine statische WebSite kopiert. Das Javascript bubble.js übernimmt die Visualisierung im Browser. Dazu werden mit d3.js die Daten gelayoutet (d3.layout.pack()) und in SVG Elemente transformiert. Dies geschieht in wenigen Milisekunden. SVG bietet den Vorteil des flüssigen Zoomens und die grafischen Objekte bleiben als DOM Elemente erhalten und könnem mit Standard Events, wie MouseOver oder Clicks gescriptet werden. Daher ist ein moderner Browser mit SVG Unterstützung notwendig, z.B. Chrome, Safari, Firefox oder IE9. Erstaunlicherweise hat aktuell der IE9 die beste SVG Unterstützung, Chrome und Safari haben gröbere Probleme mit dem Textzooming und dem Hittesting. Firefox funktioniert gut, hat aber die schlechteste Performance. Das Javascript ist nach dem AMD Standard modularisiert, als AMD Loader wird mmd.js verwendet. Da ich zu Beginn die Funktionsweise des Circle Packing noch nicht genau kannte und auch noch nicht exakt wusste, welche Eigenschaften sinnvoll  visualisiert werden konnten, existiert ein kleines User Interface (Standard Html) mit dem verschiedene Parameter geändert werden können. D3 animiert solche Änderungen automatisch mit eingebauten Transitionen. Z.B. könnte man damit die Veränderung des Repositories im Zeitverlauf animieren. Dies könnte ein weiteres Hobby Projekt von mir werden ... stay tuned ...

29 March 2012

HTML5 without warnings in Visual Studio

Today I was annoyed about warnings that Visual Studio shows when editing an html5 file. Example: VS expects a type attribute inside the script tag but html5 doesn't require it anymore (because it defaults to javascript).

When opening the context menu I noticed the "Formatting and Validation" item and opened it:

html5_validate

Choosing "HTML5" as a target removes all those annoying wrong warnings :-)

19 January 2012

The best fellow employee ...

... is someone that you can criticize without pissing him off. The same should be true the other way round. I'm glad that I'm working for an exceptional company where nearly everyone has this attitude.