This workshop will be retired on May 31, 2020.
Patterns in Debugging and a Few Words of Caution11:11 with Gabe Nadel
When you begin hunting down a bug, you never know what you'll find, but there are some common types of bugs and best-practices for squashing them. This video lays out some important classes of defects as well as guidelines for working efficiently.
Back when we started our discussion of debugging, 0:00 I mentioned that you might find yourself debugging for lots of different reasons. 0:02 Sometimes something's clearly broken, sometimes not. 0:05 You may just be using your debugging skills to check things out as you build. 0:08 As we explored the bugs in our demo app, it probably became clear 0:12 that the kinds of problems you can find can be quite diverse. 0:15 Both in terms of the bug you observe and the root cause. 0:18 Now, before I bust out the bullet points, 0:22 let's pretend you aren't a programmer at all. 0:24 Let's pretend you're a doctor. 0:27 A patient walks into your office and he tells you he's been having chest pain 0:28 after dinner every night for the last three nights. 0:31 Not extreme levels of pain, but enough that he decided to come in for a visit. 0:34 You ask him what he had for dinner each night, and he responds that he had 0:38 pork chops on night one and sausages the other two nights. 0:41 Without even trying, your mind starts crafting theories about why 0:45 pork might be causing the patient's discomfort. 0:49 You tell the patient it is probably indigestion and 0:51 to lay off most meat, especially pork, for a few days, drink plenty of water, 0:54 and see if things improve. 0:57 If they don't, he should come in again for more tests. 0:59 This recommendation probably sounds like the type of feedback you've gotten from 1:02 a doctor before. 1:06 You present a symptom you'd like to get treated and 1:07 you get a suggestion about how you might do that, but 1:09 it's based on a combination of clues, hunches, and medical knowledge. 1:12 Not much hard evidence, chemistry, or lab work. 1:16 Now, in the world of medicine, when a doctor gets a story like this for 1:19 what seems like a mild issue, they'll often try to solve the problem by 1:22 adjusting the behavior and letting some time pass. 1:26 After all, ordering a whole battery of tests would be time consuming, 1:29 expensive, and the doctor doesn't even have the luxury of observing the patient 1:32 while the issue's occurring. 1:36 Well, it turns out, in the rush to come up with the possible solution, 1:38 neither the patient nor 1:41 the doctor discussed the large milkshake that accompanied dinner each night. 1:43 Which was actually more likely the cause of the issue. 1:46 I mention this because bugs, like medical patients, 1:50 often present symptoms whose root causes are not at all obvious. 1:53 Though in cases of debugging, we have the luxury of grabbing the patient, 1:57 laying them on the table, and getting out the scalpel right away. 2:01 We can feed our patient a pork chop and 2:04 actually watch how it travels through their body and what issues may arise. 2:06 After that, we can feed him some sausages and see if he behaves differently. 2:10 The point is, debugging gives us a very high level of transparency, detail, and 2:13 testability. 2:18 So we should do our best to avoid snap judgments and actually peer into the code 2:19 for information that will help unravel the mystery. 2:23 Programmers often fall victim to something called shotgun debugging, 2:27 where they let their hunches rather than solid information 2:31 lead to a series of unfounded and often unrelated attempts to solve the problem. 2:34 Yes, sometimes you will solve the bug. 2:39 But in doing so, you fail to ever actually find the root cause. 2:41 It often wastes tons of time. 2:45 And worst of all, it may introduce new bugs with the scattershot approach. 2:47 Let's spell out some guidelines for how best to prosecute a bug. 2:51 These aren't anything approaching a formula, by the way. 2:55 But you'll find they represent real phases in how you'll often work through an issue. 2:57 When you find a bug, or more importantly, when someone tells you of a bug, 3:02 the first thing to do is replicate it. 3:06 Just because it happened once doesn't mean it'll happen again or 3:08 that it always happens for the same reason. 3:11 This leads to our next step, identify the reproduction steps or repro steps. 3:14 You see, when you're dealing with a big app, 3:19 tapping a certain button in the main navigation may cause an app to crash, but 3:21 perhaps only when a certain screen is displayed or 3:25 when a certain type of user is logged in or maybe when the app is offline. 3:28 Figuring out the exact state and steps needed to replicate the bug 3:32 is really important, both in finding the root cause, and 3:35 then knowing that you've solved it when you're finished. 3:38 It's a little like making sure that it's the pork and not the milkshakes, or 3:41 worse yet, an ulcer, that's actually causing our patient's chest pain. 3:45 If, after identifying the repro steps, 3:49 you're pretty sure you know right where the root cause is, you can go ahead and 3:51 try to solve the problem by changing some code. 3:55 But I caution you to timebox this step. 3:58 Set a timer for five or ten minutes and go for it, but 4:00 when the alarm sounds, pause and move to a more methodical approach. 4:03 You wouldn't believe how quickly hours and 4:07 hours can slip by if you start debugging through trial and error. 4:10 Assuming you couldn't solve your problem before the alarm went off, 4:14 it's time to start setting breakpoints and stepping through your code methodically. 4:17 As you do, be sure you check values for 4:21 related variables along the way to make sure you're focusing in the right areas. 4:23 Also, as you go, sketch out the logic and make sure that your mental map of how 4:27 the code is written actually matches what you're seeing. 4:31 If you don't have a good mental map of the code, now is the perfect time to draw one 4:34 with a pencil and paper so you have it for future efforts. 4:38 Based on what you find, try some more tactical fixes for the bug. 4:42 Remember, you aren't just trying to get rid of the symptom, you want to 4:46 identify the cause, as that will help keep your code safe and prevent future bugs. 4:49 If these more tactical efforts fail, I encourage you to stand up from your desk 4:55 and either explain the issue you're seeing to a rubber ducky or 4:59 some other inanimate object like an Android developer. 5:02 >> Hey! 5:05 >> Now, the object isn't to get the answer from a coworker, though that may happen. 5:06 But rather in forcing yourself to verbalize the issue and 5:10 what solutions you've already tried, you almost always uncover a leap in logic or 5:13 a new plan of attack. 5:18 Then take what new insight you may have gained and 5:19 step through the code trying to find a suitable solution. 5:22 Don't fall into the trap of a new round of trial and 5:25 error just because you came up with a new theory. 5:28 If you don't already thoroughly understand the code you're looking at, 5:30 you may want to revisit the documentation as well. 5:33 Assuming you've eventually found a solution, be sure to test it thoroughly. 5:37 Don't just test what we call the happy path, 5:41 as in the one that we know will succeed, but rather actually try to break the app. 5:43 Remember, you aren't just fixing a symptom, you're identifying and 5:48 exterminating a disease that just happens to cause symptoms. 5:51 Now that you know there was a weakness in the code, it's probably a great time to 5:55 uncover any related weaknesses while the logic is still fresh in your mind. 5:59 Ideally, you can clean them all up in one fell swoop. 6:03 If you've spent a long time working on a bug and you aren't pursuing a reasonable 6:07 and methodical course of action, then take a break and get something else done. 6:11 There's no worse feeling in coding than spending hours getting nowhere, 6:16 only to try to fall asleep with the perplexing code burned into your retinas. 6:20 If it's 4 PM and you've been banging your head against a bug since lunch, stop and 6:24 do something else. 6:28 Whether it's working on a different feature, getting some exercise, or 6:29 just reading up on a new topic. 6:33 There are two reasons this is so important. 6:35 First of all, a new potential solution will almost 6:37 definitely present itself when you actively focus on something else. 6:40 Secondly, you'll be able to go home for 6:44 the day having spent your last couple hours moving forward, 6:46 which will allow you to sleep better and start the next day fresh. 6:49 Programming can be a highly emotional endeavor, especially in your first few 6:52 years, and you should be proactive in keeping your momentum and your spirits up. 6:56 If no solutions present themselves, don't hesitate to ask the Treehouse community, 7:02 Stack Overflow, or other programmers. 7:06 Just be sure that when you ask, you supply lots of context, code snippets, 7:08 as well as descriptions of what you've tried so far. 7:13 Programmers are almost always happy to help, but often have little patience for 7:15 developers who don't take the time to craft a thorough question. 7:19 Simply asking for help is an option many devs forget about, and 7:23 it's too bad as you'd be surprised at how much time this can save and 7:26 what other useful knowledge you might gain in the process. 7:30 Lastly, no matter what happens, try to stay positive. 7:33 That can be very difficult when a bug just won't show itself to you. 7:37 But that is perhaps the most important time to be vigilant and self-aware. 7:40 Feeling like you just have to solve this bug before you can do anything else 7:44 is the first sign that you need to take a step back. 7:48 Now, chances are not every bug you attempt to prosecute will 7:51 need every step I just listed. 7:54 And over time, you'll get better and better at root causing issues faster. 7:55 To give you a little head start on that, 8:00 here are some of the most common types of bugs you'll encounter. 8:01 Syntax bugs. 8:05 Just like they sound, these come from using the wrong syntax. 8:06 Most often, using the wrong syntax in Swift will give you a compiler error 8:09 before you can even produce a bug. 8:13 But even at runtime, these may pop up, especially for new devs. 8:15 Arithmetic bugs. 8:20 This can happen for all sorts of reasons, like accidentally dividing by 0 or 8:21 losing decimal points of accuracy when dividing by different types of numericals, 8:25 like ints instead of floats. 8:30 Data type bugs. 8:31 A data type bug could occur if you accidentally do something like assign 8:33 an array to a string variable or a float to an int. 8:36 Now, in Swift, these are almost always caught by the compiler, 8:39 because Swift is type safe. 8:42 But in a language like Objective-C, 8:44 data type bugs are very common, especially when you're starting out. 8:46 Instantiation bugs. 8:50 Much like data type bugs, these are more common in Objective-C than Swift. 8:52 Very often, you might try using an array without initializing it, or 8:56 you assign a nil value without knowing it. 8:59 Swift optionals save us from many of these problems, but 9:02 they will arise from time to time, especially in other languages. 9:05 Logic errors. 9:09 These are things like infinite loops that just run forever, or being off by one, 9:10 like we were in the last video where we started our loop at the array count rather 9:15 than the count minus 1. 9:19 Multi-threading bugs. 9:20 These happen when you have different processes on different threads and 9:22 things aren't happening in the sequence you expect. 9:25 A very common type is called a race condition, where you have expected 9:28 one part of your code to have executed before another, but in reality it doesn't. 9:32 For instance, your UI refreshes before the new data you're trying to present 9:36 has been downloaded from the server. 9:40 These can be really perplexing if you don't know to look for them. 9:41 Device/simulator/operating system bugs. 9:45 Certain bugs will be rooted in the exact device or operating system you're using. 9:48 While you're trying to come up with reproduction steps, it's a good idea to 9:52 test on at least a couple devices or sims and be sure that isn't a factor. 9:56 User interface bugs. 10:00 Like we just saw, UI bugs can be caused by the views, 10:02 the assets in those views, or the code. 10:05 When you see a user interface bug present itself, it's important to remember that it 10:08 may live at the intersection of your code, your storyboards, and your assets. 10:12 Remember to explore all three paths before doing anything extreme. 10:16 Making sure your outlets and 10:20 actions are hooked up properly is always a good first step. 10:21 Performance bugs. 10:25 These are bugs which often slow or crash your app. 10:26 Very often, you'll need to employ Xcode Instruments to figure out where 10:29 the problem is coming from, and after that you'll need to change your code. 10:32 If you'd like more information on using Instruments, check the link below. 10:36 Well, I think we've given you a good start. 10:40 Debugging is something you'll be doing a lot of, but 10:42 that's just part of being a developer. 10:44 Sometimes you'll find code just littered with bugs, and 10:47 you'll spend tons of time getting rid of them. 10:49 Remember to keep your head up, don't get frustrated, and when you just can't seem 10:51 to figure it out, never be afraid to ask other developers for help. 10:55 That bug which has been hopping around evading you for hours or 10:59 days is certain to show itself sooner or later. 11:02 And when it does, your team and 11:05 your users will be glad you took the time to hunt it down. 11:07
You need to sign up for Treehouse in order to download course files.Sign up