mibTarget process crashes in coreclr.dll!ClassLoader::LoadTypeHandleForTypeKey_Body resulting in the following message from VS:
---------------------------
Microsoft Visual Studio
---------------------------
The target process exited with code -2146233082 while evaluating the function 'System.SpanDebugView
If the problem happens regularly, consider disabling the Tools->Options setting "Debugging->General->Enable property evaluation and other implicit function calls" or debugging the cause by evaluating the expression from the Immediate window. See help for information on doing this.
---------------------------
OK Help
---------------------------
coreclr.dll!ClassLoader::LoadTypeHandleForTypeKey_Body(TypeKey * pTypeKey, TypeHandle typeHnd, ClassLoadLevel targetLevel) Line 3778
at f:\workspace.1_work\1\ssrc\vm\clsload.cpp(3778)
coreclr.dll!ClassLoader::LoadTypeHandleForTypeKey(TypeKey * pTypeKey, TypeHandle typeHnd, ClassLoadLevel targetLevel, const InstantiationContext * pInstContext) Line 3677
at f:\workspace.1_work\1\ssrc\vm\clsload.cpp(3677)
coreclr.dll!ClassLoader::LoadTypeDefThrowing(Module * pModule, unsigned int typeDef, ClassLoader::NotFoundAction fNotFoundAction, ClassLoader::PermitUninstantiatedFlag fUninstantiated, unsigned int tokenNotToLoad, ClassLoadLevel level, Instantiation * pTargetInstantiation) Line 2565
at f:\workspace.1_work\1\ssrc\vm\clsload.cpp(2565)
coreclr.dll!ClassLoader::LoadTypeDefOrRefThrowing(Module * pModule, unsigned int typeDefOrRef, ClassLoader::NotFoundAction fNotFoundAction, ClassLoader::PermitUninstantiatedFlag fUninstantiated, unsigned int tokenNotToLoad, ClassLoadLevel level) Line 2737
at f:\workspace.1_work\1\ssrc\vm\clsload.cpp(2737)
coreclr.dll!EEDbgInterfaceImpl::LoadClass(Module * pModule, unsigned int classToken) Line 951
at f:\workspace.1_work\1\ssrc\vm\eedbginterfaceimpl.cpp(951)
coreclr.dll!EEDbgInterfaceImpl::LoadMethodDef(Module * pModule, unsigned int methodDef, unsigned long numGenericArgs, TypeHandle * pGenericArgs, TypeHandle * pOwnerType) Line 803
at f:\workspace.1_work\1\ssrc\vm\eedbginterfaceimpl.cpp(803)
coreclr.dll!ResolveFuncEvalGenericArgInfo(DebuggerEval * pDE) Line 1550
at f:\workspace.1_work\1\ssrc\debug\ee\funceval.cpp(1550)
coreclr.dll!DoNormalFuncEval(DebuggerEval * pDE, unsigned char * pCatcherStackAddr, Object * * pObjectRefArray, void * * pMaybeInteriorPtrArray, void * * pByRefMaybeInteriorPtrArray, __int64 * pBufferForArgsArray, ValueClassInfo * * ppProtectedValueClasses) Line 3087
at f:\workspace.1_work\1\ssrc\debug\ee\funceval.cpp(3087)
coreclr.dll!GCProtectArgsAndDoNormalFuncEval(DebuggerEval * pDE, unsigned char * pCatcherStackAddr) Line 3441
at f:\workspace.1_work\1\ssrc\debug\ee\funceval.cpp(3441)
coreclr.dll!FuncEvalHijackRealWorker(DebuggerEval * pDE, Thread * pFEFrame, FuncEvalFrame *) Line 3659
at f:\workspace.1_work\1\ssrc\debug\ee\funceval.cpp(3659)
coreclr.dll!FuncEvalHijackWorker(DebuggerEval * pDE) Line 3782
at f:\workspace.1_work\1\ssrc\debug\ee\funceval.cpp(3782)
coreclr.dll!FuncEvalHijack() Line 27
at F:\workspace.1_work\1\ssrc\debug\eeamd64\dbghelpers.asm(27)
Span<char>.```C#
static void Main(string[] args)
{
Span
mib[0] = 42;
Console.WriteLine("Hello World {0}!", mib[0]);
}
### Disassembly
Span<int> mib = stackalloc int[3];
00007FFEF90D0FD9 lea rcx,[rbp+28h]
00007FFEF90D0FDD mov edx,0Ch
00007FFEF90D0FE2 mov edx,edx
00007FFEF90D0FE4 test rdx,rdx
00007FFEF90D0FE7 je 00007FFEF90D1007
00007FFEF90D0FE9 add rdx,0Fh
00007FFEF90D0FED shr rdx,4
00007FFEF90D0FF1 add rsp,20h
00007FFEF90D0FF5 push 0
* 00007FFEF90D0FF7 push 0 // crash when evaluate from here
00007FFEF90D0FF9 dec rdx
00007FFEF90D0FFC jne 00007FFEF90D0FF5
00007FFEF90D0FFE sub rsp,20h
00007FFEF90D1002 lea rdx,[rsp+20h]
00007FFEF90D1007 mov r8d,3
00007FFEF90D100D call 00007FFEF90D0730
00007FFEF90D1012 vmovdqu xmm0,xmmword ptr [rbp+28h]
00007FFEF90D1017 vmovdqu xmmword ptr [rbp+38h],xmm0
00007FFEF90D101C vmovdqu xmm0,xmmword ptr [rbp+38h]
00007FFEF90D1021 vmovdqu xmmword ptr [rbp+48h],xmm0
```
CC @tommcdon
@sdmaclea @hoyosjs
There are several issues here.
mib. This is same issue as dotnet/runtime#9245.Only the last one might be interesting enough to include in 3.0 or backport.
This was what I found and it was reported in a similar situation by @davidfowl
One thought - in testing I didn't see any issues if I evaluated the Span through interpretation rather than func eval. Did I just get lucky, or are the the inspection APIs better at handling this partially constructed state? Also, I saw that the Length was zero. Is that also something that can be counted on?
If this is something we can count on, here is one idea for a trivial short term 'fix' -- change the DebuggerDisplay for Span to [DebuggerDisplay("{ToString(),nse}")]
This does not look like it will make 3.0. Moving to 5.0. If fix is trivial will consider backport for 3.0-preview9 if approved.
@davidfowl Unfortunately I didn't see your response till now. Looking back, I agree with you. Deferring this was a mistake. This create a bad debug experience.
I must have also missed @gregg-miskelly's comment too. Because I don't remember seeing it.
trivial short term 'fix' -- change the DebuggerDisplay for Span to [DebuggerDisplay("{ToString(),nse}")]
I just tried the proposed fix. It still crashed the process on VS Code while stepping.
The target process exited with code 0 while evaluating the function
'System.SpanDebugView<T>.SpanDebugView'.
The program '[23947] corerun' has exited with code 0 (0x0).
hmm... I am not sure why that didn't convince the debugger that it should interpret Span.ToString. Maybe ,nse doesn't work in DebuggerDisplay? At any rate, if we do think that is a useful approach, I can open a work item to investigate a possible VS work around.
@gregg-miskelly It did stop the eval of the ToString(), but it did still crash. I think it was probably
[DebuggerTypeProxy(typeof(SpanDebugView<>))]
triggering a call to the SpanDebugView<> constructor, which evals the incomplete object.
Good point. Yes, that must take precedence.
I now understand root cause. And some of the wierd behaviors.
Because of dotnet/runtime#9245 the stack pointer is sometimes unaligned while single stepping. The various ABIs require SP alignment on call boundaries. When we do a FuncEval to evaluate of the Span<T>, we hijack the thread and then call functions. This triggers an alignment exception on memory operations which require a specific pointer alignment.
We need to align the SP when we hijack the thread.
Most helpful comment
I now understand root cause. And some of the wierd behaviors.
Because of dotnet/runtime#9245 the stack pointer is sometimes unaligned while single stepping. The various ABIs require SP alignment on call boundaries. When we do a
FuncEvalto evaluate of theSpan<T>, we hijack the thread and then call functions. This triggers an alignment exception on memory operations which require a specific pointer alignment.We need to align the SP when we hijack the thread.