I used the following test program (compiled with MSVC with /MD):
``` #include <windows.h> #include <stdio.h>
typedef void** (__cdecl *pcurrent_exception)(void);
int main() { HMODULE hvcr = LoadLibraryA("vcruntime140.dll"); HMODULE ucrtb = LoadLibraryA("ucrtbase.dll"); pcurrent_exception p__current_exception1, p__current_exception2;
p__current_exception1 = (pcurrent_exception)GetProcAddress(hvcr, "__current_exception"); p__current_exception2 = (pcurrent_exception)GetProcAddress(ucrtb, "__current_exception");
try { throw("ex1"); } catch (const char *s) { EXCEPTION_RECORD* rec1 = (EXCEPTION_RECORD *)*p__current_exception1(); EXCEPTION_RECORD* rec2 = (EXCEPTION_RECORD *)*p__current_exception2();
printf("Exception %s, rec1 %p (code %#lx), rec2 %p.\n", s, rec1, rec1->ExceptionCode, rec2); } } ``` This outputs the following on Windows: ``` Exception ex1, rec1 00000089CAF9F990 (code 0xe06d7363), rec2 0000000000000000. ```
So I think that confirms that: 1. vcruntime140 and ucrtbase have distinct local data (or at least current exception data) on Windows; 2. vcruntime140_1 links to vcruntime140. 3. msvcp140 should link to vcruntime140's exception data too as it is apparently able to get the correct current exception in ?__ExceptionPtrCurrentException@@YAXPEAX@Z.
These patches allow the current exception to be correctly located when there are mixed builtin and native VC runtime 140.