| 39 | | Under construction! |
| | 53 | [http://msdn2.microsoft.com/en-us/vstudio/default.aspx Microsoft Visual Studio 2005] is the first of the Visual Studio versions to support user-customizable debugger visualizers. For CLR languages, such as C#, the possibilities are even more powerful, and documented. Native C++ debugger visualizers are not documented, though it was claimed by some people from Microsoft that some docs are coming - so if you know of some, please let us know! |
| | 54 | |
| | 55 | === Native C++ Debugger Visualizers for MSVS 2005 === |
| | 56 | |
| | 57 | The formatting rules are stored in the {{{autoexp.dat}}} text file (the {{{[Visualizer]}}} section) |
| | 58 | which can be found at |
| | 59 | {{{ |
| | 60 | Microsoft Visual Studio 8\Common7\Packages\Debugger\autoexp.dat |
| | 61 | }}} |
| | 62 | |
| | 63 | New visualizers can be installed by appending visualizer code to the {{{[Visualizer]}}} section. In the future, we would like to have an installer for this. |
| | 64 | |
| | 65 | ==== Existing visualizers ==== |
| | 66 | |
| | 67 | Visualizers for {{{boost::multi_index_container}}} stored at http://svn.boost.org/svn/boost/sandbox/boost_docs/sandbox |
| | 68 | |
| | 69 | Other existing visualizers will be added shortly. If you're lacking a visualizer for your favorite type, let us know or write one yourself - it's easy! |
| | 70 | |
| | 71 | === HOWTO === |
| | 72 | |
| | 73 | Our main source of knowledge is the [http://www.virtualdub.org/blog/pivot/entry.php?id=120 blog at virtualdub.org]. I'll try to repeat some of the basic info you need to get started. |
| | 74 | |
| | 75 | Visualizers (visualizer '''rules''') have this general format: |
| | 76 | |
| | 77 | {{{ |
| | 78 | ; Comments start with semicolon |
| | 79 | pattern [| pattern ...] { |
| | 80 | preview ( |
| | 81 | preview_expression |
| | 82 | ) |
| | 83 | stringview ( |
| | 84 | stringview_expression |
| | 85 | ) |
| | 86 | children ( |
| | 87 | children_expression |
| | 88 | ) |
| | 89 | } |
| | 90 | }}} |
| | 91 | |
| | 92 | The {{{stringview}}} section is used for formatting the data to text, HTML or XML |
| | 93 | (not covered by this guide yet). |
| | 94 | The {{{preview}}} section is used to format the data for one-line view. |
| | 95 | This is used in tooltips (when you hover over variables in code editor) and for the watch window. |
| | 96 | The {{{children}}} section enumerates child nodes (for structured types). |
| | 97 | All sections are optional. |
| | 98 | |
| | 99 | ==== Rule pattern matching ==== |
| | 100 | |
| | 101 | When visualizing a variable, the IDE looks at its (most derived) type. |
| | 102 | It then looks at all patterns in {{{autoexp.dat}}} and tries to find match. |
| | 103 | My guess is that it chooses the first rule that matches, but there should not be more than one |
| | 104 | matching rule anyway. |
| | 105 | |
| | 106 | Type names are processed as text. |
| | 107 | You can see the exact string that the visualizer sees in the watch window (the "Type" column). |
| | 108 | The bad thing about this is that extremely long type names are cut off at a certain string length. |
| | 109 | Such cropped strings then fail to match the visualizer patterns. |
| | 110 | |
| | 111 | Patterns can contain wildcards. |
| | 112 | (My guess is that the patterns are internally transformed to regular expressions by the IDE.) |
| | 113 | This is great for templates. A wildcard can match one or more template arguments: |
| | 114 | |
| | 115 | {{{ |
| | 116 | std::list<*> |
| | 117 | }}} |
| | 118 | |
| | 119 | and (preferred syntax) |
| | 120 | |
| | 121 | {{{ |
| | 122 | std::list<*,*> |
| | 123 | }}} |
| | 124 | |
| | 125 | will both match {{{std::list<int>}}} - because it is in fact {{{std::list<int,std::allocator<int> >}}}. |
| | 126 | |
| | 127 | As with marked subexpressions of regular expressions, we can access the actual text that matched the |
| | 128 | wildcards in the rule body's expressions. This text is referred to as {{{$T1, $T2, $T3}}} etc. |
| | 129 | As with shell variable expansion, the {{{$T}}}s are expanded in-place in the expression in which they appear. |
| | 130 | In case of {{{std::list<*>}}}, we have only one wildcard, |
| | 131 | and {{{$T1}}} will be expanded to {{{int,std::allocator<int>}}}. |
| | 132 | In case of {{{std::list<*,*>}}}, {{{$T1}}} expands to {{{int}}} and {{{$T2}}} |
| | 133 | expands to {{{std::allocator<int>}}}. |
| | 134 | This is more usable, because we can access the item type ({{{int}}}) in the expressions. |
| | 135 | |
| | 136 | ==== preview section ==== |
| | 137 | |
| | 138 | The {{{preview}}} expression produces a string that is used for one-line representation of the data |
| | 139 | in the tooltips and in the watch window. |
| | 140 | Usually, one wants to pick 2 or 3 important members out of the hundreds members of the class. |
| | 141 | |
| | 142 | The following code formats {{{std::list}}} preview: |
| | 143 | |
| | 144 | {{{ |
| | 145 | std::list<*,*>{ |
| | 146 | preview |
| | 147 | ( |
| | 148 | #("[list size=", $e._Mysize, "]") |
| | 149 | ) |
| | 150 | } |
| | 151 | }}} |
| | 152 | |
| | 153 | Note the use of the contatenation operator {{{#(s1, s2, ..., sn )}}}. |
| | 154 | {{{$e}}} refers to the value of the variable being visualized |
| | 155 | (we are accessing the {{{_Mysize}}} member of the {{{std::list}}} implementation). |
| | 156 | |
| | 157 | ==== children section ==== |
| | 158 | |
| | 159 | When the {{{children}}} section is present, a {{{[+]}}} will appear to the left of the visualized value |
| | 160 | and can be used to expand it (display the children). |
| | 161 | Multiple children can be added using the {{{#(c1, c2, ..., cn)}}} operator, |
| | 162 | and child values can have custom names (and will appear sorted by name): |
| | 163 | {{{ |
| | 164 | std::list<*,*>{ |
| | 165 | children |
| | 166 | ( |
| | 167 | #( |
| | 168 | first item: $e._Myhead->_Next->_Myval, |
| | 169 | second item: $e._Myhead->_Next->_Next->_Myval, |
| | 170 | [third item]: $e._Myhead->_Next->_Next->_Next->_Myval |
| | 171 | ) |
| | 172 | ) |
| | 173 | } |
| | 174 | }}} |
| | 175 | |
| | 176 | This is nice, but we need more to display real structures like lists, arrays and trees. |
| | 177 | There are special processors for these structures: |
| | 178 | |
| | 179 | ===== #list ===== |
| | 180 | |
| | 181 | {{{#list(head: head_expr size: size_expr next: next_expr) : deref_expr}}} is used to visualize a linked list of values. |
| | 182 | This can be used to visualize {{{std::list}}}: |
| | 183 | {{{ |
| | 184 | std::list<*,*>{ |
| | 185 | children |
| | 186 | ( |
| | 187 | #list(size: $c._Mysize, |
| | 188 | head: $c._Myhead->_Next, |
| | 189 | next: _Next |
| | 190 | ) : $e._Myval |
| | 191 | ) |
| | 192 | } |
| | 193 | }}} |
| | 194 | |
| | 195 | As you can see, we need to know the size of the list, where is the head node of the list, |
| | 196 | and how to get to a node's successor (this is done by accessing the {{{next}}} member of the current node). |
| | 197 | {{{$c}}} refers to the current expression, and in {{{deref_expr}}}, {{{$e}}} refers to the node being displayed. |
| | 198 | |
| | 199 | Alternative approach is {{{#list(head: head_expr skip: skip_expr next: next_expr) : deref_expr}}}. |
| | 200 | Here {{{skip_expr}}} defines node value (probably compared by memory address) which terminates the list traversal. |
| | 201 | Also, if a node is reached twice (cycle detection), it is not displayed and the traversal is stopped. |
| | 202 | |
| | 203 | ===== #array ===== |
| | 204 | |
| | 205 | {{{#array(expr: array_access_expr, size : size_expr) : deref_expr}}} is similar to {{{#list}}}, but the values |
| | 206 | are accessed by indexing the {{{array_head_expr}}} by indices {{{0, 1, ..., (size_expr-1)}}}. |
| | 207 | In {{{array_access_expr}}}, {{{$i}}} denotes the current index. |
| | 208 | |
| | 209 | There are optional parameters {{{rank}}} and {{{base}}}. |
| | 210 | {{{base}}} offsets the displayed indices of the array items (there must not be any {{{deref_expr}}} for this to work). |
| | 211 | {{{rank}}} can be used to display multidimensional arrays. In this case, {{{size}}} and {{{base}}} are evaluated |
| | 212 | repeatedly and {{{$r}}} in {{{rank_expr}}} and {{{base_expr}}} refers to the current rank being processed. |
| | 213 | |
| | 214 | ===== #tree ===== |
| | 215 | |
| | 216 | {{{#tree(head: head_expr size: size_expr left: left_expr right:right_expr skip: skip_expr) : deref_expr}}} is used |
| | 217 | to walk a binary tree. It is very similar to {{{#list}}}, the only difference being that the traversal is not linear |
| | 218 | but recursive depth-first. {{{skip_expr}}} is used to tell the shape of the tree (usually {{{skip: 0}}}). |
| | 219 | |
| | 220 | ===== conditionals ===== |
| | 221 | |
| | 222 | There is a {{{#if (expr) ( then_expr ) #else ( else_expr )}}} construct (with the ___else___ part optional) |
| | 223 | and a {{{#switch(switch_expr) #case case0_value ( case0_expr ) ... #default ( default_expr ) #except ( except_expr ) )}}} |
| | 224 | construct that can be used in the expressions. My guess (haven't tried) is that values matching {{{except_expr}}} |
| | 225 | are not passed to {{{#default}}}. |
| | 226 | |
| | 227 | === TODO === |
| | 228 | |
| | 229 | FAQ, examples, common pitfalls, ... |
| | 230 | |
| | 231 | ---- |
| | 232 | |
| | 233 | == gdb, ddd, others == |
| | 234 | |
| | 235 | If you are interested, please send an email to the |
| | 236 | [http://lists.boost.org/mailman/listinfo.cgi/boost-docs boost-docs list] |
| | 237 | telling us that you want to help. |
| | 238 | |
| | 239 | [[Image(CommonImages:help_wanted.png,nolink)]] |