 Coming up next, we have squash bugs and improved code quality with Leslie Richardson. We're very excited to toss it over to her. How are you doing, Leslie? I'm good. How are you? Fantastic. Take it away, my friend. Awesome. Well, as Seth just mentioned, I'm Leslie Richardson. I'm a program manager on the Visual Studio debugging and diagnostics team. And in this session, I'm going to show you how to squash bugs and improve your code quality with some of the brand new debugging features available for Visual Studio 2019. So let's start. So performance is always a big deal no matter what version of Visual Studio that you're using. And we've read through your feedback, we've listened to your feedback, we've implemented a lot of that feedback. And as we continue to do all three of those things with your feedback, here are some new debugger performance updates that we've made. First up, most Visual Studio Windows are now asynchronous. So for instance, if you're waiting for something to load in the watch window, then you should still be able to interact with the editor, the call stack, the immediate window, any of those windows that you've come to know and love in Visual Studio. Because most of these windows are now asynchronous, UI delays in those windows are down by more than 70% as a result. Stepping is now faster than ever with block time being down by more than half in comparison to what it was in 2017. And last but certainly not least, we've made symbols out of proc for C++. And what that means is if you are a C++ developer who tends to debug really big apps, say maybe a video game, then you should now be able to debug those applications without experiencing constant memory-related crashes and errors that you might have experienced previously. So to demo this, I actually have a video of Gears of War 4 and it's being debugged initially in Visual Studio 2017. So this is obviously a huge application to debug. It's a full-blown Xbox game, right? And you're probably thinking, well, that probably consumes a lot of memory while I'm debugging it. And sure enough, it does. If you were to open up your task manager and zoom in on the amount of memory that it consumes, it's a lot. It's nearly two gigs after just five minutes. So you can probably expect to see some lovely error messages regarding the fact that you're running out of memory. In contrast, if you debug that same application in Visual Studio 2019, you'll notice that the amount of memory being consumed is significantly lower than what it was in 2017, being at around 400 megabytes after five minutes. So that's a really big reduction in memory consumption. So if you are a C++ developer debugging those large applications and you're kind of on the fence as to whether or not you should make that leap from 2017 to 2019, then this should be a huge incentive for you because in some cases, you might actually be able to debug those applications for longer than just a few minutes. Or in some cases, just simply being able to use the debugger at all, which you might not have been able to do previously. So also new for C++ is a feature called just My Code. And this was something we introduced late into Visual Studio 2017. But this is a feature that when enabled will let you automatically step through code that's not yours. And that can mean anything from framework code to third-party library code, or maybe one of your teammates has pushed some code into the same repo as you and you're just not interested in debugging it because it's not relevant to you. So the GIF on the left illustrates just My Code when it's disabled. And as you can see, this user's stepping experience is not a good one because they got caught down that rabbit hole of having to step through a bunch of framework code in order to get back to the code that they actually care about. And in contrast, just My Code is enabled and the GIF on the right, which showcases a stepping experience that is a lot nicer. It's a lot more efficient because you're only able to step through the code that is yours. So it's also great because it minimizes the thinking overhead that you might have to do when you don't have just My Code enabled. So chances are you might have experienced that time where you're cautiously trying to step through code that's yours and you're worrying about, okay, well, if I step in here, does that mean I'm going to enter some weird framework code that I don't, that I could care less about? Or if I step out here, does that mean I'm going to miss out on something else? You no longer have to worry about those things when you have just My Code enabled. And if you wanted to take it a step further and actually pick and choose what gets considered by Visual Studio as non-user code, then you can edit the .NETJMC file that's available in Visual Studio, which will allow you to pick and choose which modules, files, and functions that Visual Studio deems non-user code. So enough of the slides. Now it's time for the fun part, which is demos. Now for the remainder of this session, I will be using Visual Studio 2019. And I'm also going to be using an ASP.NET core application. And it simply gives me a list of random books that I can choose to read. And if I choose to read the book, it should add the book to my shelf. And if I choose to not read the book, it won't add the book to my shelf. Or at least it's what it should do because right now I'm noticing that if I choose not to read the book, it's going to add it to my shelf anyway, which I don't want. So there's something going on. So my first theory is that there is something that is modifying my Sheld's books list. And this is the list that stores all the books that I want displayed on this particular page. So something is being added to it without my knowledge in a spot that I'm unaware of. So let's try to go into Visual Studio and try to figure out what the issue is. First thing I'm going to do is set a break point at the start of my application. And this will just hit after I refresh my application. And now I want to hone in on my Sheld's books list because I think that's where the problem lies. And that is an object that is listed under this Book Manager object, which I already have in the watch window here. And typically I could just expand this Book Manager object and then scroll down to find the item that I want. But instead, I'm going to use the brand new search tool that is available for the watch, locals, and autos windows, which is brand new for 2019. And search for it instead. So type in Sheld's books and hit Enter. And voila, I get what I'm looking for that much faster. So using search is super nifty, especially if maybe you have a list that's containing hundreds of items in the watch window. So instead of having to play the scrolling game and having to constantly expand each individual object till you find the one that you want, you can search for it instead, which should save you a lot of time. All right, so now that I've found this Sheld's books list, now what? In this case, I am interested in finding out when something is being added to that list. And to track that, I can use a new feature available for .NET Core called a data breakpoint. Now, if you're a C++ user, you might already be familiar with this because this is a feature that has existed with the C++ debugger for a while now. But data breakpoints are essentially breakpoints that will allow you to halt your code when a specific object's property changes in memory. So I'm going to use one of those in order to hopefully discover when this Sheld's books list is being updated. So to do that, I need to access its count property. And I'm going to use search again to find it because it's buried somewhere in that object, I'm sure. And I'm going to bump up my search depth to four so I can search a bit more thoroughly since the count property is nested somewhere inside Sheld's books. And now that I've found it, to set a data breakpoint, I can right click it, select break when value changes. And I'll know that a data breakpoint has been created because I get the standard breakpoint icon next to the property. I can also check on it in the breakpoints window just like any other breakpoint. And if I scroll up at the object containing that particular property, an object ID has also been created. And this is how visual studio will be able to keep track of what's going on with that object if it ever goes out of scope while my program's executing. So now that I've set the data breakpoint, I'm going to continue running my code and hopefully I'll get some more useful information the next time I perform that same action. So I'm going to choose not to read this book again. And this time I get a really nice notification telling me that my data breakpoint has been hit. And as an added bonus, it will tell me what the previous value of my count property was and what the new value is. So in this case, my list has increased from containing one item to two. And once I hit that data breakpoint, I will be redirected to the exact line in my code where that change occurred. In this case, my Sheld's books list is being added to under my add rejected book function, which is really weird because last time I checked, when I choose to reject a book or choose not to read a book, that book should be added to my rejected books list, not my Sheld's books one. So I might have just found my problem. So I'm going to stop debugging and change Sheld's books to rejected books. And that should fix the issue. But just to double check, I'm going to go ahead and run it again. Now currently, data breakpoints are only available for .NET Core 3.0 and higher. So if you're using .NET Core 2.1 or 2.2 or an earlier version, then you're going to need to make the leap up to 3.0 in order to try this feature, which is 3.0 is currently under preview. So definitely go give it a try. So hopefully this time, when I choose not to read the book, it won't be added to my shelf. And sure enough, that's exactly what happens. So that was data breakpoints for managed code, brand new for managed code. Super cool. I just used it in the instance where I wanted to find out when something was being added or removed from a list. But another way you can use it is maybe you have a global variable that's being accessed across multiple files and multiple functions. And if you wanted to find out where a particular change is happening, then you can simply use a data breakpoint to quickly locate where that's occurring, especially if you don't know the extent of all the things that are accessing that particular variable. You can also use it in the place of a normal breakpoint. Let's say you set a breakpoint on a property setter. So you can do that to kind of emulate the idea of a data breakpoint. But keep in mind that if you do that, you might have hundreds of objects that are accessing that property, which that property setter, which might result in you having to spam F5 or continue in order to continue running your code because that breakpoint gets hit so often. So if you feel like you can address that similar problem just by honing in on one specific object, then data breakpoints are the way to go. So now that I've finished debugging all this locally, everything checks out with this application. So I want to go ahead and deploy it and then put it in production. In this case, I've already done that and I've deployed the same application to an Azure VM that I have. Only this time I'm noticing that if I go to the page that is supposed to recommend lists of books to me, I get a lovely little book placeholder here with no title and no author and it doesn't sound like a very good read. So what's going on here? Because I'm pretty sure this worked perfectly fine when I was running this code locally. And this is a problem that you've most likely experienced if you've ever went and deployed an application and stuck it in production, right? Where your app is working perfectly fine as you run it locally, but then the moment you scale it or ship it for the world to see things are going wrong. Now the initial ways to try to solve or diagnose these problems might be to create a repro locally, but that could be tricky depending on the complexities of your application or maybe even just go into some logs or dump files in order to find the issue, but some of those logs might be insufficient. Maybe there's a specific piece of information that the logs just aren't giving you in order to solve your issue. So the next two features that I'm going to address to hopefully alleviate those problems are Visual Studio Enterprise Exclusive. So if you've decided that you're all in on everything Visual Studio has to offer and are an enterprise user, definitely try out these next two features because they're super useful. So in 2017, for Visual Studio 2017, we introduced the feature called the snapshot debugger. And this is a debugger that when you attach to it will allow you to debug your code while it's still running in production with minimal impact on the end user's experience. So I'm going to try to use the snapshot debugger in order to get to the bottom of this problem without having to halt my VM or anything like that. So to do that, I'm going to go up to debug in the toolbar here, locate, attach snapshot debugger. And then under Azure resource, I'm going to select the VM that is currently hosting my application. This is actually a new feature for a snapshot debugger for 2019 because in 2017, the snapshot debugger was only compatible with Azure app services. But now we've extended it out so that snapshot debugger is also compatible with Azure VMs and Azure Kubernetes for Linux Docker containers. So in this case, I'm going to be using a VM and I've selected my storage account that I want to use. And if you haven't remote debugged before, then you're going to need to install the remote debugger extension. Otherwise, you can skip that step. And I'm also going to check this feature called time travel debugging, which sounds pretty cool. It's got that time travel buzzword that I like. And normally, this would be the moment where I select attach, but because it might take a minute or two to initially attach this snapshot debugger, I actually have another instance of Visual Studio 2019 that's running the same code with the snapshot debugger already attached. And you'll know that you've attached successfully if you end up on this snapshot debugger landing page here. Okay, so let's get to the bottom of this problem. So I'm thinking that a placeholder book is being created right now because the JSON file, which stores the contents of all my book information at the moment, isn't being loaded correctly. So to test this theory, I'm going to set what's called a snap point instead of a break point at the line that loads up that file. And you'll notice that it's a hexagon instead of a circle and that it's hollow. And that's because I need to upload that info to the cloud, which I can do by selecting start collection. And as you can see, it's gone from being a hollow hexagon to a solid one. And what that's doing is I'm telling Azure, hey, the next time I interact with my application in a way that causes that snap point to trigger, and I want Visual Studio to take a picture or a snapshot of the state of my application at that particular line. And to trigger this one, all I really need to do is refresh my application. And this time we'll notice in the diagnostics tools window here, I got a snapshot that corresponds with the snap point that I set. And in order to further inspect all these variables and utilize some of the debugger functionality, I can select view snapshot here. So this might take a minute because we're still remote debugging, so I need to attach to several processes. But at the end of the day, the important thing is that the user can still interact with this application even if it, well, to some extent anyway, can still interact with the non-problematic parts of the application while it's, and be none the wiser about the fact that you're trying to diagnose some problems. Also, what's great about Snapshot Debugger is that it is supported for applications that might be widely distributed. Let's say you have an app that's working, that's running across multiple servers, then you should still be able to use the Snapshot Debugger without having to halt any of those servers in the process. And as you can see, my snap point has been hit as indicated by this pinkish execution pointer here. And you'll also notice that I can utilize the locals watch autos windows or any of the other debugging windows as if I were debugging the same application locally still. So in this case, if I went in on the autos window, I noticed that I have this absolute path variable here, which that doesn't sound good if it's what I think it is. And sure enough, if I check out the string that is stored here, it is in fact an absolute path that is being used to access my JSON file. So I don't want to be using this absolute path, which is obviously not going to be accessed since this app is currently being hosted on my VM instead of my local environment nowadays. So for future reference, I need to remember to change that to a relative path or store that info in a database somewhere for later. So what if I actually want to get some additional log information right off the bat that tells me that a placeholder was being created because that JSON file was being loaded incorrectly or just not being loaded at all. So to address that insufficient log problem, I can use what's called a log point instead of a simple snap point. These are kind of like trace points if you're familiar with those when debugging locally in that they allow you to print things to the output window or in this case application logs in the event or without having to modify any additional code. So to do that, I can set a snap point here, go to settings and then under actions and message, I'm going to just print out a simple message. In this case, I'll just say book not found placeholder created. We're going to hit enter and x out of that. And again, I need to update my collection to send that info up to the cloud again. And I can trigger that log point by refreshing my app. And this time you'll notice that in addition to the two snapshots that correspond to the two snap points that I created, I also get log point info which I can view in the diagnostics tools window that gives me the error message that I wanted it to print out a minute ago. Pretty sweet. So from there though, what if I actually wanted to be able to step through my code? What if there's a particular method that I wanted to view how it's being executed while running in production? So before 2019, the only way to really do this was kind of emulate it. And to do that, you'd have to set multiple snap points everywhere and then navigate back and forth between the snapshots that get created as a result and then inspect all of your variables that way. But that's obviously not very intuitive. It's not necessarily the most efficient way to go about it either. Like why can't we just step regularly, right? So for 2019, we've introduced this additional feature called the time travel debugger. And this is a tool that expands upon snapshot debugging by allowing you to step through your code. So let's try to use that on a method that I'm interested in. In this case, I want to hone in on my getBook placeholder function here because I'm curious to see how a book placeholder gets made. Now that I've gotten that, I can set a snap point at the start of this function. And hover over it and select settings again. We're going to go into actions. Minimize this a little bit so you can see it. All right. And then I'm going to check the option that says collect a time travel trace to the end of this method. So what this means is that when this particular snap point gets hit, it will record the entire execution flow of this method while in production. So now that I've updated the collection again, I can trigger it by refreshing the page. It might take a little longer to do that this time because we are recording this entire function this time. It's not just one line. And here's the snapshot that corresponds with the snap point here. And we're going to select use snapshot. Again, this might take a minute, but at the end of the day, much like snapshot debugger, user can still play around with the rest of the app while it's still running. So another thing to note about the time travel debugger is that it's still currently in preview mode. So that means you might experience some weird quirks here and there if you start to play around with it as of this particular point in time. But just know that we are working to further improve and update and expand upon it in later updates for 2019. Let's try and you can do it. All right. Well, it's taking a little longer than usual. So at the very least I can kind of describe what's going on with it. So think of it as being able to once you record your method, it's kind of like being given access to the remote control to your TV and then being able to fast forward or rewind or step by step check out and analyze each and every line of code that you have. And you can move, you can step forwards through it, you can step backward through it. If you're familiar with step back, if you're also an enterprise user, step back is another tool you can use and while debugging locally, for instance, it's kind of similar to that, but with a bit more control. All right. Well, because I'm running low on time, unfortunately, I might have to halt it here, but just know that again, this is a preview feature. It's really cool when it works. And definitely try giving it a try, but just know that we are going to improve it upon it in the near future. And for now that kind of concludes my talk on some of the brand new features available for Visual Studio 2019 in the debugging space. So definitely go down low 2019 and give it a try. And now we're going to open it up for questions. Fantastic. Thanks so much, Leslie. Debugging is hard. Luckily, when I write code, I never have to debug because it's always perfect. She's like, I don't even know you and that. We know that's not true. All right. Just a couple of questions that we have. Can the debug window show a list customer entity as a table visual? Oh, good question. So currently no, but that is something that we are considering in the near future. The closest we have is a data set visualizer, which is a class that you can use. And then you can use a visualizer similar to the ones that are listed here. Except instead of just getting a text string, you can view the whole table in a tabular format as if you were in Excel or something. That's cool. You can make your own visualizers too because I've made one one time and I showed something really cool. It was very exciting for just me because I was the only one there. So from Tijani, do we have access to the reading list demo app? Not at the moment, but I mean, I can provide access. I have it on a public get repo. So there you go. Fantastic. From Mike Simon, data break points and watch local search may be my favorite features of VS 2019. Can you go into the call stack from the break? Yes, you can. So if you end up, there might be cases where you set a data break point and it will immediately take you to just like the property setter, but that might not be entirely useful right off the back, right? You're most likely more interested in finding out what called that particular setter. So you can go into the call stack afterward and it'll redirect you to the place that called it. Fantastic. During debugging, when I have a list of objects, I want to find the object having the property x equals value y. Can I do that in VS 2019? Uh, wait, trying to think about it. Oh, I kind of like went away. Here we go. Let me bring it up. Yeah. When I have a list of objects, find the object having property x equals value y. Okay. So you want to be able to find a specific value that the property. Yeah. So if you use search, you can search for keywords across all three of those columns. So the name, value and type columns. So as of right now in the search, you can't use logic based strings like that. But at the very least, you can search for the property name or the value that you expect to see and find it that way. Fantastic. VS 2019, can you use the snapshot debugger with services running in AKS? Yes, you can. So as of 2019, we've expanded it out for Linux Docker containers in AKS currently. So any of the Linux types, Ubuntu, the other two that I'm blanking on at the moment, but you get the idea. So for Azure Kubernetes, it's for Linux containers currently. Fantastic. So I'm going through here to see if there's, oh, there's five new. If there's any new other questions, here we go. Will snapshot debugger and VS 2019 allow to inspect C++ release executable in debug mode? Currently, no. So snapshot debugger is only available for ASP.net and ASP.net core applications at the moment. Awesome. From Enrique, is this time travel debugger also for standalone applications? It's looked by your explanation. Looks like you already talked about for Azure deploy applications. Yeah. So as of right now, it's exclusive for applications that were pushed into the Azure space. So if you have your app running somewhere else, unfortunately, the snapshot debugger is not compatible currently. Awesome. And then we're going to finish up with this question. What about data breakpoints for Xamarin and other non.net core three project types? Yeah. So currently, that's something that we're still working on. I don't have a concrete answer on the Xamarin part. Very good question that I can definitely get back to you on. But for main.net core applications and ASP.net C sharp, that sort of thing, it should work fine. Awesome. Well, thanks so much for your time. This has been amazing. And what I want to do is I want to continue to shout out people that are this is from Germany that are watching in Germany.