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)]] |