Tips and Tricks for .NET Debugging in Visual Studio

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody welcome back to the virtual net conference of 2019 my name is Leslie Richardson I am a program manager on the visual studio debugging and diagnostics team and in this session I'm gonna teach you some tips and tricks for dotnet debugging and visual studio so debugging can be really tough and really frustrating chances are you spent a lot of time debugging issues in your code and you just want to get back to coding as usual right so hopefully some of the tools that I showcased today will help you out and make your experience a more efficient and fun one there's a lot of ground to cover today and very little time to do so so we're just gonna jump right into demos so for this session I'm gonna be using the latest version of Visual Studio 2019 and I'm using an asp.net core 3.0 application that will randomly take in a list of books that I can either choose to read and add to my shelf or choose to reject and they won't be added to my shelf I love to read so this applications right up my alley the problem is there's a lot of issues going wrong with it and I want to use some of the tools in Visual Studio in order to figure them out so I already have a breakpoint set at the end of this book manager constructor and this is a constructor that's taking in a JSON file with all my relevant book information converts each of those into a book object and then stores each of those book objects into a list called books so books is the first variable that I would like to inspect so I'm going to hover over books here pull up its data tip which I'm going to go ahead and pin because I'm gonna be using this more than once now when I expand this out initially it's not very useful if I wanted to identify each book by its title for instance I could do that but I would have to expand each and every one of these out which can be really annoying and tedious I have a hundred books in this list in particular so that can take some time this also goes if I were looking at the same view and the locals are Otto's windows so as an alternative c-sharp has an attribute that I can use called debugger display and this is an attribute that will allow me to customize how I view my objects in the watch Otto's locals and data tip windows so to use it I have to stop debugging go to where I defined my book class and at the top of that class definition I'm gonna add some debugger display syntax and the brackets will return the value of whatever variable that I specify in this case I want to identify each book by its title property so I'm gonna type in title and continue debugging here so technically you can perform the same behavior by simply overriding your to string method but if you want to have that separation between the strings that you're viewing while you're diagnosing your code versus the strings that to string is displaying in your actual application then using debugger display might be the better option you know wait for it to load and for those of you wondering this is a feature that has been in Visual Studio for a very long time as well as just G sharp in general so this is not an exclusive tool that you should definitely check out because here's the final product I'm stopped at my breakpoint again and this time when I expand my data tip I get a lot more helpful information so as you can see I can now quickly identify each book based off of their title and this goes for if I were looking at that and the locals window or the watch window or autos as well so it's one of my personal favorite attributes and hidden features in Visual Studio but there's a couple cons with this number one you have to modify your code in order to use it which depending on your project or depending on who you are if this may not matter but if it does matter then that can definitely be a problem number two you have to stop debugging in order to use it so if you didn't plan ahead when defining your class from the get-go upon and you want to use debugger display later you're gonna have to stop what you're doing and then add in this code and then number three and most importantly it's not the most discoverable thing to begin with so you need to either know this feature or you don't and you need to be familiar with the syntax in order to use it so based off of all those cons and after listening to a lot of your feedback and your reactions to when I've discussed this feature in the past we are currently working on a brand new feature that can perform the same behavior that can hopefully make the experience a lot better that you can now get a sneak peek of right now so in this version of the experience you can perform that same behavior that debugger display does except you can do it in the locals autos or watch Windows so for instance if you wanted to favorite a particular property say the language property as displayed here you can click on this pin icon that will display or you can right-click on a context menu option and then when you click the pin you'll get that same behavior where that property will show up under your vial you call them in any of those windows so this is really great because one you don't need to modify your code to use it you can perform this behavior while still in debugging mode number two you can you don't need to stop debugging in order to run it and number three hopefully it's a lot more discoverable at the end of the day if you play around with locals autos and watch Windows a lot chances are you'll have this pin pop up just at will and you can say hey what's that maybe I should check it out and that should help alleviate some of those issues all right so now that I have gotten my ideal debugging environment set up in the format debugger display I'm gonna hit f5 to continue running this code and try to identify some of the other issues that I'm having so as I mentioned before this is an asp.net core 3.0 application that will randomly give me a list of books that I can either choose to read or not read in this case I'm gonna say that I want to read this book called sentimental education which sounds riveting I'm sure it's a fascinating read I have no idea what's about but you know I'm game and I click on it and the first issue that I'm having has to do with this read one time string here so this is a value that's supposed to increment every time I say that I finished the book because any time I read a book that I like chances are I'm going to read it multiple times at first glance I'm already getting the red flag of it telling me that I've read it already even though I just added it to my shelf but I'm gonna click that I finished this book anyway and when I go back to it I expect it to say that I've now read it twice but now it's telling me that I've read it four times so I either read this book three more times within the past five seconds and was slightly not conscious or there's something going on in my code that's causing a property to be modified without my knowledge so it's probably the latter so let's check out Visual Studio to figure this out so I don't need this breakpoint anymore but I do need to set a breakpoint at the end of my index function here and this correlates with my home page so I just need to restart the page in order to hit it and from there I want to hone in on that particular book and just to get a sense of what's going on and try to solve this problem so normally this would be the time where I can expand out this myshelf variable and locate the book that way but another and faster way that I can use that's new to 2019 is the new search feature for the locals autos and watch feat locals autos and watch windows so I'm gonna type in education there you go and as you can see I'm immediately directed to the place where I want to go which can save me some time this is especially useful if you have hundreds of items that you're looking at at any given point in time or you have a list containing lots of different items and you don't want to have to go through the trouble of expanding each one of these out so from there I'm actually interested in looking at this objects times red property and this is the property that's supposed to increment every time that I say that I finished the book so I'm gonna search for that again and as you can see I'm taken to where I need to be now at this point I want to locate where this times red property is being changed and the problem with that is I don't really know where that change could be coming from because I wasn't expecting it so normally I could just set a regular breakpoint on this property setter but I don't necessarily want to do that because that might mean that I could have hundreds of my object of my book objects access accessing that particular setter at a given point which can make my debugging experience a little noisy so instead I can use a new break point available for dotnet core 3.0 called a data breakpoint and this is a breakpoint that will allow me to halt my code on a specific objects property whenever it changes even if my even if that property goes out of scope so I'm going to use that in order to determine where that change could be coming from so to use the data breakpoint I can right-click on the property and then select break one value changes and I know the data breakpoints been created because I get the standard breakpoint icon next to the property I can also view it and the breakpoints window right here and if I scroll up a little bit you'll notice that there's an object ID the dollar sign one here that has been added and this is how Visual Studio will be able to keep track of what this object is doing if it ever goes out of scope while my codes running so now that I've set that data breakpoint I'm gonna hit continue on my code and hopefully the next time I perform an action that triggers that data breakpoint I'll get some more useful info so I'm gonna click on the book again and right off the bat I get a data breakpoint notification that's telling me that it was hit so as an added bonus it'll tell me what the previous value of that property was as well as what the new value is in this case times red has been incremented from four to five and I'll be redirected to the exact line of code where that change came from so in this case it's happening in my property setter which makes total sense but I'm more interested in determining what lasts called that property setter so I'm gonna go into my call stack window and then select the frame right below the one that I'm currently at and then I'm taken to the line of code that last called that property setter so in this case times red is being incremented under my get shelves book method which I don't want because I already have times red being incremented somewhere else so I'm gonna comment this out and that should solve the problem and we're gonna restart so data breakpoints are super cool they were originally a C++ exclusive but as of 2019 we've added them for dotnet core 3.0 or higher and since 3.0 is finally out of preview mode there's no excuse you should definitely go try out data breakpoints if you're curious yeah so it's really cool all right I'm gonna comment I don't need that breakpoint anymore so we're gonna keep running now I'm gonna perform that same behavior again so I'm gonna select this book called the recognition of check kuntala forgive my pronunciation we're gonna click on it and say that I finished the book and then go back and as expected it now says that I've read the book time so those data breakpoints and search for the watch window both are 2019 exclusives super cool data breakpoints you can use for several cases in this case I used it because I realized I could solve my problem by just honing in on a specific object you can also use it if you have like a global variable that's being accessed across multiple files and multiple methods and you you can also use it if maybe you've just inherited your co-workers code and you're unfamiliar with the code base but there's something going on in it that's causing the property to change in a spot that you're unaware of so you can use a data breakpoint to determine where that location is even if you're unfamiliar with the code alright so the next problem that I want to look at has to do with the line directly below where it says read one time so I like to read a lot of books at the same time and as a result I can finish several books in the same day so this just getting the date is not specific enough for me I want to know what time I finished each book so I would like to add time to this string so let's go into Visual Studio and try to break down that string in order to determine where I need to put that so I'm gonna set a breakpoint at this line that corresponds to that particular string display and I can just refresh now looking at this right off the bat there is a lot going on here I've got several function calls including a nested one here I've got this time finished action it's kind of a lot so I'd like to break this down into smaller chunks in order to understand what's going on and to ultimately pinpoint where I need to change my code to add time related info so the first thing I'd like to do is step into the string function but given the standard stepping options that I have step into step over and step out I can't really do that because it's nested and as an aside you'll probably notice that over where you're stepping icons usually are in the toolbar the icons have changed as a 16-3 and that's because we heard all of your feedback about how the previous icons in 2720 19 were not very readable and I was one of those people personally so we reverted the icons back to what they were in 2017 too that that legibility experienced a bit better so anyway I would like to step into this two string function here and so in order to do that I can use a tool called step into specific and this performs a step into except I can pick and choose which functions I would like to go into first so to do that I can right click on this line and then go to step into specific then I'll get a drop-down containing all the different functions that I can choose to step into so in this case I'm gonna go to person dot two string and just like I was performed as if I were performing a normal step into I'm taken to this function and this one's pretty basic I'm just passing in my name and then it's being returned so I'm gonna step through it and step right back out no problem so from there I want to go into the finish two string method which is this outer function call so I can you step into specific again to go into there and Here I am at finished shoestring so now I want to look at this string that's being concatenated and normally this might be where I need to stop debugging and create an arbitrary variable that's equal to this value because I currently don't have one and at first glance it's kind of hard to see what the final value that's being returned is as just given this current view but if you go into the autos locals or watch Windows I'm going to show you the autos and locals first and step to the end of your function you'll notice that at the top here there's a little return keyword that appears and so by default the autos and locals windows will automatically give you what your return value is when you reach the end of a function which is very helpful and requires you to not have to make variables that you don't want you can also view the same return value in the watch window by typing dollar sign return value and you'll get that same deal so the perk about using in the watch window is that you can also add these things called format specifiers to this value and these are little keywords that you can add that lets you further customize how you're viewing these variables and your watch window so to do that you can add a comma and in 2019 you can get a nifty drop-down that tells you all the different format specifiers that you can use so if you're unfamiliar with format specifier then have no fear because this drop-down is here and in this case for instance if I wanted to remove the quotation marks around the string then I can go to NQ which says string with no quotes and I can select that one and I mean there's a bunch of different ones so you can use NSC which stands for no side-effect so if you don't want to see any side-effects and some of the variables that you're evaluating in the watch window you can use that or if you want to see a decimal value that's converted into a hex you can use comma H to do that and so on and so forth so definitely go try those out they're really fun to play around with right so from there I now want to go into this finish book string but the problem is I'm now currently at the end of this function so I'm thinking I might have to stop debugging and then create a new session which is not fun and you know run my code all the way back up to this line again but instead I can use something else called set to next statement and this is a tool that will let me pick the next line of code that I want executed so to use that I can just drag my execution arrow here up to the line that I want to run next so this is really great if you need to just quickly go back and reenact something small in your code but you kind of have to use this at your own risk because depending on what your code is this you're not you're not actually rewinding back in your code instead you're Reax acute Anor you have the potential to reiax acute things that have already been running so depending on what your code is this could easily create some side-effects that you don't want to see in your codes execution that may result in you having to restart the session entirely which is not great but for here is totally fine and from there I'm gonna step in right here so I'm at my finished book string method and now I'm gonna step to the very end of this function and as you can see with return value I'm getting the return value of my function which is also very nice and from there I'm noticing I have this too short date string function call and I think that's what's causing the time to be omitted so if I get rid of that then time should be displayed the next time i refresh now at this point I just modified my code so now would be the time to start a new debugging session but actually I can use the new the existing feature called edit and continue which will allow me to continue running my code because Visual Studio will actually recompile the changes that I just made it in my code so that I don't need to stop debugging so this only works for certain scenarios but it's really cool when it works and speaking of that we've gotten a lot of your feedback previously about edit and continue not working working when it actually should be working so as of 16/3 we've made a lot of improvements and changes to the tooling and that that will allow you to use edit and continue a lot more successfully so if you've been burned by edit and continue in the past definitely tried to give it another chance and let us know your feedback about the the update so from there I'm gonna refresh this page and I don't need this breakpoint anymore so hit f5 and as you can see the time is now being displayed as I expected it to so that's super cool lots of different features that I just mentioned they're set to next statements that step into specific return value format specifiers lots of cool things that you can play around with there now from there I've actually gone and updated my code I heard about that cool thing called asynchronous programming which I hear is all the rage so I wanted to try it out so I've created a new branch called async and I've just modified some of my existing methods to make them asynchronous but while I was making all those changes I accidentally created some bugs that have been resulting in exceptions being thrown in my code so let's take a look at some of those and how we can better diagnose those those kinds of issues all right so back at my same application so got the books I'm gonna choose to read this book it's got a weird name that I've never heard of right and let's say that I finished it and go back and yay we get that lovely browser error that you've probably seen before if you've ever run an asp.net application it's telling me that an unhandled exception occurred so this isn't super useful because in my past experience whenever I get an error such as like an ol reference exception I will automatically be redirected to visual studio and get like a nice exception helper notification telling me where that exception was being thrown from and I'm not getting it here so there's a couple ways that I can get that exception to appear the first one is by using the Diagnostics tools window for those of you who don't know what that is it's that tool it's that window that you probably found yourself closing and in the past from time to time I know I am also guilty of this but it actually has some cool perks to it if we open it up alright so here's the Diagnostics tools window and I'm gonna expand this up a little bit and I'm interested in this events tab here so this is where Visual Studio is logging all major events that are going on as my code is being run and then I can go back and check out any of these which is great so I'm gonna filter this down to just my exceptions and you'll notice that there's one here that has a red diamond icon with a smaller camera icon here it might be kind of hard to see but it's there so what's cool about this is that when my exception gets thrown Visual Studio will take a snapshot or save the state of my application at that given point in time so that I can then go back and examine this exception further up the exact moment that it happened so I can double click on this and I'll be taken to the line where is thrown and I'll also get the notification telling me that I mean that I'm now in historical debugging and because this was an exception that was thrown in the past so that's super cool if you're an enterprise user then this is the way to go so if you're not an enterprise user what do I do well the other option that you can use is the exception settings window and in this window you can perform an action called break one thrown so in this case I had an exception that was a runtime error so I'm gonna check all common language runtime exceptions and what I did there is I'm telling Visual Studio to stop my code the next time that a runtime exception occurs and it's automatically going to break my code at that given point so to demo that I can hit continue and I'll just refresh the page and as I expected the first time round I now get that helpful exception helper that gives me more information about that exception and also just to talk about what Diagnostics tools window works great it swells because I just threw another exception there and you'll notice another exception appeared under the events so it's cool I can go back and forth between any of those instances where those exceptions were thrown so both of these options are really great for any kinds of exceptions that you see the caveat the caveat for exception settings is that because I checked all runtime exceptions I can expect to see a notification anytime any runtime exception occurs which you may not want that could happen pretty frequently depending on what the issue in your code is so if you're more familiar with the specific exceptions that you're having issue with then it's better to narrow it down and just check the ones the specific exceptions that you want to have your code break at so all both of these are also great for your asynchronous code as well because while asynchronous code can be cool and while dotnet and c-sharp make it easy to incorporate in your current code using the async and pass keywords it also adds an additional layer of complexity to your code that maybe you didn't want so in this case Visual Studio was handling all those exceptions and time and as a result I wasn't able to get this exception helper initially so speaking of improving the async experience for debugging another tool that we've been working to improve as of 16/3 is the parallel stacks tool for tasks window so I have a gif of it running here but in the new version I can visually inspect all the different tasks that I have both awaiting and active and I can view their corresponding call stacks as well so this is great if you want a visual representation of what's going on in your in your async code and trying to understand you know what actions are happening what particular order alright so I have two more features that I want to quickly go through the first is source link which we've added to 2019 and this is a tool that when enabled will allow you to hook up or sync up your your dll's or binaries no matter where they came from to your source code so if you've wanted to debug a new get package or anything like that that's currently published out and github or get lab or anything like that then you can enable source link in order to do that and last but not least my team has made an extension called the child process debugging power tool so if you've ever needed to debug processes that are being called by a parent of some kind then check out this exception that's available for not just 2019 but pretty much every version of Visual Studio up to 2013 super cool my team gives it the seal of approval because we made it so go check it out and last but not least if you want to experiment more and want to play around with the code that I was using in today's session I have the links available for the master branch and the async version of that code as well and from there I hope you all learn something new and now I'll open it up to questions
Info
Channel: Microsoft Visual Studio
Views: 27,148
Rating: undefined out of 5
Keywords: Visual Studio, .NET, dotNET, dotNET Core, .NET Core, dotNETConf
Id: lgKInHJ-tcg
Channel Id: undefined
Length: 26min 27sec (1587 seconds)
Published: Mon Sep 23 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.