 On today's Toolbox, we're going to continue fixing the app we started working on last week, and Leslie will show us additional tips and tricks for debugging. Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and joining me today for part two of our debugger tips and tricks is Leslie Richardson. Hey, there. Hey, Leslie. Hi. Welcome back. Thank you. You haven't changed a bit since we recorded the last episode. I know. It was almost like it happened like five minutes ago. Almost. Yeah. So refresh our memories. What do we see in part one? Yeah, so in part one, we talked about a lot of different things from run to click, set to next statement, text visualizers, debugger display, which is my personal favorite, and of course, conditional breakpoints, trace points, and the list goes on. Cool. And so what are we going to see today? So today, we're going to see a lot of different things, including some of the new 2019 features like search for the watch window, manage data breakpoints, and then other little things peppered throughout in the watch window, such as return value keywords, and format specifiers. Cool. It goes on. All right. We're using the same app, which in spite of the fact that we spent all last week fixing it, still isn't 100% correct. Yeah. Still many, many problems. We like to mimic the real world on this show. Right? Fair enough. Yeah, so again, as a refresher, this is the same app as in part one, but it's an app that will randomly give me a list of books that I can choose to read and add to my shelf, or I can choose not to read it, and it won't be added to my shelf. So there's several more bugs that we didn't fix last week or throughout the week either. So they're still here. So let's investigate those. So I'm going to add a book, in this case, this book called Middlemarch to my shelf. And when I click on it, one of the problems I've been experiencing revolves around this string here that says that I've read the book one time. Already? Yeah, already. I know I haven't even heard this book. That would be an easy way to get through your 100 books done if you just click it and just mark it as read. Right, yeah, just stay out already, read it. And then I'm going to predict that that date is an issue. Yep, that date is also an issue. I'm looking ahead. Lots of problems going on here. OK. Yep, so what's supposed to happen is when I select I finished this book, this value should increment by 1. And it's already saying I read one time, which is ominous in and of itself. So if I say that I finished this book, it should jump from 1 to 2. But if I do it in this case, it's jumped from 1 to 4. So either I subconsciously read this book three more times in the last 30 seconds, or there's something going on in Visual Studio in my code. Oh, and then the date changed. Yeah, oh, yep. Right, so let's see if we can fix that problem of reading it three additional times out of nowhere. So I'm going to set a break point at the start of my index function here. And that will hit when I go back to my shelf page. And from there, I want to hone in on that specific book, which was called Middlemarch. I can't even remember the title. I'm going to read it three times, apparently. So from there, instead of simply expanding until I find what I want, I can use the brand new search tool available in the autos, locals, and watch windows for Visual Studio 2019. So from here, I'm going to do Middlemarch. I think I can just say middle. And as you can see, I'm directly taken to where I need to go. So cool, and again, that is new in 2019. Yeah, it is brand new. Now, if I remember correctly, you wrote a blog post on that. I did. I recently wrote a blog post on that, where you can go to aka.ms, watch window search, and check it out for more detailed info. So from there, I have that. And you'll also notice that as I start typing, it will automatically start highlighting for me. So in the case you don't want to execute the full search, you can just type away. And if it's visible on screen, it'll start highlighting. And you can find things that way as well. And especially this is really nice if you have a bunch of items in the watch window at a time, which can save you the trouble of having full. And does that do both the name and the value? Yeah, so you can search for name, value, or type if you wanted to. So if you just wanted to see all the types, I can type in reading list. And you can see it'll start going. OK, cool. All right, so from there, I have Middlemarch. And I'm specifically interested in a property that this book has called Times Red. And this is the property that's supposed to increment every time I finish it. So I'm going to go into Times Red. Only this time I get a notification telling me that it couldn't be found. But luckily, it's given me the suggestion to bump up my search depth to a larger number. So I'm going to change the search depth here to three so that I can search more thoroughly. Does it default to two? For me, I set my default to two. But normally when you first download Visual Studio for the first time, it's set to three. Oh, where do you change that? Is that an option? Yeah, or just remember the last thing you set. It'll remember. So if you set your search depth to 10 and then you exit out of this session and start any one, it will remember that you were at 10. OK. But I'm going to bump mine up to three. And then I'm taken to that particular property, again, saving me some time of having to remember where that property is. And now the case that I'm trying to deal with is why is this Times Red property changing without my knowledge? And normally this is when I might have to play some trial and error and try to narrow down where it could possibly be coming from. But I ultimately don't know where that location could be. So I can use something called a data break point, which has existed in C++ for a while, but is brand new to manage code users in .NET Core 3.0 in 2019. So this is a break point that will allow me to halt my code when a specific object's property changes, even if it goes out of scope. So I'm going to use that in order to track down the problem. So I can right click on that property and then select break when value changes. And I know that the data break point's been created because I have the standard break point icon there. Yes. And of course I can see it along with the rest of the other break points that I have in the break points window. And then if I scroll up a little bit to the top of this item, an object ID has been created. And this is how Visual Studio will be able to keep track of that object if it ever goes out of scope while my program's running. So from there, I'm going to hit Continue and perform that same action again. And hopefully I get some quick, fast, useful information. Yeah. So this time I get a notification telling me that my data break point has been hit with an added bonus of telling me what the previous value of that particular property was and now what the new current value is. And it will also redirect me to the exact location where that change came from. So in this case, obviously it's coming from the property setter, which makes sense. But ideally, I like to know what called it. So I can go into the call stack and then just double click here. And then I'll be taken to where that setter was called. And in this case, it's happening in my getShelled book function, which I don't need because I already set the times read property to be in somewhere else where. So you retrieved the list. So the fact that you got the book off the shelf was being equated to reading it. Yeah. Apparently. Oh, OK. Brandon, that's kind of what I did in high school from time to time. If I didn't like the book, it's like time to go to Spart notes. But I'll buy the book anyway just so it looks kind of legit. So there's another blog post that you wrote on this as well, right, Managed Data Breakpoints? There is, yep. Yeah, definitely go check it out at aka.msManagedDataBreakpoints. ManagedDataBreakpoints. Yeah. Kind of a mouthful, but. We'll have these in the show notes. Yeah, so it's all good. All right. Cool. Great, so now that I've found the issue, I'm going to comment out this line. And that is really helpful, because you're now being notified when it changed, and then go finding out why, and then you get to decide whether that's valid or not. Absolutely. So it can be great in several different scenarios. That can save a ton of time. Right? Yeah, you don't want to play trial and error all the time nonstop, right? So this is currently a .NET Core 3.0 exclusive feature at the moment, though. Oh, yeah. Yeah, you're going to need to get 3.0 and play around with that if you want to check these out and manage code land. Is it scheduled to make it into framework, or is that TBD? TBD. We've gotten a lot of feedback about that, so it has not been forgotten. We are acknowledging that and going from there. Cool. So going back and performing that same action, this case I'm going to read some other book I've never heard of called Missed Out, Mrs. Dalloway. But this time, correctly, it tells me I haven't ready yet. So that's a good sign. And if I say I finished the book and go back to it, it's increased from 0 to 1. So yeah, those are data breakpoints and searching. So data breakpoints, again, are extremely useful for many scenarios. In that case, I just wanted to hone in on a specific object. So it's great for that, especially in contrast to if you were to just set a breakpoint on that property setter where multiple objects could be accessing that and maybe you don't want that. It's also good if you have a global variable that's being accessed across multiple files and things and you don't know where it's being modified and you can use that for this. Or maybe you just inherited one of your teammates' pieces of code and you're unfamiliar with it, but there's something going on it that's causing a property to change without your knowledge. So then you can use a data breakpoint to hunt it down instead of having to play. Well, maybe it's in this area. I don't know what this piece of code does. Let's try it. Cool. Type of deal. All right. So from there, there's one last bug that I want to deal with. It's not so much of a bug, so much as an added addition on my part. But the line right below read one times, it tells me when I last completed the book. But I have a tendency to read multiple books at once and can finish several books in one day as a result. So I'd like to know also the exact time that I finished it as well. OK. So that's currently not there, so I want to go into Visual Studio and see where I can add that. So I'm going to set a breakpoint at this line here that returns that related string about when I finish the book and refresh the page. And just looking at it at first glance, there's a lot going on on this line. I have a nested function call happening within a parameter of an outer function call, and then there's a property value being set. It's a lot. So I want to break down this line of code and see what pieces of the string are coming from where, just so I have a better understanding of what's happening. So the first thing I want to look into is the person.toString function. But as it stands now, if I were to try to use step into or step over any of those, there's not really a way to get into that nested function from there. So I can use step into specific in order to choose which of these function calls I want to go to first. Is that new in 2019? No, this has been around. This is not a 20 yet. This is an old one. Awesome. Yep, so it's been around for a while. So I can right click this line, and I can go to step into specific, and I'll get a dropdown with all the different places I can go to. You know what, we need to add a feature to Visual Studio where when you hover over something, it will tell you when it first appeared. That would be amazing if there's an extension for that. Or it's like a Visual Studio history extension. Exactly. Call me when it came out. Yeah, just for fun. Yep, so you can pull your hair out wondering, how did I not know about that, seriously? And you can lard it over your friends. Oh, man, yeah. So from there, I can select person.toString. And just as if I were to use the regular step into, it'll take me into that function. So super great. So this one's pretty straightforward. It's just returning the value of the parameter that I gave it, in which case it was just my name. So I'm going to step through it, and then step out. Then I'm back to this line again. So from there, now I want to look into the finished toString method here. So again, using step to specific, I'm going to select that one. And here I'll be taken to the finished toString method. And I have even more stuff going on here. I have some string concatenation going on. So first, I just like to see what is the exact return value with this method. But normally, in order to do that, because it's not currently set to a variable, first I would think, oh, great. Now I got to stop debugging and then set it to an arbitrary variable, and then look in the watch window or something what that variable could be. But another way that you can look at this return value without having to stop debugging and do all that is to step to the end of that function. And you'll notice that in the locals as well as the autos window, there is a line that has the return keyword on it. And that will tell you exactly what's being returned by that function. So that happens by default. So you don't have to do any other additional legwork in order to see the results of something that's not set to a particular variable. And another way that you can do this is also in the watch window. So I'm going to add dollar sign and then return value. And then I get that same result. OK, cool. So the added bonus about being able to do that in the watch window is that I can also have format specifiers to it, which are things that allow me to temporarily view the contents of the watch window in a different light. So if I wanted to remove the quotes around the string, for instance, because they're kind of redundant at this point, I can add a comma to the item that I have here. And I'll get this dropdown, which is new to 2019, with a list of different format specifiers I can use. So instead of having to memorize the giant table that you'd have to look up online, it'll give me some options right off the bat. So I'm going to select NQ, which stands for String with No Quotes, hit Enter, and that will run the quotes. And that's just in the watch window. You're not actually touching the running code, right? Correct. OK. I'm not filling with the code itself at all. Yeah. So great. From there, I now want to step into yet another function. I have this finished book string here. But again, I am now out of scope because I've reached the end of the function, so I need to get back to it. I'm going to use setToNextStatement again. And there's several ways you can use setToNextStatement. I can actually drag the execution arrow up if I wanted to instead of holding down the Control key like I did previously. So from there, once more, we're going to use step into specific. And I'm going to select Finish Book String. And here I'm being taken to yet another function with more string concatenation going on. So let's say I wanted to break down this line of code. So I can use return value again. And again, I'm going to step to the end of the function. And this time, so I have the final result here, of course. But if I wanted to break it down even further, then I can do that as well by adding return value. I can do return value 1. And that'll give me the results of this.title. And if I wanted to get this last red date thing over here, then I can also do return value 3. And that will give me the value of this too. Interesting. And this also goes for if you're looking in the locals and autos windows, it will show you the same thing as this. What would you do that rather than just, if you hovered over this.title, it shows you that information, right? And if you hovered over to short date string, it shows you that. You can also add those to the watch window. So when would you, what's the value of being able to specify return value 1, return value 3? It's just another kind of variation to be able to look at what's being returned on top of that. If you're doing it in the watch window, you can mess around with, again, the format specifiers and stuff, and just kind of keep everything grouped together. If you're, I like to say organized, so I'd prefer to just have all the return value stuff grouped together. Cool. So, all right. And from there, I have found where I can add my time related scenario because I have this too short date string function here that I don't need in order to show the full time and the date. Right. All right. And from there, I'm going to continue running my code. That is known as edit and continue. That is edit and continue. That's magic that sometimes it works, sometimes it doesn't. And this is a scenario where it should work, because if I refresh this page. I remember when that was introduced. Right? That was amazing. When was it introduced? Because I think it was 2015. I told you that I knew the date, and I'd have to admit how old I am. A while ago. Great. Yep, so we are making. I'm old enough to remember when that was introduced the first time. Cool. Awesome. Yep, so it's an empty tool when it works. We are making improvements on it as we speak, however. Cool. So, yeah, from there, I just refreshed the page. And as you can see, I now have the time. And that was return value, step into specific, format specifiers, and then set to next statement, made a reprise as well. Cool. So now the app is perfect. Yeah, now it's absolutely perfect. There's nothing wrong with it. I'm never going to have any trouble with it ever again. Cool. So over the course of these two parts, we've obviously seen some things that we knew were in there. Learned a lot. I saw a number of things I didn't know were in there, including some things that have been in there for a while. So this has been great. Thanks so much. Awesome. Thanks for having me yet again. Hope you guys enjoyed that. And we will see you next time on Visual Studio Toolbox.