¶How to fix debugger visualizers for VS2005 SP1 and VS2008
If you've written a bunch of custom visualizers for the Visual Studio debugger, you may have run into the problem lately of the preview() section of your visualizer causing the debugger to hang or crash, or simply displaying ... when used in nested visualizers. I tracked this down to a change that was snuck into VS2005 SP1 and which is also in VS2008 beta 2. It used to be the case that $c (container) and $e (element) were equivalent in the preview() block. This is no longer the case -- $c instead refers to the top level container. This means that you can run into problems if you have a nested setup like this:
A { preview($c.m) } B { preview($c.m) }
Formerly, this would work fine with an object of type B which derives from A. In VS2005 SP1 / VS2008b2, this causes the debugger to crash, because instead of evaluating B::m and then A::m, it evaluates B::m over and over and then blows up. In visualizers where the fields of the nested type don't alias with the type that started the evaluation, you'll see ... instead as that's the debugger's way of signifying evaluation error.
In the cases that I've seen, replacing $c with $e within preview() fixes the problem.
I also have some additional tips that I've learned since writing the original blog entry:
- You can avoid bumping the indices of the auto-numbered elements by surrounding named elements in #(), which will push them after the auto-numbered ones:
MyVector { children( #( #array(expr: $c.s[$i], size: $c.len), #(raw: [$c,!]) ) ) }
This can also be used as a dirty way to force w to the end of the variable list for a 4-vector that has x, y, z, and w components, which would ordinarily be sorted alphabetically.
(Although this bug still exists in VS2005 SP1, it appears to be fixed in VS2008 beta 2 — the indices start at [0] regardless.) - The expression parser is whitespace sensitive when parsing template type expressions, so you should mimic the debugger exactly. Generally, this means the unusual style of placing a space before the comma separating template elements and not after, i.e.: mytype<$T1 ,$T2>.
- The "b" at the end of a debugger format tag means "bare" and is useful for displaying a value without adornment like quotes and 0x prefixes. It's used in the existing visualizers for strings (foo,sub), but you can also use it for integers: value,xb
- If you use #array() within a preview block, the debugger will automatically insert commas between each element.