This is much slower on Linux than Windows. By adding QueryPerformanceCounter calls, I found that the difference is that stack walk is 23x on Linux than Windows (160.5 ms vs. 6.8 ms per walk).
More instrumentation would be needed to diagnose exactly what part of stack walk is slow, but here where the CPU is active in this scenario:
NOTE: This is an inverted call stack that originally had mangled symbol names. I partially unmangled the names by hand.
libvsdebugeng.so!dispatcher::DkmThread::GetTopStackWalkFrame(DkmRuntimeInstance, DkmStackWalkFrame)
libvsdebugeng.impl.so!MonitorStackMerge::CMergeObj::GetTopStackWalkFrame(DkmThread, DkmRuntimeInstance, CallStack::DkmStackWalkFrame)
libvsdebugeng.impl.so!Common::GetRegistersForThread(DkmThread, DkmRuntimeInstance, DkmFrameRegisters)
libvsdebugeng.impl.so!Common::GetTopStackPointerForThread(DkmThread)
libvsdebugeng.impl.so!Microsoft::VisualStudio::Debugger::DkmThread::GetContext()
libvsdebugeng.so!Proc6C71BAFC0CA8B6BB34725A9DB87FBDAC
libvsdebugeng.so!dispatcher::DkmThread::GetContext()
libvsdebugeng.impl.so!ManagedDM::CV2EntryPoint::GetContext(DkmThread)
libmscordbi.so!CordbThread::GetRegisterSet(ICorDebugRegisterSet)
libmscordbi.so!ShimProcess::LookupOrCreateShimStackWalk(ICorDebugThread)
libmscordbi.so!ShimStackWalk::ShimProcess(CorDebugThread)
libmscordbi.so!ShimStackWalk::Populate()
libmscordbi.so!CordbThread::CreateStackWalk(ICorDebugStackWalk)
libmscordbi.so!CordbStackWalk::Init()
libmscordaccore.so!DacDbiInterfaceImpl::CreateStackWalk(VMPTR_BaseI6Thread6__VPtrIS1_EEP10DT_CONTEXTPPP)
libmscordaccore.so!DacDbiInterfaceImp::SetStackWalkCurrentContext(VMPTR_BaseI6Thread6__VPtrIS1_EEPPv22CorDebugSetContextFlagP10DT_CONTEXT)
libmscordaccore.so!StackFrameIterator::ResetRegDisp(REGDISPLAY)
libmscordaccore.so!EECodeManager::EnsureCallerContextIsValid(PREGDISPLAY, StackwalkCacheEntry pCacheEntry, EECodeInfo * pCodeInfo)
libmscordaccore.so!Thread::VirtualUnwindCallFram(CONTEXTP30_KNONVOLATILE_CONTEXT_POINTERSP10EECodeInfo)
libmscordaccore.so!DacUnwindStackFrame(T_CONTEXTP30_KNONVOLATILE_CONTEXT_POINTERS
libmscordaccore.so!StackUnwinderAMD6413VirtualUnwindEjmmP29_IMAGE_RUNTIME_FUNCTION_ENTRYP8_CONTEXTPPvPmP30_KNONVOLATILE_CONTEXT_POINTERSPPFiP17_EXCEPTION_RECORDmS3_S4_E
libmscordaccore.so!DacReplacePatchesInHostMemory
libmscordaccore.so!CHashTable13FindNextEntryEP8HASHFIND
libmscordaccore.so!DacInstantiateTypeByAddressHelpermjbb
libmscordbi.so!ShimRemoteDataTarget11ReadVirtualEmPhjPj
libmscordbi.so!DbgTransportSession10ReadMemoryEPhS0_m
libmscordbi.so!DbgTransportSession25SendRequestMessageAndWaitEPNS_7MessageE
```C#
using System;
using System.Diagnostics;
namespace HitCountBpTest22
{
class Program
{
static void Main(string[] args)
{
int ms = HitCountFunc();
Console.WriteLine("HitCountFunc executed in {0} milliseconds.", ms);
}
static int HitCountFunc()
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int x = 0; x < 90; x++)
{
Nop(x); // Set breakpoint here with condition 'x == 100'
}
sw.Stop();
return (int)sw.ElapsedMilliseconds;
}
static void Nop(int x)
{
}
}
}
```
same problem on mac, it's obnoxious
We would really love to get this fixed in 3.0 to improve the debugger experience in Visual Studio for Mac.
cc @unniravindranathan
@mikem8361 since this is the DAC stack walking, could you please take a look? Possibly a debugger transport performance issue?
Juan (@hoyosjs) is going to take a look.
What version of the runtime is this being reported on?
I tried both 2.2 and 3.0
Linux portion of issue fixed on dotnet/coreclr#24844
Most helpful comment
We would really love to get this fixed in 3.0 to improve the debugger experience in Visual Studio for Mac.
cc @unniravindranathan