DEV Community

CodingBlocks

The Pragmatic Programmer – How to Debug

It’s about time we finally learn how to debug by taking take a page from The Pragmatic Programmer playbook, while Michael replaces a developer’s cheat sheet, Joe judges the H-O-R-S-E competition for VI, and Allen stabs you in the front.

If you’re reading these show notes via your podcast player, be sure to check out https://www.codingblocks.net/episode111 where you can find this episode’s full show notes, as well as previous episodes, and be part of the conversation.

Sponsors

  • Clubhouse – The first project management platform for software development that brings everyone on every team together to build better products. Sign up for two free months of Clubhouse by visiting clubhouse.io/codingblocks.
  • Datadog.com/codingblocks – Sign up today for a free 14 day trial and get a free Datadog t-shirt after creating your first dashboard.

Survey Says …

Anonymous Vote
Sign in with Wordpress
What your favorite shell of choice?
  • bash
  • ksh
  • ash
  • Dash
  • zsh
  • fish
  • Command Prompt
  • PowerShell

News

  • We take a moment to thank everyone that left us a review:
    • iTunes: Sebastian Schrodinger, drakegens, svolvovsky, Bert1994DK, -Branford-, MikeMac-AU, dylan w roberts, ManYouFactSharingEngineEar, Jahn_08
    • Stitcher: i_dare_you_to_try_fsharp, geoffster, Mr Maladroit, Stickersoft, InfinitePumpkin, SPACEDANCE
  • The authors of The Pragmatic Programmer, Andrew Hunt and David Thomas, discuss the 20th Anniversary Edition on episode 352 of The Changelog.

The Meat and Potatoes

Power Editing

  • Learn one editor very well and use it for everything.
Tip 22: Use a Single Editor Well
  • If you use a single editor for everything, the keystrokes, commands, shortcuts, etc. will become second nature for various tasks.

Features to look for in your editor

  • Configurable. You should be able to configure all aspects of the editor to your preferences.
  • Extensible. You should be able to configure/integrate with the compiler of your choice.
  • Programmable. You should be able to program the IDE to perform complex tasks (i.e. macros).

Source Control

  • Gives you a giant UNDO button that you can use to rewind days, weeks, or longer!
  • Allows you to see who changed something.
  • Commenting allows you to see the why something changed.
  • Lets you see the differences between versions.
  • You can track which files change the most.
  • Using source control properly allows you to go back to a specific release version in time.
  • Allow for concurrent changes to files.
Tip 23: Always Use Source Control
  • Even if you’re the only one working on the project.
  • Put everything in source control: documentation, memos, phone numbers, etc.

Source Code and Builds

  • Using source control allows for automated code pulls and builds.
  • Additionally if you have automated tests set up, those can be run through as well.

Debugging

  • The term bug is credited to Rear Admiral Dr. Grace Hopper, inventor of COBOL.
  • Debugging will consume the majority of your day. Accept it.

Psychology of Debugging

  • Accept that debugging is just another form of probem solving.
  • It doesn’t matter who’s to fault for the origin of the bug. It’s your problem now.
Tip 24: Fix the Problem, Not the Blame.

A Debugging Mindset

  • Adopt the right mindset before you start.
  • Drop your defences and forget your ego.
  • Forget about the project pressures and get comfortable.
Tip 25: Don’t Panic
  • Take a step back and think about what conditions might cause the bug.
  • Don’t waste any brain cells on thoughts like “that can’t happen” because it has.
  • Don’t just fix the bug though.
    • Determine the root cause and fix that so that it doesn’t happen again.

Where to Start

  • Before you start, first make sure your environment compiles.
  • Set your compiler to treat warnings as errors so that you can focus on the more difficult problems.
  • Talk to the user that reported the bug (if possible). You may be able to get more information.
  • Test boundary conditions and realistic usage patterns.
  • “The best way to start fixing a bug is to make it reproducible.”
    • Create a unit test that reproduces the bug when applicable.

Tracing

  • Debuggers focus on the state of the application now, but sometimes you need to watch the state over time.
  • Tracing statements are diagnostic messages printed out that say something like got here or value of x = 2.
    • When doing this, sometimes it’s helpful to add the fully qualified method name (like class::method()) to remove ambiguity.
  • Tracing can be invaluable when time itself is a factor.
  • These tracing statements should be in a consistent format.

Rubber Ducking

  • Simply talk through the problem to someone else. Seems silly, but it often works.
  • The simple act of describing step-by-step what is supposed to happen often causes the problem to leap out as you explain it.
  • By forcing yourself to explain it verbally to someone else, you have to state things that you might otherwise take for granted.

Process of Elimination

  • While it might be possible that a bug exists in a 3rd party library or the OS, this shouldn’t be your first thought.
    • Assume that the problem is in your code first.
    • Even if the library does have a bug, you will still need to eliminate the possibility of an issue in your code first before submitting the bug report.
Tip 26: “select” Isn’t Broken
  • If you changed one thing and things stopped working, guess what? It’s probably that one thing.
  • If you don’t have an idea of where to start, a binary search can help.

The Element of Surprise

  • When you find yourself surprised by a bug saying something like “that’s impossible”, you must reevaluate what you know as true.
  • The amount of surprise you have is directly proportional to the amount of trust you have in that particular code.
  • You must accept that one or more of your assumptions is wrong.
  • Don’t gloss over a piece of code because you “know” it works.
    • Prove that it works. In this situation. With this data. And these conditions.
Tip 27: Don’t Assume It – Prove It
  • Determine why this bug wasn’t caught before.
  • Create or update unit tests so that it is caught in the future.
  • Ask yourself: “Are there other places that might have this same bug?” If so, fix them, too.
  • If it took a while to fix this bug, ask yourself why?
    • Is there anything you can do (i.e. refactor) that would make it easier in the future.
  • If the bug is due to someone else’s wrong assumption, discuss the issue with the whole team.
    • If one person misunderstood, it’s likely that others did, too.
  • Part of your debugging checklist should include: Are your tests complete?

Resources We Like

  • The Pragmatic Programmer by Andrew Hunt, David Thomas (Amazon)
  • The Pragmatic Bookshelf (pragprog.com)

Tip of the Week

  • Preview your markdown in VS Code by using CMD+K V on macOS or CTRL+K V on Windows.
  • Use LINQPad as your ultimate .NET scratchpad. (LINQPad)
  • Use vimtutor to learn VI.
  • Reversee – The super simple reverse proxy web debugger.

Episode source