natvis visualizers do not follow typedefs on Linux
Djoulihen opened this issue · 14 comments
Hi
First of all thanks for implementing natvis visualization even with GDB, that is a very useful feature.
One pretty limiting shortcoming I found is that the visualization gets broken on Linux when the type of the variable is hidden behind a typedef. An example:
std::vector<int> myVec1(5);
typedef std::vector<int> MyVectorType;
MyVectorType myVec2(10);
Using this natvis declaration:
<Type Name="std::vector<*>">
<DisplayString>{{ size={_M_impl._M_finish - _M_impl._M_start} }}</DisplayString>
<Expand>
<Item Name="[size]" >_M_impl._M_finish - _M_impl._M_start</Item>
<ArrayItems>
<Size>_M_impl._M_finish - _M_impl._M_start</Size>
<ValuePointer>_M_impl._M_start</ValuePointer>
</ArrayItems>
</Expand>
</Type>
In this case myVec1 will have its display string as { size=5 } while myVec2 will just have {...}. As it would be a cumbersome to add a new declaration in the natvis for every local typedef that could be used, it would be very useful if the visualizer could find the real type behind the typedef and match it, as Visual Studio does.
Thanks,
Julien
@Djoulihen Thank you for reporting this. The natvis implementation inside the extension is a subset of Visual Studio, but that being said, we will investigate.
The code for our implementation lives here: https://github.com/Microsoft/MIEngine/tree/master/src/MIDebugEngine/Natvis.Impl
std::vector may sound insignificant but this is a much bigger problem when it comes to std::string as visualizer type is defined as basic_string<*>.
- when working with a remote ssh session, the natvis visualization is very slow. That is why it is disabled by default - but, that being said, is there room for improvement?
- are there plans to implement showing the return value of the last function(s) that was/were exited on the stack - I find that feature in Visual Studio Debugger extremely useful.
@ferdinandhelmer My assumption is the size of the data set and then the transformation it goes through. We request the data from gdb through the MI protocol and then based on formatting will need to request additional data for each item. If you enable engineLogging and step for a frame that uses natvis, you can see the amount of data we have to request to get it to be displayed.
Implementation: https://github.com/microsoft/MIEngine/tree/master/src/MIDebugEngine/Natvis.Impl
For the request of showing the return value of the last function, I suspect we would need gdb to have that functionality. It works in the Visual Studio debugger because we also own the debugger and have implemented that.
For the request of showing the return value of the last function, I suspect we would need
gdbto have that functionality. It works in the Visual Studio debugger because we also own the debugger and have implemented that.
Return value is covered by #3214.
Regarding gdb, looks like you could instead of stepping over the function step into it and the execute finish:
https://stackoverflow.com/questions/267674/how-to-inspect-the-return-value-of-a-function-in-gdb
std::vectormay sound insignificant but this is a much bigger problem when it comes tostd::stringas visualizer type is defined asbasic_string<*>.
That's an easy one and already handled in the official natvis:
<Type Name="std::string">
<AlternativeType Name="std::basic_string<char,*,*>" />It is much worse that template code and thus in particular STL is riddled with member typedefs. This is severe!
For example I wrote this for std::optional:
<Type Name="std::optional<*>">
<DisplayString Condition="!_M_payload._M_engaged">nullopt</DisplayString>
<DisplayString Condition="_M_payload._M_engaged">{_M_payload._M_payload}</DisplayString>
<Expand>
<Item Condition="_M_payload._M_engaged" Name="value">($T1)_M_payload._M_payload</Item>
</Expand>
</Type>Without the ($T1) value gets a type like _Optional_payload::ResultType (which is a typedef of course) and when expanding the value node all the nested visualizations will fail!
This issue has been closed automatically because it has not had recent activity.
Seems that issue still present in C/C++ version 1.5.0-insiders.
See the linked MIEngine issue. There's simply no easy way to get the base type from gdb.
This issue is still present 1.61.2
This issue has been closed automatically because it has not had recent activity.
No recent activity does not mean the bug is magically gone.
@awulkiew see the MIEngine ticket. ptype output is hard to parse.
Real issue is here microsoft/MIEngine#1026