Subject: [Boost-bugs] [Boost C++ Libraries] #8544: Calling managed DLL from within boost::context may cause a crash
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-05-03 00:50:53
#8544: Calling managed DLL from within boost::context may cause a crash
-------------------------------------+--------------------------------------
Reporter: vitaly.blinov@⦠| Owner: olli
Type: Bugs | Status: new
Milestone: To Be Determined | Component: context
Version: Boost 1.53.0 | Severity: Problem
Keywords: context, coroutine |
-------------------------------------+--------------------------------------
Only Windows platform is affected.
If the code running in the context (coroutine) invokes anything that
involves crossing clr.dll (mscorwks.dll) boundary, a crash occurs with
about 50% probability.
My investigation showed that call stack of the problem is consistent with
clr.dll!Thread::InitThread throwing OutOfMemory exception. With some deep
debugging I narrowed the problem down to CommitThreadStack function inside
the clr.dll. That method accesses a dword located at FS:[0xE0C] (this is
called "deallocaton stack" on
[http://en.wikipedia.org/wiki/Win32_Thread_Information_Block TIB wiki
page]) and compares it with current top of the stack (FS:[0x4]). It
appears that exception is thrown if FS:[0xE0C] value is greater than
FS:[0x4] (or, perhaps, FS:[0x8]).
That variable is not very well documented, but I believe the pair
FS:[0xE0C] - FS:[0x4] defines the maximum stack size. On windows 7, the
difference between these is always 0x100000, which gives stack size of 1M.
Interestingly, that always the case even if the fiber or thread were
created with smaller stack size.
jump_context never touches that variable. As a result, the value in
FS:[0xE0C] is defined by the calling thread, and therefore it contains
arbitrary value. If it is greater than current top of stack, problem
occurs.
clr.dll!CommitThreadStack also appears to be accessing FS:[0xF78], but
it's purpose and whether the value stored in it affects the behavior is
unknown.
My current workaround of writing current bottom of the stack to FS:[0xE0C]
prior to calling managed DLL appears to be working:
(MS VS specific)
{{{#!cpp
DWORD store = __readfsdword(0xE0C);
__writefsdword(0xE0C, __readfsdword(0x8));
call_managed_dll();
__writefsdword(0xE0C, store);
}}}
This bug is very obscure and so far I only managed to observe it on
Windows7 and Windows server 2008.
Suggested fix: Store and restore FS:[0xE0C] in jump_context.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/8544> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:13 UTC