{"id":20931,"date":"2018-09-26T07:00:43","date_gmt":"2018-09-26T07:00:43","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/vcblog\/?p=20931"},"modified":"2019-02-18T17:47:40","modified_gmt":"2019-02-18T17:47:40","slug":"step-back-going-back-in-c-time","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/step-back-going-back-in-c-time\/","title":{"rendered":"Step Back &#8211; Going Back in C++ Time"},"content":{"rendered":"<h2><strong>Step Back for C++<\/strong><\/h2>\n<p>In the most recent, 15.9, update to Visual Studio 2017 Enterprise Edition, we\u2019ve added \u201cStep Back\u201d for C++ developers targeting Windows 10 Anniversary Update (1607) and later. With this feature, you can now return to a previous state while debugging without having to restart the entire process. It\u2019s installed as part of the C++ workload but set to \u201coff\u201d by default. To enable it, go to Tools -&gt; Options -&gt; IntelliTrace and select the \u201cIntelliTrace snapshots\u201d option. This will enable snapshots for both Managed and Native code.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/IntelliTraceOptions2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/IntelliTraceOptions2.png\" alt=\"\" width=\"654\" height=\"506\" class=\"aligncenter wp-image-21075 size-full\" \/><\/a><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/IntelliTraceOptions.png\"><\/a><\/p>\n<p>Once \u201cStep Back\u201d is enabled, you will see snapshots appear in the Events tab of the Diagnostic Tools Window when you are stepping through C++ code.\n<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/StepBackSnapshotsTaken.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/StepBackSnapshotsTaken.png\" alt=\"\" width=\"480\" height=\"322\" class=\"aligncenter wp-image-21035 size-full\" \/><\/a>\nClicking on any event will take you back to its respective snapshot \u2013 which is a much more productive way to go back in time if you want to go further back than a few steps. Or, you can simply use the Step Backward button on the debug command bar to go back in time. You can see \u201cStep Back\u201d in action in concurrence with \u201cStep Over\u201d in the gif below.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/StepBack.gif\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/StepBack.gif\" alt=\"\" width=\"296\" height=\"292\" class=\"aligncenter wp-image-21015 size-full\" \/><\/a><\/p>\n<h3>Under the Hood<\/h3>\n<p>So far, we\u2019ve talked about \u201cStep Back\u201d and how you can enable and use it in Visual Studio, but you could have read that on the <a target=\"_blank\" href=\"https:\/\/devblogs.microsoft.com\/visualstudio\/\" rel=\"noopener\">VS blog<\/a>. Here on the VC++ blog, I thought it would be interesting to explain how the feature works and what the trade offs are. After all, no software, debuggers included, are magical!<\/p>\n<p>At the core of \u201cStep Back\u201d is an API in Windows called <em>PssCaptureSnapshot<\/em> (<a target=\"_blank\" href=\"https:\/\/docs.microsoft.com\/en-us\/previous-versions\/windows\/desktop\/api\/processsnapshot\/nf-processsnapshot-psscapturesnapshot\" rel=\"noopener\">docs<\/a>). While the API isn\u2019t very descriptive, there are two key things that it does to a process. Given a target process it will:<\/p>\n<ol>\n<li>Create a \u2018snapshot\u2019 which looks suspiciously like the child process of an existing process that has no threads running.<\/li>\n<li>Mark the processes memory, it\u2019s page tables (<a target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Page_table\" rel=\"noopener\">Wikipedia<\/a>), as copy-on-write (<a target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Copy-on-write\" rel=\"noopener\">Wikipedia<\/a>). That means that whenever a table is written to, the table is copied.<\/li>\n<\/ol>\n<p>The important thing about the above is that between the two you basically get a copy of the entire virtual memory space used by the process that you snapshotted. From inside that process you can then inspect the state, the memory, of the application as it was at the time the snapshot was created. This is handy for the feature which the API was originally designed for; the serialization of a process at the point of failure .<\/p>\n<p>In VS when debugging C++, we take these snapshots on certain debugger events, namely:<\/p>\n<ol>\n<li>When a breakpoint is hit<\/li>\n<li>When a step event occurs \u2013 but only if the time between the stepping action and the previous stepping action is above a certain threshold (around ~300ms). This helps with the case where you are hammering the stepping buttons and just want to step at all possible speed.<\/li>\n<\/ol>\n<p>From a practical perspective, that means there will be a snapshot as you step through code. We keep a First in First Out buffer of snapshots, freeing them up as more are taken. One of the downsides of this approach, is that we aren\u2019t taking snapshots as your app is running so you can\u2019t hit a breakpoint and then go back to see what happened before the breakpoint was hit.<\/p>\n<p>Now there is a copy of the process, a snapshot, but how does that get debugged in VS?<\/p>\n<p>Well, this is the \u2018easy\u2019 bit, basically when you hit \u201cStep Back\u201d or activate a snapshot from the Diagnostic Tools window, VS goes ahead and attaches the debugger to that process. We hide this from you in the VS UI, so it still looks like you are debugging the process you started with, but in reality, you are debugging the snapshot process with all the state from the past. Once you go back to \u2018live\u2019 debugging you will back to the main process which is still paused at the location you left it.<\/p>\n<h3>Performance of Step Back<\/h3>\n<p>One of the first considerations of adding any new feature to the debugger is on how it might impact the performance of VS while debugging. While improving performance of VS is something of a Sisyphean task and as many improvements as we make there is more to be made as well as additional features that take some of those wins. Taking a snapshot takes time, everything does, in this case it takes time both in the process being debugged and back in VS. There\u2019s no sure way to predict how long it will take as it\u2019s dependent on the app and how it\u2019s using memory, but while we don\u2019t have a magic 8 ball, we do have data, lots of it\u2026<\/p>\n<p>As of the time of writing, from testing and dogfooding usage in the last 28 days use we\u2019ve seen 29,635,121 snapshots taken across 14,738 machines. From that data set we can see that the 75th percentile for how long it took to take a snapshot is 81ms. You can see a more detailed breakdown in the graph below.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/StepBackTimeTaken.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/StepBackTimeTaken.png\" alt=\"\" width=\"624\" height=\"269\" class=\"aligncenter wp-image-21045 size-full\" \/><\/a>\nIn any case, if you were wondering why \u201cStep Back\u201d isn\u2019t on by default, that graph above is why, \u201cStep Back\u201d simply impacts stepping performance too much to be on by default, all the time, for everyone. Instead, it\u2019s a tool that you should decide to use and, by and large, you\u2019ll likely never notice the impact. Though, if you did we will turn off \u201cStep Back\u201d and show a \u2018gold bar\u2019 notification that we\u2019ve done so. The \u2018gold bars\u2019 are the notifications that pop at the top of the editor, the picture below shows the one for when you try \u201cStep Back\u201d without snapshots being enabled.<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/StepBackGoldBar.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/9\/2019\/02\/StepBackGoldBar.png\" alt=\"\" width=\"624\" height=\"139\" class=\"aligncenter wp-image-21025 size-full\" \/><\/a>\nThat\u2019s the CPU usage aspect of performance out the way, now to look at the second aspect, memory.<\/p>\n<p>As you continue to debug your app and the app continues execution it will no doubt write to memory. This could be to set a value from 1 to 2 as in the example above. Or it could be something more complex, but in any case, when it comes time to write that change the OS is going to copy the associated page table to a new location. Duplicating the data that was changed, and potential other data, at the new location, while keeping the old. That new location will continue to be used. That means that the old location still has the old value, 1, from the time the snapshot was taken, and the new location has the value of 2. As Windows is now copying memory as it\u2019s written, the app will consume more memory. How much though depends on the application and what it\u2019s doing. The consumption of memory is directly proportional to how volatile it is. For example, in the trivial app above each step is going to consume a tiny bit more data. But, if the app instead were encoding an image or doing something intense a lot more memory would get consumed than would be typical.<\/p>\n<p>Now as memory, even virtual, is finite this poses some limitations on step back. Namely that we can\u2019t keep an infinite number of snapshots around. At some point we have to free them and their associated memory up. We do that in two ways; firstly, the snapshots are let go on a First in First out basis once a limit of a 100 has been reached. That is, you can never step back more than a 100x. That cap is arbitrary though, a magic number. There\u2019s an additional cap that\u2019s enforced and based on heuristics, essentially VS is watching memory usage and in the event of low memory snapshots get dropped starting with the oldest \u2013 just as if a 100 was hit.<\/p>\n<h3>Conclusion<\/h3>\n<p>We\u2019ve covered how you can use \u201cStep Back\u201d and how it works under the hood and hopefully you are now in a place to make an informed decision on when to use the feature. While this feature is only in the Enterprise versions of Visual Studio you can always try out the <a target=\"_blank\" href=\"https:\/\/visualstudio.microsoft.com\/vs\/preview\/\" rel=\"noopener\">preview channel<\/a> of Visual Studio Enterprise. I highly recommend you go turn it on, for me, personally it\u2019s saved a whole bunch of time not restarting a debug session. And when you do use the feature I\u2019d love to hear your feedback, and as ever if you have any feedback on the debugger experience in VS let us know!<\/p>\n<ul>\n<li>Developer Community: <a target=\"_blank\" href=\"https:\/\/developercommunity.visualstudio.com\/\" rel=\"noopener\">https:\/\/developercommunity.visualstudio.com\/<\/a> <a target=\"_blank\" href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/talk-to-us?view=vs-2017\" rel=\"noopener\"><\/a><\/li>\n<li><a target=\"_blank\" href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/talk-to-us?view=vs-2017\" rel=\"noopener\">https:\/\/docs.microsoft.com\/en-us\/visualstudio\/ide\/talk-to-us?view=vs-2017<\/a><\/li>\n<\/ul>\n<p>You can also reach me by mail at <a href=\"mailto:andster@microsoft.com\">andster@microsoft.com<\/a>)or on twitter at<a target=\"_blank\" href=\"https:\/\/twitter.com\/andysterland\" rel=\"noopener\"> https:\/\/twitter.com\/andysterland<\/a>.<\/p>\n<p>Thanks for reading!<\/p>\n<p>Andy Sterland<\/p>\n<p>Program Manager, Visual Studio, Diagnostics Team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Step Back for C++ In the most recent, 15.9, update to Visual Studio 2017 Enterprise Edition, we\u2019ve added \u201cStep Back\u201d for C++ developers targeting Windows 10 Anniversary Update (1607) and later. With this feature, you can now return to a previous state while debugging without having to restart the entire process. It\u2019s installed as part [&hellip;]<\/p>\n","protected":false},"author":7412,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[270,239,230],"tags":[],"class_list":["post-20931","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcement","category-diagnostics","category-new-feature"],"acf":[],"blog_post_summary":"<p>Step Back for C++ In the most recent, 15.9, update to Visual Studio 2017 Enterprise Edition, we\u2019ve added \u201cStep Back\u201d for C++ developers targeting Windows 10 Anniversary Update (1607) and later. With this feature, you can now return to a previous state while debugging without having to restart the entire process. It\u2019s installed as part [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/20931","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\/7412"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=20931"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/20931\/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=20931"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=20931"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=20931"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}