EDIT: Nevermind, I found the problem. It seems that std::wcout uses quite a bit of stack space. I had the native stack too small, so once I increased the size to 16K or larger, the problem went away. I was initially keeping the stack size smaller because I thought the few calls I was making just didn't use that much space. What is weird is that I'm sure I increased the size of the stack to something like 512K at some point but I also found another bug in a vector class I was using, so maybe I didn't realize that the corrupted memory at that time was really caused by the vector class.
OK I finally was able to get back to the heap corruption issue. In order to really test context switching, I needed to implement threading, which required me to implement delegates (including MultiCastDelegates while I was at it), and also TimeSpan and DateTime. Quite a tangent.
Anyway, so I was testing the StartMainThread call as shown a few messages above. I tried many different things, including giving NativeStack its own block of memory, but that block of memory is always corrupted. I carefully looked at the end of the block of memory (where the new thread will push and pop values), and indeed it pushes them within the boundary of the allocated block of memory (going downwards as expected).
The corrupted memory is always the size of the allocated block of memory plus 0x40. It is as if the stack switching code is doing something with the end of the block of memory. I even tried allocating a huge block of memory, and then setting the NativeStack to the middle of this block of memory - it still ends up corrupting the end of the block of memory. It is as if it known where the boundaries of the allocated block of memory is and then mucks around at 0x40 bytes past the end of it.
I confirmed that other code that allocates different blocks of memory aren't corrupting those blocks by allocating large dummy blocks inbetween those allocation calls so that the used blocks are not next to each other - it always comes back to the NativeStack block of memory as the one being corrupted.
Any ideas what could be going on here?