 Hey everybody, this is Brian and welcome to the 118th cute tutorial with C++ and GUI programming. A little bit of shameless advertising first. Be sure to visit my website voidrealms.com for source code for this tutorial and all the 117 other tutorials that I've done. Just go to tutorials and select the language. You're probably looking for cute, right? And a little bit of shameless advertising. Go to pluginbot.net, my new side project centralized device management. Now my friends will be happy because I've done my marketing. Now back to the stuff I enjoy doing. Alright so what we're going to cover today is debugging. You see this beautiful bar on the left here and through 118 tutorials we've managed to totally avoid this big bug icon. When you click it you get all these weird windows. What in the heck? What does all this stuff do? Well we're going to explore this and find out. Alright so I've got a very basic program here. Let's go back into edit mode. I've got a dialog with some buttons and each one of these has a signal slot so we can open that up. Some people ask why I don't just put the signals and slots right in the classes. Well I don't want any voodoo magic so to speak. I don't want anything hidden so when somebody's brand new to this they can come just go oh that's how that works. So you can very easily see what happens when you push each button. So basically all we're doing is calling this class MyClass which has some functions in it like bad pointer. You guessed it. Returns a bad pointer. So let's actually go here. This is a pretty common mistake I see people do. Queuescope pointer and you're making a new queue string and then you're returning the pointer. Well what happens with queuescope pointer? It goes out of scope and it deletes the pointer but you're returning the pointer therefore boom program crashes. Custom debug we're going to cover this it's just a for loop and let's see here what's that oh I never used I variables we're just going to talk about how to explore local variables and bad math something that's also very common here. So let's just dig right in. If we run this program tick tock tick tock tick tock see we have this beautiful interface and just to show that it dies we're going to click bad pointer and you see it does something for a second and then boom program has unexpectedly finished. If you've gone through 117 of my tutorials you've probably had this at some point and you've had to sit there and figure out what the heck happened. Well we're going to talk about how to fix all that. So first things first how do we launch debug mode? Well you can either click debug and then click this little arrow with the bug next to it or you can click this guy down here. Some of you may be wondering what's the difference between debug and release. Well if you've compiled you'll notice that debug you're executable or your binary is significantly bigger than release and that's because it adds what's called debug symbols meaning it adds little bookmarks if you will into the code so it knows where it is so we can figure out what happened. Release strips all that out so it's lean mean and ready for production. So be sure you're in debug mode otherwise I fear this may not work. Alright so if you're in edit mode and you click this little guy here you notice how it instantly flips you into debug mode that's the first thing you should notice. So let's talk about all these windows and what do they do? Actually kill the program here. We're going to add some break points as they're called. So the first thing we're going to do is we're going to go down to variables and we're just going to on line 29 right click and we're going to set break point. Notice how there's suddenly a break point here shows you the number there's no real function name but you can mouse over and get a whole ton of information about where you're at. Now when we debug this again click variables boom it stops. And you'll notice how suddenly we've got a ton of data and you got a little error that tells you that's where we are in our code. So you've got all this information of where we are we're in the my class variables function on line 29 and then you can see kind of like a trace of what happened. I think this is called the stack trace kind of like breadcrumbs of where you were. Here is the break point that was triggered. And these are the variables. You can see how we have i right here. Sometimes you can get it to work where you can mouse over and it'll give you the value. It says you know it's ten your name Brian. So like if you mouse over locals because you're at that debug point is Brian Cairns because we're saying name is Brian name dot append. So let's actually stop debugging. We're going to add another break point in here. So now we've got two break points. What is a break point? Think of it as if you're on the information superhighway and you see something really interesting and you want to hit the breaks and stop that's what it does it actually stops the execution of your program and gives you a chance to glimpse into the memory and see exactly what's going on under the hood. And you can see how we've got our our number and our line. You notice how they're flipped around. You can sort those I believe. We're going to debug again. Now you can just press F5 on the keyboard to debug. And click variables. Notice how we're at the first break point. So it just says name is Brian. It also gives you the address to this. You can right click and you get a whole slew of options. You can actually use like raw pointers and just display it any old way you want. So how do we jump from this break point to this break point? Well, very simple. Click that button or just hit F5 to continue. And it jumps to the next one. You see how it jumped from the first to the second. You also have stop. You have step over. Step into and step out of. And this little guy which switches the debugger into instruction wise mode, which if you click that you get this horrendous looking nightmare. It looks like ancient Egyptian algebra. That's actually assembly code. That's pretty much one step ahead of machine code. So that's about as close to bare metal as you're going to get. I personally do not know assembly code. I can kind of see a little bit of what it's doing just because I've been programming for so long. But I don't dare try to mess around with that just because I don't know it. So if you click that, just click it back and go here. If you step over, you're going to jump over Qtabug. Notice how Qtabug is a function. So if you step into what happens, you actually step into the header file of the Qtabug class or actually the Q logging class which holds the definitions for Qtabug. So if you get lost in that, step right out and jump back out. And that's how you do that. And you can just continue. And it'll run your program. Click stop. We're going to do something a little more complex here. We're going to do a... Let's do bad math here. We're going to set a break point. And now we're going to actually disable that break point. You can actually disable those. Isn't that pretty neat? Enable, disable. So if we disable that break point, let's run this bad boy. Click on bad math. Look at that. And fear stop because it received a signal from the operating system. Arithmetic exemption. So even with that disabled, let's actually just delete that. Do this again. Boom! See, you catch those really weird errors. Like if we were to just not debug this and just run it, do bad math, what happens? Boom! Program unexpectedly finished. And you're left scratching your head trying to figure out what just happened. Well, this is a division by zero error. You can't divide by zero, obviously. But when you're in debug mode, it'll catch that. Even if you don't have a break point. Now, there's another way you can do that. Which you can actually set a break point. And then you can edit the break point. And you notice how you get this break point type. File, name, and line number. Well, you can set this to like function name. If it's a specific function name. If it's a memory address. Or whenever a C++ exemption is thrown or caught. Or, you know, a whole slew of other options. So we'll just say thrown. And then you can add conditions. You can ignore. Just like a number of counts. So if you want to wait until it happens a hundred and two times, then you can do that. Commands, trace point and message. I believe that's for remote debugging. I've never actually gotten that to work. So we're just going to set our little invisible break point there. And bad math. Boom! Same deal. So, pretty neat, huh? So we're going to delete that break point. Actually, we're going to delete all these just so we can see what's going on here. All right. So, so far we learned to look at variables. Now we're going to make something a little more complex here. We're going to create a break point. On line 18. And then we're going to edit that break point. Now, you see we're in a for loop. For i equals 0 to 10. So basically it's going to go from 0 to 9. So what we want to say here is condition. We want to know if i is a certain number. So if i equals 5. And it's going to use the i variable from your current scope of where that break point is. And you can see over in your condition view you've got the i equal 5. You can even select specific threads if you wanted to. So we're going to debug this thing. Custom debug. Now, you can tell this work because we're in the My Class Custom Debug. Our little break points there. And what's the value of i? 5. Same thing as our condition over here. So that's one way of setting a break point. So we're going to stop that. And let's see here. Move big point. Last but certainly not least, we're going to go with a bad pointer. This is probably one of the most frustrating things to debug. Especially if you're working with some legacy code where they don't really do any memory management. They just hand you a raw pointer and well, there you go. And a lot of times if there's an error, they'll just say something like, you know, if error then return zero. So you may get a zero and you still think you're working with something. But in this case, scope pointer, remember when this goes out of scope, program's going to crash. So let's actually run this. Bad pointer. Boom. Program has unexpectedly finished. So how do we go about debugging that? Well, we can't debug it here because, well, it's still in scope. So we need to go to our other class that's actually calling it right here. Bad pointer. So we got a couple of different things here. You see how we're debugging? We're doing a QDBug. We're spitting out the address. Well, because we got an address, we know it's not zero. It hasn't been deleted. So what's going on here? Let's actually create a breakpoint. Whoops. Mouse is acting up a little bit. And let's create another one here. And we're going to edit this guy. And we're just going to say C++ Exemptions thrown. And we're going to do bad pointer again. And you can see how we have a string. It's got a memory address. And boom, there's our segment fault. The inferior stopped because it received a signal from the operating system. I mean, the operating system says, I don't know what you're talking about. That pointer doesn't exist anymore. So it does what's called a segmentation fault. If you ever used, I think it was Windows 98, maybe even XP at some point, you get what's called the blue screen of death. That's pretty typical. But you also see what it highlighted for you. Q strings append function. And from there, you can figure out, oh, well, I don't have a very good pointer. So then you can actually spit out the pointer and things of that nature. And you can see how it's actually highlighted right here. And it tells you, okay, here's your breadcrumbs, metacol, static metacol on the button push, string append. There you go. Let's step out of there. Whoops. So that in a nutshell is debugging. You can do many, many more things. And you can actually do some very cool things. Unfortunately, I don't think the breakpoints actually persist with the code. I will put the code out on my website, voidrealms.com, just so you can see exactly what I've done and play around with it a little bit more. This is horrendous programming. Don't ever do this, but this is just for demonstration purposes. All right. Thanks for watching. I hope you found this educational and entertaining.