Debugging Tips and Tricks Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
>> If your code is perfect and there's nothing wrong with it, don't watch this episode of Visual Studio Toolbox where Leslie Richardson will show us debugger tips and tricks. >> I envy that person. [MUSIC] >> Hi, welcome to Visual Studio Toolbox. So I'm your host Robert Green and joining me today is Leslie Richardson. Hey, Leslie. >> Hi. >> Thanks for coming on the show. >> Thanks for having me. >> Leslie is a PM in Visual Studio land. >> Sure, I am. >> We're going to talk about debugging tips and tricks. >> Yes, we are. So there's obviously a lot to cover in the debugging space that sadly a lot of people don't know about. You can spend countless hours debugging that one bug and going through the most tedious steps possible when at the end of the day you just want to get back to writing code, right? >> Yeah. >> Yeah, so hopefully some of these tips that I show you will help you out in the long-run. >> Cool, and a lot of these have been in the product for a while. Some are new to 2019. >> Yup. >> So if you can remember too when there's something that's brand new and 2019, let's call that out. >> Okay. >> Otherwise, this is just stuff in Visual Studio. >> Awesome. Yeah, definitely. So I'm going to be focusing more on the .NET space today but a lot of these features overlap into C++ as well. So I'm in Visual Studio 2019 right now and I'm using an ASP.NET Core application. Because I loved to read so much, this is an app that randomly gives me a list of books that I can choose to read and add to my shelf or reject and they won't be added to my shelf. So this app also has a lot of problems with it, so hopefully we can use some of the debugging tools available to us in order to figure them out. >> Cool. >> So first off, I have a breakpoint already set in this Book Manager constructor here and this happens pretty early on in my program's execution where it takes in a JSON file containing a bunch of different book-related information, converts each piece of that into a book object and then stores each of those in a list. So I'm at the start of my function here but I actually want to navigate to the bottom here instead. So normally that would be when I start stemming F10 or step over in order to get down there but that can be tiresome especially because I have this for loop right in the middle, so that can take a lot of time and that's not very productive of me. So the other option of course is to just set a breakpoint at the end and then hit F5. But then if I do that, I have to remember to delete the breakpoint afterward. >> Right, because the next time you run the app and you get up and go for a coffee or something, you come back and sitting on that breakpoint you forgot to remove. >> Exactly, it's like I thought it was going to run without me while I get my coffee but no. So another alternative is something called Run to Click which I can perform by hovering over the line I want to navigate to next. When I do that, you'll notice there's this little green glyph icon that shows up, and I can click on that and it'll run all of my code up to that particular line. >> Which is easier than going down there right-clicking and then finding Run to, or set next statement, or whatever it was. This is just quicker. >> Exactly. It's like having a remote control for your code and being able to fast-forward to where you want to go. So from there, the reason why I wanted to go to the end of this function is because I wanted to hone in on that book lists which stores a hundred different books because I want to quickly inspect each one. When I hover over it, I get a data tip but one of my problems that I have a data tips from time to time is that the moment I hover away from it, it disappears. So if I want to keep it for a while longer, what I can do instead is pin it, and when I pin it, this data tip will stick around for as long as I decided to leave it until I ultimately close it. >> You can drag that to a second monitor; is that true? >> You know I haven't actually tried. Good question. I feel like that should be possible. >> Okay. >> But good question. The good news about this is that when I close out of my debugging session here, it'll still be present even when I start a new one. So now if I wanted to inspect all of the contents of this list here, at first glance, this isn't really helpful. Let's say I wanted to inspect each book by their names, it would be a little tedious to expand each of these out until I find there's the title property and then keep going to the next one and so forth until I find what I'm needing. So this also goes for if I were in the Locals window as well or Watch, or Autos. Ideally, it would be a lot nicer if instead of getting the type of object under the Value column, I could see particular properties that I'm interested in so I can just quickly skim through this list. So thankfully, there is a feature that you can use in Visual Studio, that's one of my favorites and it's an attribute called DebuggerDisplay. That is an attribute that allows you to customize how you view your objects in the Watch, Autos, Locals, and Data Tip windows. So to do that, I can go and see where I defined my class. At the top of that class definition, I can write in some DebuggerDisplay syntax. The curly brackets will return the value of any property or properties because I can go plural with it, I can also use expressions, if I wanted of whatever property that I specify. In this case, I want to view books by their title property. So I'm going to type in title, and I'm also going to have to restart the debugging session. But hopefully, this is where the magic happens. So this is an attribute that exists currently in F#, C#, and Visual Basic. So this is for manage users but if you're a C++ user, the equivalent that you can use that performs the same function is something called Natvis where the difference mainly is that you have to create a separate Natvis file inside your project. That contains some XML that you can add to or modify in order to perform the thing that I'm about to show you. So I need to go back to the end of this function again. I'm going to use Run To Click, and I have my Data Tip that I penned earlier that's still here because I never closed it. This is my favorite. This is the magic. >> That is cool. >> So cool. I love it a lot. >> Okay, now this is the part where we have fun. How long it's been in the process? >> Yeah. Longer than 2015. Longer than 2015. It's been around for a while. Longer than me, definitely. >> That's my favorite part of the show. >> I get asked that all the time. So is this a 2017, 2019 exclusive? I'm like, "Oh no". >> No. Awesome. >> Yeah. So that's one of my favorites. So another thing that I like- >> You can do expressions, so you could concatenate a couple of fields, actually? >> Exactly, yeah. If you wanted to do some simple type of expressions, then you can do that as well. If you're interested in seeing one property plus another it's possible. >> Could you do something like a function that says if these three fields are missing, just display "incomplete", then if they're there, display "complete". Can you do stuff like that? >> You can, yeah. You can do some simple if conditional type statements as well. Do it at your own risk. My recommendation for when things start to get very complicated in your DebuggerDisplay syntax, is to create another property or function within that class first called like the DebuggerDisplay or something like that. Include all that logic and then you can write the function name inside- >> That makes a lot of sense. >> -the DebuggerDisplay. >> Okay. >> From there, another feature that I like are the Text Visualizers in Visual Studios. So for instance, I have this JSON variable here that stores all my JSON contents, and if I'm looking at it, first, I need to actually navigate back to it because this is earlier on in my code and I'm currently out of scope. So what I can use for that is something called set to .NET statement which I think you mentioned earlier. So to do that, I can pretend as if I were doing another Run To Click, so I can hold down the Control key and that green glyph will turn into yellow icon which will automatically move my execution pointer up to that particular line. So that's nice especially if you want to try out what different execution paths are going to be looking like or if you want to go back and re-inspect a previous variable but you have to use it at your own risk because since you are changing the execution flow in a way that it is not necessarily intended, it has the potential to mess with the rest of your codes execution unless you restart and make a new debugging session. So from there, I have the JSON variable and looking at it, it's not very readable right off the bat because it's formatted for JSON particular. That and it cuts off the screen. So if I'm looking at it in the Local's window for instance, there's this magnifying glass icon that's next to that and I can click this drop down to get a list of different visualizers I can use. So I'm going to use the JSON visualizer because it's a JSON. This time I get a lot better of a formatted view. So I can quickly view this giant string and it's proper format which is great. Again, if you had a string that's cater for HTML or XML, then you can do that as well or if you have something that's catered for something completely different, you can also make your own visualizers, so that's pretty needed. Also, if you just have a giant paragraph of text being stored in a variable, you can just use the regular text visualizer as well. >> Cool. >> So from there, now I want to start looking into some problems with my application itself. So I'm going to hit "Continue", and so this is the general application, and again, I can go to this rate books page where'll randomly give me a list of books that I can read to add in my shelf or not read and they won't be added. So in my case, I just want to read everything. So I'm going to add. >> A hundred books. >> Yeah, I'm going to read all hundred of them. >> How long will that take you? >> It depends. Depends on how big it is. I have the goal every year of reading 25 books. So I'm not quite at the 100 a year things, so let's go with four years for 100. But I'm noticing that of the 100 books that are supposed to be added to the shelf when I do that, it looks like there's only around half of them. So if I go into Visual Studio, I want to double-check that out but also I should receive a notification if I click on the "Rate Books" page telling that all the books are gone. Instead, I get a lovely exception error instead. So let's try to solve this issue. I'm going to navigate to my AddAlltoShell() function, and this is my function that will take each book on the "Rate Books" page and move them into my shelf. I'm thinking the problem lies within this for loop here. So I want to see what's going on here. When I first started coding, I was really big on print statements everywhere. Yeah, I don't know how many people in the audience out there love print statements as much as I did but they're great. >> Well, I graduated to writing things to a text file. >> Yeah, that's great too, accounts logging. But I guess the problem with that at least for me was that it would be all over my code even when it's not needed, I forget to delete it when I'm done. So I prefer to not modify my code nowadays. If you do like to log your information to the output window, an alternative you can use is a trace-point which is an offshoot of a regular breakpoint. That will allow me to essentially perform a print statement without having to modify my code in the process. I'm going to set a normal breakpoint inside this for loop first and then I can hover over the breakpoint to get little settings icon. When I click on that I'm going to select "Actions" and here I'll get a prompt telling me what I want to log to the output window. In this case, I want to see how many indices this for loop goes there before it stops because I feel like it's stopping prematurely. So I'm going to do index:{i} and return the value of variable i. Hit "Enter" and I'm going to leave "Continue Execution" checked but if you wanted your code to stop when a trace-point is about to be printed, you can do that as well. You get a diamond icon instead of the circle as well. I'm going to boot up the program again. >> It would come in handy if you wanted to watch the progress of something. I was working on some code yesterday that looks in GitHub repositories and it loops through a large number of them and some of them there was an exception and I just wanted to know which ones through the exception without watching this program go, that could take hours. So I wrote it to a file which worked but it seems like this way I could just write that information out to the console window and then I don't have this printing, the saving to a file in my code, which I could accidentally released to production and then it will blow up because someone didn't have the directory that this is writing to, right? >> Right. >> The big risks in modifying the code to do debugging is you leave that stuff in there. >> Yeah, because I am pretty sure I've done a demo in school at one point where I left some arbitrary console.log something rather, and I always write weird quotes in it when I'm frustrated and trying to debug. So like I said, like a random [inaudible] right in the middle of the demo. >> What idiot wrote this code, how comes this doesn't work? >> From here, I'm going to perform that same "Add All Books" to My Shelf option and this time, I should see some print statements to go with it. So going back into VS, I can go to the output window and scroll up a little bit and here you'll notice that there's a bunch of related print statements going back with the trace-point that I created. This is one way to check out your trace-points but also the problem with this is that these can easily get buried in the sea of stuff in the output window. So the other place where you can check them out that I like is in the diagnostic tools window. This is the window that I have a bad habit of closing usually when I'm debugging but one of the perks of keeping it open is this because you can filter out events that you see. >> I have a bad habit of leaving it open and watching the pretty picture. >> Yes, that's true too. I do love the CPU graphs. >> Yeah, but then what are you doing with that? >> But it makes you look official when somebody's walking past you, what is that person doing? >> Although I did use it in this application I was working on to tell if there was a problem because the exceptions, and there's like 10 exceptions that just happen, but then when I noticed that there were 20,000 exceptions or 50,000 or 150,000 exceptions, that was my clue because the way this code works if it hits an exception, it just sits in a loop because it's assuming that it just needs to keep trying and when I got to 400,000 exceptions that was my clue that, hold on a second. >> Like well, okay, maybe I should do something. You can view your trace-points here as well which might make things a little easier too. So from there, I'm noticing that my index value, i, only goes up to 49 when it should go up to 99. At this point, I just want to step through like that last iteration of my for loop just to see what's going on with each piece of it. I'm going to go back to where I set this trace-point and now the new problem is I want to go through this for loop but I don't want to start from the very beginning of it, like from when i is equal to zero because I'll be there for days and chances are I'm not going to pay attention and I'm going to skip when i equals 49 and then I have to rinse and repeat. So I can use a conditional breakpoint instead which will allow me to halt my code only under a specific scenario that I give it. So where I set the trace-point, I'm going to go back to settings and I'm going to uncheck "Actions" because I'm done with this tracepoint and check "Conditions". From there, I want my code to halt when i is equal to 49, hit "Enter" and closeout. The conditional breakpoint has been created based off of this little plus icon inside the standard icon. I'm going to have to restart it again. >> Now, those conditional breakpoints are things have been in there for pretty much all or I don't even remember when those were created. >> Yeah, I have no idea. I feel like I started hearing about Visual Studio around 2013 or whichever one was before 2015. >> 2013. >> Yeah, '13. So anything past that, I have no idea. Cool. Again, we're performing that "Add All Books" to My Shelf action. My code halts this time and you'll notice that the value of i is set to 49 instead of zero. So from there if I step through this for loop, I'm noticing that I used my neutralBooks.Count here as my loop condition and at the same time, a book is being removed from neutralBooks at the end of each iteration, which is causing the count to decrease at the start of each new iteration. So think I found the problem here. So I'm going to stop debugging and we're going to comment out this line and then just clear all the books at the very end of the function instead and that should solve the issue, get rid of that. >> Now, is there a way, okay, let's say you thought that was the issue, you could add neutralBooks.Count to the watch window, right? >> Right. >> But, correct me if I'm wrong, but it doesn't update in real-time as the application is running; is that true? >> Oh, it does update in real-time. If you add it to the watch window and you're stepping then if it changes, it will let you know that it changed because it usually highlights in red in either the watch or in local's window. >> All right. Good. >> Cool. From there, adding all books. It's time it looks like there's a lot more books that have been added and just to double-check, it turns out yeah, I've rated all the books in the library already. That was conditional breakpoints and tracepoints, two awesome alternatives to regular breakpoints that you can use in your everyday debugging environment. >> Cool. So I think what we'll do is stop here and call this part one and then next week we'll do part two and see more debugging tricks. People want to learn more about that, you wrote a blog post on this, right? >> I did. >> People can check out at aka.ms/DebuggerDisplay. >> Yeah, it goes through a lot more of the different scenarios that you can use with it and you can go check it out for more examples. >> We will see you next time on Visual Studio Toolbox. [MUSIC]
Info
Channel: Microsoft Visual Studio
Views: 28,413
Rating: undefined out of 5
Keywords:
Id: Uld-2m2tGiI
Channel Id: undefined
Length: 19min 36sec (1176 seconds)
Published: Thu Jul 25 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.