Category Archives: C++

(Русский) Проклятье C++ программиста

Sorry, this entry is only available in Russian.

(Русский) Время кидаться пальцами

(Русский) Докатился…

boost::context and SEH

I have been using boost::context library to implement coroutines in my project since this library was officially released with boost 1.52. We desperately needed an option to replace win32 fibers (there is always at least a couple of points to justify such move), and boost::context came in just right.

It all worked fine until lately, when we discovered a very odd thing that was happening only on Windows Server 2008. If an exception was raised from within the context, the application was immideately closed by the OS. Even though that exception was handled in place.

As it turned, Windows Server 2008 has so-called SEH overwrite protection mechanism enabled by default. In shirt, every time exception is raised, the OS first checks that nobody messed with exception registration pointers. Each thread, or, broadly speaking, each parallel stack has its own exception registration information (pointer to which appears to be on the top of the thread info block or at FS:[0]). That registration record contains a pointer to exception handler and a pointer to the previous record in a chain (so, you can have a list of exception handlers). When user code wants to raise an exception, SEHOP protection mechanism of Windows Server 2008 walks back this list to make sure it always ends with a handler provided by the OS itself.

And here is the problem – with boost::context library you end up with parallel execution stacks, each of which having different thread information blocks (TIBs). And, while this library correctly initialized the TIB, in version 1.52 it didn’t bother replicating list of handlers from the original thread. Basically, it’s prev pointer was pointing somewere but definitely not where OS would expect it to point. It does not like it at all, and bang, your process is shot.

This SEHOP mechanism is explained in details on technet, and a lot of useful infomration about SEH could be found on microsoft website.

Apparently, a number of people implementing custom coroutine mechanism run into this issue before. Boost 1.53 has updated and fixed version of boost::context library that addresses exactly this problem.

BTW, SEHOP is included in Vista and Windows 7, is disabled by default, but can be enabled. List of known issues is quite impressive though:

After you enable SEHOP, existing versions of Cygwin, Skype, and Armadillo-protected applications may not work correctly.

(Русский) Программерское

(Русский) Шаблонная магия

(Русский) Это они серьезно?

Warning C4103 in Visual Studio 2010 is broken?

A few days ago my colleagues came across a very nasty bug caused by a header changing struct alignment (my apologies, this post is only available in Russian at the moment). In short, we were never supposed to have that problem in the first place as compiler should have given us a warning C4103.

But it didn’t. (Best said in Jeremy Clarkson voice).

Consider this header

// dummyHeader.h
#pragma  pack(push, 1)
			struct Dummy
			{
				int a;
				char b;
				short c;
			};
// oops, #pragma pack(pop) is missing..

The problem is fairly obvious – it changes struct alignment without restoring it back. Side effects of it include scary debug runtime check assertion, buffer overruns, sudden hard disk formatting and reactor core meltdowns.

Let’s include this header:

#include "DummyHeader.h"

#include "SomeOtherHeader.h"

And compile. As expected, compiler is not happy at all:

warning C4103: ‘test.cpp’ : alignment changed after including header, may be due to missing #pragma pack(pop)

Now, do the magic trick of changing the order in which headers are included

#include "SomeOtherHeader.h"
#include "DummyHeader.h"

Now it compiles without warnings.

I played with it for hours and could only get compiler to produce a warning when the offending header was on the top of the list.

I have only one thing to say – WTF?

P.S:
Microsoft Visual Studio 2010
Version 10.0.30319.1 RTMRel

P.P.S:
Visual Studio SP1Rel appears to be free of this problem

(Русский) Что pragma pack в себе таит

(Русский) В продолжение – universal references

0 visitors online now
0 guests, 0 bots, 0 members