Getting started with VisualGDB Type Visualizers
Type visualizers are a powerful mechanism allowing you to display the variable values during debugging in a more user-friendly way than simply listing all members. This is extremely useful if your program contains custom STL-like containers or string classes.
This tutorial shows the very basics of making a simple type visualizer and registering it with VisualGDB. It will simply make VisualGDB show "Hello, Visual Studio" instead of the actual value for a given C++ class.
- Create a simple "Hello, World" application with VisualGDB. Although the type visualizers will work for all projects types, the most simple way to start is by creating a MinGW application (follow this tutorial).
- Replace the contents of the main C++ file with the
following:#include <stdio.h>
template <class _Type> class VeryBasicArray
{
private:
size_t m_Count;
_Type *m_pData;
};
int main()
{
VeryBasicArray<int> test;
return 0;
} - Place a breakpoint at the "return 0" line and start debugging. When the breakpoint is hit, hover the mouse over "test" to see its value:
- We will now make a VisualGDB plugin that will replace the value of test ("m_Count = 68, m_pData = ...") with a custom string. Please refer to the SDK reference for more information about things that type visualizers can change.
- Start Visual Studio as Administrator so that it can write to the VisualGDB installation directory inside Program Files. Go to FIle->New Project and select C# -> Class Library:
- Right-click on the newly created project, select "Add Reference". Select "Browse" and point to the VisualGDBExpressions.dll assembly inside the VisualGDB directory.
- Right-click on the project and select "Properties". Go to the Debug tab, select "Start External Program" and specify the path to your Visual Studio's devenv.exe:
- Go to the Build Events page and specify the following
post-build command line:
copy /y $(TargetPath) "C:\Program Files (x86)\Sysprogs\VisualGDB\TypeVisualizersEnsure that the VisualGDB installation directory is specified correctly. - Add a file called MyBasicFilter.cs with
the following contents:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VisualGDBExpressions;
namespace MyTypeVisualizer
{
class MyBasicFilter : TypeListBasedExpressionFilter
{
public MyBasicFilter()
: base("VeryBasicArray<")
{
}
protected override IExpression DoAttach(
IExpression expr,
IExpressionEvaluator evaluator)
{
return new StaticExpressionFilter(expr)
{
ValueOverride = new ExpressionValue.Custom(
"Hello, Visual Studio")
};
}
}
}
- Add a file called Factory.cs with the
following contents:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VisualGDBExpressions;
namespace MyTypeVisualizer
{
public class MyFilterFactory : IExpressionFilterFactory
{
public IEnumerable<ExpressionFilterRecord>
CreateExpressionFilters()
{
return new ExpressionFilterRecord[]
{
new MyBasicFilter().Record
};
}
}
}
- Build the project. Ensure that your DLL has been copied to the TypeVisualizers directory inside the VisualGDB directory (the directory should already contain STLTypeVisualizer.dll).
- Start debugging your project. Another instance of Visual Studio will be executed. Open your VisualGDB-based project using that Visual Studio. Put a breakpoint on the return statement and run the project.
- Hover the mouse over "test" to see the modified value:
- Go back to the outer Visual Studio instance, set a
breakpoint inside the DoAttach() function, go back to the
inner Visual Studio and hover the mouse over test
again. A breakpoint will be triggered.
Do not evaluate the IExpression members in the outer Visual Studio. This would require a cross-thread call that cannot be performed while your plugin is stopped at a breakpoint. - Use edit-and-continue to copy the value of expr.Type into a temporary variable. Run the newly created statement using the "Set next statement" and "Step" commands:
Now we are ready to make a meaningful expression visualizer. Follow the next tutorial to make this visualizer display array contents in a structured way.
The explanation
This section explains how the basic visualizer implemented above works.
When we inherited the TypeListBasedExpressionFilter class and specified "VeryBasicArray<" in the constructor, we have created a simple filter that only attaches itself to instances of the VeryBasicArray class.
The DoAttach() method essentially allows replacing an expression (the original value) with another arbitrary expression returned by the method. However, instead of implementing the IExpression interface manually we have used the StaticExpressionFilter class to make a clone of the original expression replacing the value with our string (represented as an instance of ExpressionValue.Custom).
Source code
You can download the source code for the example in this tutorial here. The code in the archive is provided under the BSD license.