{"id":1693,"date":"2013-03-07T00:25:00","date_gmt":"2013-03-07T00:25:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2013\/03\/07\/guest-post-the-expression-evaluator\/"},"modified":"2021-09-29T16:33:59","modified_gmt":"2021-09-29T16:33:59","slug":"guest-post-the-expression-evaluator","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/guest-post-the-expression-evaluator\/","title":{"rendered":"Guest Post &#8211; The Expression Evaluator"},"content":{"rendered":"<p>Hi. My name is Ofek Shilon and <a href=\"http:\/\/www.thetweaker.wordpress.com\">I blog<\/a> mostly about various VC++ tricks I come by. Today I&rsquo;d like to explicitly introduce a debugging feature we all use daily but seldom refer to it by name &ndash; the native <em>expression evaluator<\/em> (abbreviated EE below).<\/p>\n<h2>The Basics<\/h2>\n<p>Every time you use the Watch window, a lot is going on behind the scenes. Whenever you type a variable name, something needs to map that name to the memory address and type of the named variable, then display that variable, properly formatted based on its type. Conversely, when you modify the contents of a variable &#8211; something needs to take your text input, convert it to the right type and correctly update the memory at the right address.<\/p>\n<p>That something is <em>the Expression Evaluator<\/em>. It is an impressive and often overlooked piece of technology and once familiar with it, you can put it to good use, sometimes in surprising ways!<\/p>\n<p>As the component name suggests, it is in fact able to parse and evaluate expressions:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/3157.watch1_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/3157.watch1_.png\" alt=\"Image 3157 watch1\" width=\"408\" height=\"239\" class=\"aligncenter size-full wp-image-28920\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/3157.watch1_.png 408w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/3157.watch1_-300x176.png 300w\" sizes=\"(max-width: 408px) 100vw, 408px\" \/><\/a><\/p>\n<p>These expressions can be assignment statements or can otherwise modify variables, too:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/3603.watch2_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/3603.watch2_.png\" alt=\"Image 3603 watch2\" width=\"402\" height=\"205\" class=\"aligncenter size-full wp-image-28922\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/3603.watch2_.png 402w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/3603.watch2_-300x153.png 300w\" sizes=\"(max-width: 402px) 100vw, 402px\" \/><\/a><\/p>\n<p>And more importantly &ndash; the expressions can include function calls!<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/4336.watch3_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/4336.watch3_.png\" alt=\"Image 4336 watch3\" width=\"415\" height=\"258\" class=\"aligncenter size-full wp-image-28924\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/4336.watch3_.png 415w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/4336.watch3_-300x187.png 300w\" sizes=\"(max-width: 415px) 100vw, 415px\" \/><\/a><\/p>\n<p>The EE lives in various IDE contexts&mdash;the Watch window, the QuickWatch dialog, the Immediate window, Breakpoint conditions and a bit more &ndash; but it is most obvious (and most frequently used) in the various Watch windows. When expertly used this feature can raise debugging interactivity to surprising levels, and in fact comes rather close to being a full C++ interpreted environment (especially alongside Edit and Continue). However, there are several important differences between expression evaluation and real code compilation that you should be aware of.<\/p>\n<h2>Calling functions<\/h2>\n<h3>What can and can&rsquo;t be called<\/h3>\n<p>The EE cannot call inlined functions, as they are not really &lsquo;there&rsquo; as code to be called.&nbsp; On the upside, the EE is blind to access privileges and would happily evaluate calls to private methods or file-static functions.<\/p>\n<h3>Side effects<\/h3>\n<p>The expressions are being evaluated at the context of the currently selected thread (that is, the one whose stack, registers and local variables are shown in the corresponding IDE windows). In particular, expressions are evaluated in the debuggee&rsquo;s address space, which could have unexpected consequences if one isn&rsquo;t careful. For example, suppose you&rsquo;re trying to evaluate an expression which allocates heap memory &ndash; but a different thread is frozen holding the heap lock. The debuggee would be left in an unknown state and the IDE should take measures against hanging by itself!&nbsp; Many similar scenarios might occur: since all debuggee threads are frozen various resources might be in unstable states and one should be careful when messing with them.&nbsp; That line of thought is probably what caused the EE designers to explicitly forbid usage of a large subset of CRT and WIN32 API. The full list of banned APIs is an implementation detail and is subject to change between versions or in updates (and was indeed expanded considerably in VS2010).<\/p>\n<p><em>However<\/em>,<\/p>\n<p>(1)&nbsp;&nbsp;&nbsp; In practice, side effects as described are extremely rare, and I&rsquo;ve been messing interactively with debuggee state for years with no problems.<\/p>\n<p>(2)&nbsp;&nbsp;&nbsp; The tests against this list are shallow, and you can easily bypass them by wrapping API in the list with your own functions (in advance, i.e. at the source itself):<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/5857.watch4_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/5857.watch4_.png\" alt=\"Image 5857 watch4\" width=\"484\" height=\"396\" class=\"aligncenter size-full wp-image-28925\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/5857.watch4_.png 484w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/5857.watch4_-300x245.png 300w\" sizes=\"(max-width: 484px) 100vw, 484px\" \/><\/a><\/p>\n<p>All that being said, such bypasses are undocumented and unsupported &ndash; <em>use them at your own risk!<\/em><\/p>\n<h2>The Context Operator<\/h2>\n<p>The EE does not include a full-fledged linker, and when you call functions outside the main executable the EE might require help in resolving the call. You can deliver that help with <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/y2t7ahxk.aspx#BKMK_Using_context_operators_to_specify_a_symbol\">the context operator<\/a><em>:<\/em><\/p>\n<p>{,,DllName.dll}FunctionName()<\/p>\n<p>(You can also omit the &lsquo;.dll&rsquo; in the module name. )<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7230.context.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7230.context.png\" alt=\"Image 7230 context\" width=\"449\" height=\"91\" class=\"aligncenter size-full wp-image-28928\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7230.context.png 449w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7230.context-300x61.png 300w\" sizes=\"(max-width: 449px) 100vw, 449px\" \/><\/a><\/p>\n<h2>Some Rough Edges<\/h2>\n<p>As useful as it is, the EE parsing and symbol resolution will probably never be as robust as the compiler&rsquo;s &ndash; and sometimes some workarounds are in order.<\/p>\n<p>Symbols sometimes need to be &lsquo;resolved manually&rsquo; by taking addresses and casting:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7522.context2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7522.context2.png\" alt=\"Image 7522 context2\" width=\"506\" height=\"281\" class=\"aligncenter size-full wp-image-28930\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7522.context2.png 506w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7522.context2-300x167.png 300w\" sizes=\"(max-width: 506px) 100vw, 506px\" \/><\/a><\/p>\n<p>Enum types are mostly recognized, but individual enumerators (enum values) are not. Implicit casting to an enum type can fail too. Luckily, you can easily cast the raw integral values yourself:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/6562.enum_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/6562.enum_.png\" alt=\"Image 6562 enum\" width=\"511\" height=\"264\" class=\"aligncenter size-full wp-image-28927\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/6562.enum_.png 511w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/6562.enum_-300x155.png 300w\" sizes=\"(max-width: 511px) 100vw, 511px\" \/><\/a><\/p>\n<p>If symbols reside in namespaces, they must be fully qualified. If functions are template, the template types must be fully (sometimes very verbosel<em>y)<\/em> specified.&nbsp; You may come across other similar behaviors. As a rule of thumb, when things aren&rsquo;t going as you expected &ndash; try to be as explicit as possible.<\/p>\n<h2>&nbsp;Applications<\/h2>\n<p>&nbsp;Finally, here are some examples of real life usage &ndash; specifically, enhanced investigation of memory issues in debug builds.<\/p>\n<p><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/e73x0s4b%28v=vs.110%29.aspx\">_CrtCheckMemory<\/a> essentially walks the CRT heap and detects out-of-bound writes by inspecting the padding that CRT inserts at the end of allocated blocks. Now you can pin-point the origin of corruptions without repeatedly spreading _CrtCheckMemory at the source and recompiling. Here&rsquo;s an evaluation right before a corruption:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/8715.mem1_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/8715.mem1_.png\" alt=\"Image 8715 mem1\" width=\"406\" height=\"247\" class=\"aligncenter size-full wp-image-28931\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/8715.mem1_.png 406w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/8715.mem1_-300x183.png 300w\" sizes=\"(max-width: 406px) 100vw, 406px\" \/><\/a><\/p>\n<p>And here it is again two lines later (after clicking refresh, to re-evaluate):<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/2117.mem2_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/2117.mem2_.png\" alt=\"Image 2117 mem2\" width=\"403\" height=\"241\" class=\"aligncenter size-full wp-image-28919\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/2117.mem2_.png 403w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/2117.mem2_-300x179.png 300w\" sizes=\"(max-width: 403px) 100vw, 403px\" \/><\/a><\/p>\n<p>If you define a _CrtMemState slot at the source, you can populate and inspect it interactively using the <a href=\"http:\/\/msdn.microsoft.com\/en-US\/library\/wc28wkas%28v=vs.100%29.aspx\">many tools the CRT supplies<\/a>. First fill it:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/4300.mem3_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/4300.mem3_.png\" alt=\"Image 4300 mem3\" width=\"464\" height=\"185\" class=\"aligncenter size-full wp-image-28923\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/4300.mem3_.png 464w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/4300.mem3_-300x120.png 300w\" sizes=\"(max-width: 464px) 100vw, 464px\" \/><\/a><\/p>\n<p>Then explore its contents &ndash; the CRT APIs ultimately call OutputDebugStringA , which still dumps to the output window:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7485.mem4_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7485.mem4_.png\" alt=\"Image 7485 mem4\" width=\"473\" height=\"330\" class=\"aligncenter size-full wp-image-28929\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7485.mem4_.png 473w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/7485.mem4_-300x209.png 300w\" sizes=\"(max-width: 473px) 100vw, 473px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/6471.mem5_.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/6471.mem5_.png\" alt=\"Image 6471 mem5\" width=\"475\" height=\"260\" class=\"aligncenter size-full wp-image-28926\" srcset=\"https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/6471.mem5_.png 475w, https:\/\/devblogs.microsoft.com\/cppblog\/wp-content\/uploads\/sites\/9\/2013\/03\/6471.mem5_-300x164.png 300w\" sizes=\"(max-width: 475px) 100vw, 475px\" \/><\/a><\/p>\n<p>You can also reserve several _CrtMemoryState&rsquo;s at the source, populate them at different locations and diff them with _CrtMemDifference. &nbsp;And so forth &#8211; you get the idea.<\/p>\n<h2>Bottom Line<\/h2>\n<p>Hopefully that&rsquo;s enough as an intro to this underappreciated debugging feature. I&rsquo;d love to hear (via the comments, <a href=\"http:\/\/www.thetweaker.wordpress.com\">my blog<\/a> or just ofekshilon-at-gmail) whether all this works out for you, and of other cool directions you&rsquo;re taking it to.<\/p>\n<p>My deep thanks goes to Eric Battalio and James McNellis, for making this post happen and then improving it.<\/p>\n<p>Cheers,<\/p>\n<p>-Ofek<\/p>\n<p><strong><em>Thanks for the great article, Ofek.&nbsp;Readers, if you have an idea for an article that might appeal to&nbsp;the&nbsp;Visual C++ \/ C++ community, ping me @ <a href=\"mailto:ebattali@microsoft.com\">ebattali@microsoft.com<\/a>. I encourage you to&nbsp;ping me even if you think you&nbsp;can&#8217;t write, the topic might&nbsp;not fit, or&nbsp;you have any other reservations! \ud83d\ude42&nbsp;<\/em><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi. My name is Ofek Shilon and I blog mostly about various VC++ tricks I come by. Today I&rsquo;d like to explicitly introduce a debugging feature we all use daily but seldom refer to it by name &ndash; the native expression evaluator (abbreviated EE below). The Basics Every time you use the Watch window, a [&hellip;]<\/p>\n","protected":false},"author":281,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[55,36],"class_list":["post-1693","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-debugging","tag-vc"],"acf":[],"blog_post_summary":"<p>Hi. My name is Ofek Shilon and I blog mostly about various VC++ tricks I come by. Today I&rsquo;d like to explicitly introduce a debugging feature we all use daily but seldom refer to it by name &ndash; the native expression evaluator (abbreviated EE below). The Basics Every time you use the Watch window, a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/1693","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/281"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=1693"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/1693\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=1693"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=1693"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=1693"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}