>> 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 Greene,
and joining me today for part two of
our debugger tips and tricks is Leslie Richardson.
>> Hey there.
>> Hi, 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 like happened five minutes ago.
>> Almost.
>> Yeah.
>> So refresh our memories,
what did we see in part one.
>> Yeah. So in part one, we talked about a lot of different things,
from Run To Click, set to .NET statement,
Text Visualizers, DebuggerDisplay which is my personal favorite,
and of course, conditional breakpoints,
tracepoints and the list goes on.
>> Cool. 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.
>> Okay.
>> Then other little things peppered
throughout in the Watch window such as return value,
keywords, and format specifiers.
>> All right. Cool.
>> It goes on.
>> All right. We're using the same app.
>> Yeah.
>> Which in spite of the fact that we've
spent all last week fixing it,
still isn't 100 percent correct.
>> Yeah. Still many, many problems.
>> We like to mimic the real-world in this show.
>> 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.
When I click on it, one of the problems I have been
experiencing revolves around this String
here that says that I've read the book one time.
>> Already. Wow.
>> Yeah, already. I know. I haven't even heard of the book.
>> That leads you to where to get to your 100 books done.
If you just click it, it will mark it as read.
>> Yes. There I already read it.
>> Then I'm going to predict that that date is an issue.
>> Yeah. That date is also an issue.
>> Looking ahead.
>> Lots of problem is going on here.
>> Okay.
>> Yeah. So what's supposed to happen
is when I select 'I finished this book',
this value should increment by one.
It's already saying I read one time,
which is ominous in and of itself.
>> Okay.
>> So if I say that I finished this book,
it should jump from one to two,
but if I do it in this case,
it's jumped from one to four.
So either I subconsciously read this book three more
times in the last three seconds,
or there's something going on in Visual Studio and my code.
>> Then the date changes.
>> Yeah. All right.
So let's see if we can fix that problem of
reading it three additional times out of nowhere.
>> Okay.
>> So I'm going to set a breakpoint at
the start of my index function here,
and that will hit when I go back to my shelf page.
From there, I want to hone in on
that specific book which was called Middlemarch.
I can't even remember the title and I read it three times.
So from there, instead
of simply expanding until I find what I want,
I can use the brand new search tool available and
the Autos, Locals, and Watch windows for our Visual Studio 2019.
>> Oh, yes.
>> So from here,
I'm going to do Middlemarch,
I think I can just say middle.
As you can see, I'm directly taken to where I need to go.
>> That's so cool. Again, that is new in 2019.
>> Yeah. It is brand new.
>> Now, 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.mswatchwindowsearch, and then check it out.
>> Cool.
>> For more detailed info.
So from there, I have that.
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 will start highlighting
and you can find things that way as well.
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 it all.
>> Does that do both the name and the value?
>> Yeah. So you can search for name,
value or type if you wanted to.
>> Okay.
>> So if you just wanted to see all the types,
I can search a reading list and as you can see I'll start going.
>> Okay. Cool.
>> All right. So from there I have Middlemarch,
and I'm specifically interested in a property that this book has
called timesRead and this is the property
that's supposed to increment every time I finish it.
So I'm going to go into timesRead,
and this time I get
a notification telling me that it couldn't be found,
but luckily, it's giving me the suggestion to
bump up my search depth to a larger number.
So I'm going 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.
>> Where do you change that, is that an option?
>> Yes.
>> Or just remember the last thing you set.
>> Yeah, it will remember.
>> Okay. Got it.
>> So if you set your search depth to
10 and then you exit out of the session if it's reading one,
it will remember that you were at 10.
>> Okay.
>> Yeah. I'm going to bump mine up to three,
and then I'm taken to that particular property,
again saving some time of having
to remember where that property is.
Now, the case that I'm trying to deal with is,
why is this timesRead property changing without my knowledge?
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 breakpoint,
which has existed in C++ for awhile,
but is brand new to manage code users in .NET Core 3.0 in 2019.
So this is a breakpoint 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 One Value Changes".
I know that the data breakpoint has been
created because I have the standard breakpoint icon there.
>> Nice.
>> Yeah. Of course I can see it along with
the rest of the other breakpoints that
I have in the breakpoints window.
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 is running.
So from there, I'm going to hit "Continue"
and perform the same action again,
and hopefully I get some quick fast useful information.
Yeah. So this time I get an a notification
telling me that my data breakpoint 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.
It'll 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'd 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.
In this case, it's happening in my get shelved book function,
which I don't need because I already
set the timesRead property to be committed elsewhere.
>> Yeah. So you retrieve the list.
So the fact that you got the book
off the shelf is being equated to reading it.
>> Yeah. Apparently.
>> Yeah. Okay.
>> That's what I did in
high school from time to time if I didn't like the book,
like time to go to spark notes,
but I'll buy the book anyway, just so it looks legit.
>> So there's another blog post that you
wrote on this as well, Managed data breakpoints.
>> There is, yeah. Yeah. Definitely go check
it out at aka.msmanageddatabreakpoints.
>> Managed data breakpoint.
>> Yeah.
>> All right.
>> Kind of a mouthful but.
>> We'll have these in the show notes.
>> Yeah. Looks all good.
>> All right. Cool.
>> Great. So now that I found the issue,
I'm going to comment out this line.
>> 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. Very cool.
>> 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 time nonstop.
So this is currently a
Dynacore 3.0 exclusive feature at the moment though.
>> All right. Okay.
>> So yeah.
You're going to need to get 3.0 and play around with that
if you want to check these out in a managed code land.
>> Is it scheduled to make it into framework or is that TBD?
>> TBD.
>> Okay.
>> We've gotten a lot of feedback about that,
so it has not been forgotten.
We are acknowledging that and go in from there.
>> Okay.
>> Cool. So going back and performing that same action.
In this case, I'm going to read
some other book I've never heard of called Mrs Dalloway,
but this time correctly it tells me I haven't read it yet.
>> Okay.
>> So that's a good sign.
If I say I finished the book and go back to it,
it's increased from zero to one.
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.
>> Yeah.
>> 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.
>> Yeah.
>> Or maybe you just inherited one of
your teammate's pieces of code and you're unfamiliar with it,
but there's something going on in 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."
>> Yeah.
>> Let's try it.
>> Cool.
>> This 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 finished several books in one day as a result,
so I'd like to know also
the exact time that I finished it as well.
>> Oh, okay.
>> 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 finished the book,
and refresh the page.
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 fed, 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 depth into or step-over or any of those,
there's not really a way to get into
that nested function from there.
>> All right.
>> 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. Yeah. This is an old one.
>> Yeah. So it's been around for awhile.
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.
>> Yeah. 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 is an extension for that.
>> Yeah.
>> It's like, Visual Studio history extension.
>> Exactly. Yeah. Just for fun.
>> Yeah. So you can pull your hair out wonder,
''How did I not know about that seriously?''
>> You can load 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. Yes, so super great.
So this one is 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 FinishedToString method here.
So again, using Step Into Specific, I'm going to select that one.
Here, I'll be taken to the FinishedToString method.
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 at first, I would think, Oh, great.
Now, I got to stop debugging and 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.
You'll notice that in the Locals as well as the Autos window,
there is a line that has the return key Word 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 leg work in order to
see the results of something that's
not set to a particular variable.
Another way that you can do this is also in the Watch window.
So I'm going to add dollar sign and then ReturnValue,
and then I get that same result.
>> Okay, cool.
>> So the added bonus about being able
to do that in the Watch window is that,
I can also add 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 redundant at this point,
I can add a comma to the item
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" in that will enable it to pass.
>> That's just in the Watch window,
you're not actually touching the running code.
>> Correct.
>> Okay.
>> 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 under scope because I've reached the end of the function,
so I need to get back to it.
I'm going to use that to next statement again.
There's several ways you can use that to next statement.
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 FinishedBookString.
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 ReturnValue again.
Again, I'm going to step to the end of the function.
This time, 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 ReturnValue,
I can do ReturnValue1.
Now, give me the result of this.Title.
If I wanted to get this last read date thing over here,
then I can also do ReturnValue3,
and that will give me the value of these two.
>> It's interesting.
>> This also goes for if you're looking
in the Locals and Autos windows,
it will surely do things like this.
>> So why do that rather than just
if hovered over this .Title, it shows you that information.
All right. If you hovered over ToShortDateString,
it shows you that.
>> Yep.
>> You can also add those to the Watch window.
So when would you list the value of being able
to specify ReturnValue1, ReturnValue3?
>> It's just another variation to be
able to look at what's being returned on top of that,
you're doing it in the Watch window.
You can mess around with the format specifiers and stuff,
and just keep everything grouped together.
I like to say organize though.
I'd prefer to just have all the ReturnValue group together.
>> Okay.
>> So all right.
From there, I have found where I can
add my time-related scenario because I have
this ToShortDateString function here that I don't need
in order to show the full time and the date.
>> Right.
>> From there, I'm going to continue running my code.
>> That is known as edit and continue.
>> That it's edit and continue that.
Yeah, that's a magic that
sometimes it works, sometimes it doesn't.
>> Yeah.
>> This is a scenario where it
should work because if I refresh the speed.
>> I remember when that was introduced.
>> Okay.
>> That's amazing.
>> When was it introduced?
Because I think that was interesting.
>> But they told you then I meet to date
and I had to admit it a while ago.
>> Yep. So we are making-
>> I'm old enough to remember when that
was introduced the first time.
>> Awesome, yep.
So isn't 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.
That was ReturnValue, 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 is 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 awhile.
So this has been great. Thanks so much.
>> Awesome. Thanks for having me yet again.
>> Hope you guys enjoyed that.
We will see you next time on Visual Studio Toolbox.