DEV Community

Cover image for Debugging - you’re doing it wrong. 10 techniques to find a bug in your code

Debugging - you’re doing it wrong. 10 techniques to find a bug in your code

Nik Poltoratsky on July 23, 2019

Do you remember those long, long hours spent on debugging? When you're staring at a codebase and can't figure out what exactly went wrong? You're n...
Collapse
 
hamatti profile image
Juha-Matti Santala

Great post, thanks Nikita!

Debuggers are amazing, my absolute favorite tools in my toolbox. The ability to jump into the code to examine variables, to jump back and forth in the execution and figure out where things go awry is just wonderful.

One thing I would add is making sure you can reproduce it and find the boundaries of the problem: under which circumstances does it happen. If you can't define the problem, it's much harder to start fixing it.

I've been burnt so many times by jumping into trying to fix something without first fully understanding when and how it happens. That way, you can also manually test those use cases after you have attempted to fix it.

And yes, I'm in the rubber duck wagon myself too! I have two at work (a regular one for easier problems and a Sherlock Holmes duck for the times when things get though.

Collapse
 
nikpoltoratsky profile image
Nik Poltoratsky

Hey man! Thank you for sharing your thoughts about debugger. I agree with you

Collapse
 
ssimontis profile image
Scott Simontis

I was taught as an eager Electrical Engineer that there are two rules to fixing any problem.

1) Start from a known good: You need to be certain you are using components you can trust. Start from code (or hardware) that you can prove is working properly. If HW or SW is in an unknown state, you cannot reason about it.

2) Divide the problem in half: What would it take for you to get rid of half of the test cases or possible inputs? Can you isolate a module and remove dependencies so that you don't have to worry about the interaction of components, but only the functionality of a single system?

This combo has never failed me.

Collapse
 
monfernape profile image
Usman Khalil

Cool and makes great sense. I'm mechanical engineer myself and love when paths cross

Collapse
 
shamimahossai13 profile image
Shamima Hossain

I have never used a debugger. As for me, I have learnt the most by manually tracing and grinding at the code. Yes it may be inefficient but a lot of the times you don't get an expected output due to some wrong logic. I guess manually analyzing code helps catch those.

Great read btw!

Collapse
 
simbo1905 profile image
Simon Massey • Edited

I set up a debugger to step through some open source code that I had volunteered to help out with. I was wanting to add a small feature so wanted to step through to get familiar. On the first step through the code I saw a bug that had been around a while and saw some dead code. I wasn’t looking for bugs but I was reading ahead and stepping and it suddenly did stuff that I mentally said “oh! why? that cannot be right...”.

This particular project is a bash tool to encrypt secrets in git called git-secret. No-one had run a debugger as its bash and folks don’t really thinks about debugging bash with breakpoints. Fortunately visual studio code on mac can integrate with bashdb and you can step through. So i made a video to show others on that project how to use a bashdb with vs code.

Maybe you will see something for the first time if you try stepping through code. Just a thought.

Collapse
 
lishine profile image
Pavel Ravits

Me too, never use debugger, just console.log

Collapse
 
charliechauri profile image
Carlos Echauri

Regarding to debugger vs. manual investigations, I think a good approach is to first do some manual investigation to get more context on what's going on and what could possibly be the root cause of the problem. Once you have an idea the real problem then you can totally use the debugger since it will save you some time. This is what I've done and it has worked for me 🤓

Collapse
 
markerikson profile image
Mark Erikson • Edited

Excellent post! Three other similar articles that are worth reading as well:

I will say that I've never tried the "tambourine" technique before. I'll have to keep that in mind next time I run into an issue :)

Collapse
 
nikpoltoratsky profile image
Nik Poltoratsky

Thank you for sharing those articles! I'll check them.
And yep, you have to try tambourine dancing. 😅

Collapse
 
cutiko profile image
Erick Navarro

I think the tambourine is very smart, frustration is the most common bug inducing and detouring factor; let's solve our internal issues with a nonsense ritual! As long as it is known as a ba ritual is great, in the minute it's become a hippy thing with spirituality, just move one

Collapse
 
nikpoltoratsky profile image
Nik Poltoratsky

Well said 🙃

Collapse
 
johannesvollmer profile image
Johannes Vollmer

Nice compilation! I think the most underrated debugging technique is static typing - the more things your compiler checks, the less bugs will appear.

Collapse
 
nikpoltoratsky profile image
Nik Poltoratsky

Yep, static typing can help you with reducing bugs, but I'm not sure it's a debugging technique 😅

Collapse
 
konstantinklima profile image
Konstantin Klima

I would just advise caution when doing console.log() on an object or an array objects you are tracking.
As i usually stick to backend languages, it really took me by surprise when I spent three hours basicly stripping several hundred lines of code in JS looking for a bug, just to realise that thr objects I was loging were printed out as they were at the end of execution and not in their current state for that current iteration as one would expect.
This was denoted by a little alert sign in chrome, which I checked out a bit too late. :D

An easy but boring workaround is to use JSON.stringify on the object when loging it. :)

Collapse
 
nikpoltoratsky profile image
Nik Poltoratsky

Thanks for sharing that tip. I've faced it multiple times and it still confuses me

Collapse
 
havarem profile image
André Jacques

Great advice. I like the "talk to a rubber duck!" A long time ago, my project manager was literally my rubber duck. I would talk about a problem and she would just "hmm hmmm" me for 3 minutes until I say "and... oh! wait a sec" to see everything resolve.

Furthermore, I would add this: baby steps. Either when you develop or debug, doing one thing and then make sure it works as intended will save you a lot of trouble. Sometimes it is easier said than done, you don't need to do TTD per se (but it will help you a lot). It is especially true in embedded system development when you do not necessarily have access to a console or have enough storage for log files. (Debugging with gdb on an embedded system that is time critical can be in the range of the impossible).

Collapse
 
mykezero profile image
Mykezero

Add breakpoints / console.log statements in every try/catch statement that you can find. Chances are, you may be swallowing the real problem, without even realizing it. I wish debuggers had an option to toggle this on when needed.

Collapse
 
simbo1905 profile image
Simon Massey • Edited

The argument that not using a debugging tool is better somehow reminds me of when I was startling out a friend in the office met someone who prided themselves at writing code that compiled and ran correct first time. This was C back in the 90s where your compiler would puke for an hour and your test cases would crash with memory errors without any output. It would take me 20 attempts to get anything none trivial to run before I could even start to check its inputs and outputs to begin to get the logic right. My friend had asked the craftsman how long it took him to write the code they were looking at. The answer was that he took about twice as long as our trial and error approach that involved having the tool (the compiler) give us fast feedback on where our intent had been mistranscribed into code. Yet the person was extremely proud that they wrote code the way they did.

I think the argument that not using a tool like a debugger is in some way more... I am struggling for an adjective... “effective” or “beneficial” seems a little strange to me. If you are having to fix bugs on a large codebase of a team you just joined the best technique is make the bug repeatable, fire up a debugger, and step through. Running a debugger accelerates finding and fixing and also learning the code. You read the code as you step through but are looking at what it does not what the code as written claims it does. I can think of no more effect technique. I could go without the tool and use only other techniques, or I can use the tool and other techniques, and be squashing bugs faster. The clue is in the name of the tool!

What about if its not a large strange code base? Write a unit test, bang out some code, set a breakpoint at the top, and step through the code rewriting and moving the breakpoint. I find this an effective way to get from “looks finished” to ready to ship. Maybe it doesn't work for everyone all the time but a debugger is is certainly a core tool that every dev should be able to run on their codebases.

Collapse
 
imtiyaz profile image
Mohammed Imtiyaz

Great Tips, Thanks Nikita!

Doesn't know it is called Talk to a rubber duck. I always follow this trick.

Collapse
 
idanarye profile image
Idan Arye

How does the tambourine work? It makes the other developers fix your bugs for you to make you stop?

Collapse
 
nikpoltoratsky profile image
Nik Poltoratsky

It's one of several possible applications 😃

Collapse
 
smartym profile image
Sergey V.

A great post with useful tips, thank you!

Collapse
 
mdhesari profile image
Mohammad Fazel

Thanks man that was excellent article about debugging!

Collapse
 
nikiiv profile image
nikiiv

Writing tech articles - you are doing it wrong. Putting around the 10 BASIC principles of debugging and slapping such title .. nah

Collapse
 
nikpoltoratsky profile image
Nik Poltoratsky

Thank you for sharing your criticism! I appreciate it

Collapse
 
yarmaa profile image
Yarmaa

Thank you man, it's a very good post :)
The last one is very funny XD

Collapse
 
simbo1905 profile image
Simon Massey

Just try it. The more people around the better it works.

Collapse
 
v6 profile image
🦄N B🛡

Only for back-end systems, though. There have been relatively few Tambourine debugging kits released for Java, though.

Collapse
 
vincajayi profile image
Vincent O Ajayi, PhD in Economics

Good!

Collapse
 
juancarlospaco profile image
Juan Carlos

If you really want to remove Bugs from your code:

  • Learn & use Design By Contract (Hoare Logic), TDD is poors man DbC.
  • Make variables Immutable, as much as possible, if your lang allow.
Collapse
 
lalo_tellez profile image
Lalo Téllez

On the comment your colleage did about debugger I agree, but the truth is almost no one has all the time in the world to search bugs manually, which usually takes longer.

Collapse
 
ashekhawat32 profile image
IamLegendChamp

The collection of all sorts of debugging was really helpful. Now I know where to look at. Thanks :-)

Collapse
 
adusoft profile image
Geofrey Aduda

I normally make a copy of the affected Code and undo my code step by step until I reach the point where the error might have occurred. Done

Collapse
 
bwilcutt profile image
Bryan Wilcutt • Edited

Real programmers don't use silly operating systems and, if they're lucky, they can twiddle an LED for debugging.

Collapse
 
nikpoltoratsky profile image
Nik Poltoratsky

oh my gosh 🙃

Collapse
 
zeslova profile image
Simon Newby

Jacob Herrington's article on git bisect is great and a lot less dry than the documentation. dev.to/jacobherrington/git-bisect-...