Reputation: 7323
Using Windows CRITICAL_SECTION
, I can see the thread that locked it by expanding the variable:
However, I can't seem to do the same with std::mutex
, and get a lot of useless values instead:
Is there a way around it that doesn't require modifying my code?
Upvotes: 8
Views: 2861
Reputation: 21
Using visual studio 2019:
If you find yourself in a lockup using std::mutex. Show external code and go to... mtx_do_lock() in the call stack (probably 3 calls up from user code) and from here hover over mtx paramenter. This will show the owning thread id it is waiting for.
Upvotes: 0
Reputation: 7323
Thanks to @PeterT's comment, wrote a visualizer for various mutex types (place in /Documents/Visual Studio 2017/Visualizers/mutex.natvis):
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="std::_Mutex_base">
<Expand>
<Item Name="[thread_id]">*(long*)((char*)&_Mtx_storage+sizeof(_Mtx_storage)-8)</Item>
<Item Name="[count]">*(int*)((char*)&_Mtx_storage+sizeof(_Mtx_storage)-4)</Item>
</Expand>
</Type>
<Type Name="std::mutex">
<DisplayString>mutex</DisplayString>
<Expand>
<ExpandedItem>(_Mutex_base*)this</ExpandedItem>
</Expand>
</Type>
<Type Name="std::timed_mutex">
<DisplayString>timed_mutex</DisplayString>
<Expand>
<Item Name="[locked]">_My_locked</Item>
</Expand>
</Type>
<Type Name="std::recursive_mutex">
<DisplayString>recursive_mutex</DisplayString>
<Expand>
<ExpandedItem>(_Mutex_base*)this</ExpandedItem>
</Expand>
</Type>
<Type Name="std::recursive_timed_mutex">
<DisplayString>recursive_timed_mutex</DisplayString>
<Expand>
<Item Name="[locked]">_My_locked</Item>
<Item Name="[owner]">_My_owner</Item>
</Expand>
</Type>
</AutoVisualizer>
Upvotes: 13