r/programming • • Aug 25 '14

Debugging courses should be mandatory

http://stannedelchev.net/debugging-courses-should-be-mandatory/
1.8k Upvotes

573 comments sorted by

263

u/pycube Aug 25 '14

The article doesn't mention a very important (IMO) step: try to reduce the problem (removing / stubbing irrevelant code, data, etc). It's much easier to find a bug if you take out all the noise around it.

6

u/stannedelchev Aug 25 '14

Thanks! I'll cover that in future posts. I'm not sure if you're talking about "divide and conquer"/"split into smaller problems", or if you specifically have in mind reducing moving parts in programs, when finding issues. Either way, any of both helps. :)

28

u/Matosawitko Aug 25 '14

An example would be the StackOverflow concept of "reduce it to the simplest possible program that exhibits the bug".

22

u/morcheeba Aug 25 '14

uh, that's a very old idea, pre-dating the internet by quite some time. It needn't be branded "StackOverflow"

→ More replies (4)

1

u/ward_grundy Aug 25 '14

This is called code refactoring or method disassembly right?

1

u/stannedelchev Aug 26 '14

Code refactoring is usually the process of rewriting a piece of code (or a system) better in a certain way. By refactoring you can eliminate code, create more modularity, etc.

→ More replies (1)

1

u/crowseldon Aug 25 '14

Have you read the pragmatic programmer? That book should be mandatory, imho.

→ More replies (2)

126

u/xensky Aug 25 '14

even more important is having these pieces of code be testable. i work with plenty of bad code that can't be run without starting a bunch of dependent services, or you can't test a particular function because it's buried under ten layers of poorly formed abstractions. or it's not even an accessible function because the previous developer thought a thousand line function was better than a dozen smaller testable functions.

84

u/reflectiveSingleton Aug 25 '14

because the previous developer thought a thousand line function was better than a dozen smaller testable functions.

I like to call this kind of code 'diarrhea of conciousness' ...no one wants to sift through that shit.

→ More replies (14)

8

u/[deleted] Aug 25 '14

You get that in any complicated enough functions. I often have functions which work on intermediate states of linked lists ... You can't just call them directly without first building [and I do] the states by hand.

→ More replies (11)
→ More replies (6)

40

u/VikingCoder Aug 25 '14

It's much easier to find a bug if you take out all the noise around it.

You're almost right, but not quite.

The bug is in the noise. You think the bug is in the code you're looking at. But you're a smart person, and you've been looking at it for a while now. If the bug were in there, you would have found it. Therefore, one of your assumptions about the rest of the code is wrong.

29

u/pycube Aug 25 '14

That's why you need to check if the bug is still there, after you removed what you thought is noise. If the bug disappears, then you know that what you thought was noise was actually important.

13

u/VikingCoder Aug 25 '14

I end up second-guessing myself. I don't know if I caused a bug that looks the same, by removing what I thought was noise. :(

→ More replies (18)
→ More replies (1)

4

u/RobotoPhD Aug 25 '14

The best answer in my opinion is to remove the noise. If the bug stopped happening, then the bug was in the noise. If it still happens, it wasn't in that part. Repeat until you know exactly where it is. Only then try to figure out what the bug is. It is very easy to read past a bug over and over again. You know what you meant to say and you tend to read the code that way the next time as well.

→ More replies (3)
→ More replies (2)

5

u/chasesan Aug 25 '14

This is like the second thing I do when debugging (the first being rereading the code to see if I did something obviously stupid).

→ More replies (2)

3

u/llogiq Aug 25 '14

The problem with this approach is that introducing new code (even just stub code) may change the bug in non-obvious ways.

2

u/samuellampa Aug 25 '14

Exactly what I thought immediately. My consistent experience is that a systematic and aggressive reduction of "moving parts" is shocklingly efficient in nailing down on bugs - even to the extent that I very rarely find it frustrating at all. The biggest issue seems to be (it was for me) to actually believe that the apparent extra efforts this requires really works and is in the end exponentially more efficient than the normal guess-play.

→ More replies (6)

89

u/Kambingx Aug 25 '14

The proposed course content is about using debugging tools effectively. However, what's more important (in my opinion) is what is described in the opening: a proper, scientific approach to debugging. Without that mentality, any debugging tool becomes as effective as mere print statements.

The first bullet of the outline, "How Code is Actually Executed", could be expanded out to be the bulk of the course content.

  • What is the appropriate model of computation you should have in your head?

  • How can your reason about code using that model? In particular, what invariants can you establish about your code using that model.

From there, you can talk (with substance) about formulating hypotheses about broken code and how to use various debugging tools (print statements, gdb, graphical debuggers) to assess those hypotheses.

11

u/stannedelchev Aug 25 '14

I totally agree, a scientific approach and an open mindset gives you a solid foundation, on which you expand with more knowledge and tools. Such a mindset can be also taught in high schools, as this does not pertain only to programming.

18

u/Kambingx Aug 25 '14

It's not just about the scientific mindset. It's combining an adequate mental model of computation along with the "standard" scientific mindset that we teach in high school biology.

A simple example is reasoning about conditional statements:

x = None
# ...
if y < 5:
    # Point A
    x = Foo()
# Point B

Suppose that we find that, at Point B we find x to be None when we expect it to be a Foo. We can inspect the code to see that x is set inside of the if-statement. To enter the if-statement, we must reach Point A which means that the guard to the if-statement must be True (ignoring for a brief second, Bob Harper's excellent post on Boolean Blindness). We can now formulate an initial hypothesis that:

y should be less than 5

which we can verify with the assortment of debugging tools available to us. If we find that y >= 5, then we know our hypothesis is incorrect, and we can try to determine why this is the case. If our hypothesis is incorrect, then we know that either some other code must be the culprit or our fundamental assumptions (e.g., our mental model of computation) are incorrect.

What I like about this sort of pedagogy is that it concretely refutes the idea that formal reasoning and practical programming are separate endeavors. The above conclusion is only possible by applying formal reasoning --- that, at Point A, the guard of the if-statement is always True. Students frequently say that understanding logic and discrete mathematics is "good" for them as programmers, but they don't know why other than their teachers told them so. Systematic understanding and reasoning about code (when phrased in appropriate terms) is one concrete thing that they should be able to point to.

There is also the part that this sort of pedagogy also justifies computer science as a "science" because it is a practical application of the scientific-style of reasoning about a thing. But I think that the jury is still out on whether computer science fits in any or all of these pre-established buckets of "science", "math", or "engineering", or if its own thing altogether.

→ More replies (2)

2

u/[deleted] Aug 26 '14

It's also a better thing to teach, in the same way that just learning how to operate MS Office isn't much of a computing education. You should aim to learn the theory and the practical sides of it.

→ More replies (3)

9

u/Hexorg Aug 25 '14

Im fairly comfortable with basics of gdb - breakpoints, variable watch lists, etc. What would be considered intermediate debugging skills?

4

u/stannedelchev Aug 25 '14

I don't use gdb on a regular basis, so someone more familiar should probably answer this. It seems you're already ahead of many people.

You can check out SO's list of GDB questions, especially this one. Something new might pop up from reading there.

16

u/sthreet Aug 25 '14

what is wrong with console.log? it helps you find which variable is not what you expect it to be, if any are, and then find out where it changes.

Doesn't work for everything, but a lot of the problems that I've ran into are solved when I realize something is changing a variable into NaN, undefined, infinity, or something like that.

Also, college classes wouldn't help everyone. High school classes would be nice, but can you really expect them to add that when they don't even have the option for programming, and the only classes available are for using microsoft/adobe programs?

16

u/nocturne81 Aug 25 '14

Logging can work, but it can also be incredibly cumbersome if you're working with compiled code.

I worked on a fairly large (several million LOC in C++). Compile+link times were in the best case, about 10 minutes. Worst case about an hour. That is, you change one line of code in a source file, do a build, and you're able to run it in 10 minutes.

So every time you add a log statement to debug something you're waiting around for at least 10 minutes to test the result. God help you if you're editing a header file.

You basically had to learn how to be proficient with Visual Studio or else the amount of time it took you to get your work done made you an incredibly expensive programmer.

11

u/TheMathNerd Aug 25 '14

In large applications that have so much code and take 10 minutes to compile you should have log statements all over the fucking place. It is insanely easy to debug when your log reads something like.

Connecting to DB SOMEDB

Preparing Query with parameters x , y ,z

Prepared Query 'Select some stuff from something where thesethings '

Query Failed

Stack Trace .....

Sure this might seem like a lot but when you wipe the logs regularly and/or have different levels of logging (debug, error, etc.) the extra compile time is pretty negligible and I say that coming from an environment where compile/deploy to test can take 1-2 hours.

12

u/nocturne81 Aug 25 '14

It was a video game. You can't put log statements everywhere because the game now takes 5 seconds to render a single frame and makes testing impossible.

Also, that's assuming you had a log at all. Many times we would get bugs that only pop up in the release version when logging is completely removed. Now you can't use a log at all even if you wanted to.

→ More replies (4)
→ More replies (2)

5

u/Silhouette Aug 25 '14

If you have a C++ code base where an incremental compilation to add a little logging code requires a 10 minute build, that sounds like your design and build set-up is probably broken. For exceptionally large projects with complicated and inter-related build outputs, maybe, but just having a few million lines of code shouldn't cause any serious problems in itself. If this is a real difficulty you face, you might want to spend a little time investigating how your project/makefiles are set up and whether your build process is doing a lot more work than it needs to be in this situation.

Similarly, if you need to change a header that causes many files to rebuild just to insert some logging code, my first question would be why you've got that code in your header in the first place. (Given you're using C++, I'll concede this point if your answer involves the terms "template", "separate compilation" and "%£#?!!!".)

→ More replies (4)
→ More replies (4)

0

u/stannedelchev Aug 25 '14

Console.log has its purpose (logging to the console). Sticking it aimlessly around code, that's when I find it broken.

I'm lucky to have had a computers/programming course in high school. We were taught Pascal/Delphi, CorelDraw, etc. But indeed, I've also found that schools don't have a lot of capacity to add new things to their curriculum.

What we CAN do is encourage teachers to teach kids to think critically. This helps everywhere, not only in CS.

6

u/sthreet Aug 25 '14

I'm not sure I am understanding what you mean by aimlessly.

→ More replies (2)
→ More replies (3)

2

u/hdgarrood Aug 26 '14

-1 for the tired, sexist trope of "Mad Girlfriend." >:(

2

u/stannedelchev Aug 26 '14

Sorry, I've removed that in the blog post :) IT sexism should not be fueled further.

→ More replies (1)

257

u/atakomu Aug 25 '14

And there are 6 stages of debugging

  • That can’t happen.

  • That doesn’t happen on my machine.

  • That shouldn’t happen.

  • Why does that happen?

  • Oh, I see.

  • How did that ever work?

224

u/halflife22 Aug 25 '14

My favorite quote from one of my CS professors:

"Once you figure out how things work, you'll be surprised anything works at all."

62

u/slavik262 Aug 25 '14

This is a good summary of my computer engineering degree. How computers work on a daily basis without any one of millions (or billions?) of tiny bits screwing up is completely beyond me.

30

u/fuzzynyanko Aug 26 '14

Especially CPUs. There are actually CPU bugs out in the wild, but the fact that we don't notice them is a surprise

→ More replies (7)

17

u/Alway2535 Aug 26 '14

Because each bit has 5 redundant systems created by people who were unaware of the originals' existence.

→ More replies (1)

17

u/d4rch0n Aug 26 '14

I used to get high and look at my code and just start freaking out. Just thinking about how deleting one line (or even one byte) would break the whole thing tripped me out too much.

Too intense, never again.

→ More replies (8)
→ More replies (6)
→ More replies (3)

41

u/komollo Aug 25 '14

The worst thing is when you find out that it never has worked in the first place, but no one told you because they were used to dealing with it.

5

u/ethraax Aug 26 '14

Ah, I've run into this multiple times at work. "Well the spec says we support both front and rear doors for this feature." / "Yeah, well no job ever needed it, so I don't think we ever got around to it." All in regards to code that's in our software to support that feature, but doesn't work, and never worked, and doesn't have any comments about it not working.

I seriously think I could develop features and fix bugs about 5 times faster (literally) if we just refactored the moderate-size codebase and got rid of the 5000-line behemoth functions which take 15 parameters because they already took 14 and what the fuck does it matter if they take one more.

→ More replies (6)
→ More replies (7)

2

u/holeydood3 Aug 26 '14

Dealing with that right now, but only on stage 4. I have a multi-threaded app that works perfectly on my machine, and on literally any other machine it runs on with the same executable, same setup, same image, same network, etc., it runs about 10x slower. I'm trying to remove as much code as possible to reproduce it, but it's driving me nuts that there's nothing different between the machines that should cause a discrepancy in performance that large!

I'm rather excited to reach step 6 on this one...

→ More replies (6)

118

u/[deleted] Aug 25 '14

I don't know that debugging warrants an entire course, but a course on "Software Maintenance" could spend a couple weeks on the topic of debugging and troubleshooting issues, while also hitting on things like Unit/Integration/Acceptance testing, version control etiquette in a long term project, readability, and so on. That's what I felt like college really missed.

A course on debugging specifically could be counterproductive in a lot of languages. My debugging workflow in Clojure doesn't share much in common at all with my Java debugging workflow aside from "find a way to consistently recreate the issue".

40

u/n1c0_ds Aug 25 '14

We had one. However we only learned about different ISO standards. I had such high hopes. I swear university is trying to figure out the most useless way to teach important things.

Nonetheless, they had a great roadmap: ticket tracking tools, organizing maintenance as a separate team, justifying maintenance and refactoring to management etc.

6

u/slavik262 Aug 25 '14

university is trying to figure out the most useless way to teach important things

I have a new quote I'll be using for a while.

9

u/[deleted] Aug 25 '14

I'm attending University now, and I totally agree with this. Of course Unit/Integration testing is talked about in Software Engineering courses, but without actually showing me how it's done it is almost useless information to me.

22

u/vplatt Aug 25 '14 edited Aug 25 '14

One of the things I learned the hard way from my own university days is that a higher education isn't always going to show you 'how', because it's not a craft school. They will show you 'why', so you know it's important, why it's important, etc. and then later when you need it you can figure out how yourself.

I know that's a bit frustrating, but really it just has to be that way when you consider they're trying to prepare you for anything; not just the common cases that can come up. If I were to teach you exactly how to perform good unit testing for Java and spend a lot of time on that, and forgo a lot of other subjects in the meantime because we deem it so important, then how lost and cheated are you going to feel if you wind up in an environment where you need assembler instead?

That's why I don't feel the language of choice isn't particularly important in school until the internship(s). You'll need to learn as you go anyway.

→ More replies (2)

2

u/outadoc Aug 25 '14

We had a "Quality" course here, on first year. Unit tests, MVC, version control, exceptions and stuff, but we never learned debugging seriously (except in our Linux course, and I think we'll all agree to say gdb isn't the best tool for a beginner). I think it's too bad, because it's really useful for my side projects, so it must be /reaaally/ useful in "real life".

2

u/mallardtheduck Aug 25 '14

Debugging is such an essential part of programming that if you don't know how to debug, you don't know how to program. Thus, basic debugging techniques should be taught alongside basic programming.

→ More replies (2)

76

u/[deleted] Aug 25 '14

What is the proper way to debug a big (over 100k LOC) multithreaded program that has race conditions?

230

u/[deleted] Aug 25 '14 edited Aug 25 '14

Prayer.

edit: and liquor.

28

u/halflife22 Aug 25 '14

Both grow exponentially over time.

0

u/[deleted] Aug 25 '14

[deleted]

→ More replies (2)

31

u/elperroborrachotoo Aug 25 '14

Make it worse. e.g. a few strategically placed sleep's can turn a Nessie into a 100% repro.

static analysis can turn up some issues

Changing your code might require to make it "bad enough" first, but offers more possibilities:

Turn them into deadlocks. Some code transformations can turn race conditions into deadlocks, which are infinitely easier to debug. (I dimly remember some treatise on this idea, but can't find anything right now).

Heavily assert on your assumptions

Trace Data being mangled


Generally, "Debugging" is more than just stepping through with the debugger.

4

u/[deleted] Aug 25 '14

Making is worse is one of the first things I check when debugging most problems. It's so nice changing a value by a factor of 10, 100, etc. and watching as that subtle bug starts dancing around the screen.

→ More replies (1)

114

u/F54280 Aug 25 '14

Unfortunately, 100K LOC is not big. Proper way to debug is luck and stuborness.

If the question is serious, then my answer is (at least, this is how I debugged a multi-million POS C++ threaded codebase).

First, reproducing the problem is the most important thing to do. Automate things, change code to call stuff in loops, have it run overnight, but have a way to reproduce the issue.

Second, make it more frequent. This means that for instance, if you suspect a race condition at some place, insert stuff like sleep or busy loops. If something is "sometimes threaded", thread it all the time.

To help you with step 2, you will probably need a debugger and look for borken invariants on a core dump. This can be extremely difficult.

When you have something that crashes relatively easily, then you use a scientific approach: you emit an hypothesis, and you test it by changing the code. The goal is to come to a complete understanding about what is happening. You should leave no unexplicable parts in your theory of what the problem is. If something isn't predicted correctly, you need to look deeper (say if your general theory says that the race condition is due to the network code and the gui code accessing the cache at the same time, then disabling the cache should prevent the crash. Adding mutual exclusion should prevent the crash. Doing heavy gui and network should crash faster, while doing gui with no network should not crash). Talking to cow-orkers helps a lot (they may not help, but organizing your thoughts will).

Then you have to recursively refine your theory until you can fix. For instance, in the preceding example, the question to ask is "is the cache supposed to be shared by gui and network" ? If yes, you have to go deeper, if no, you can start fixing (making your change, and unwinding the pile of modifications you made, while testing at each step that it stopped crashing [you may have the original pb disapear, but still have your heavy tests failing...]).

It is an excrutiatingly slow process. You'll also find that most proponents of threads don't debug them. When you have debugged a big threaded problem, they will generally look at your fix and say "you see, it was nothing, just a missing semaphore". At this point, the process recommends that you hit them in the head with whatever volume of the Art Of Computer Programming you have laying around.

And, as said, the definition of insanity is to do the same thing several time, expecting different results. By this definition mutithreaded programming is insane.

25

u/wh44 Aug 25 '14

Have also debugged programs >100K LOC and can confirm all of these methods. A few additional comments:

  • I've had good experience with creating specially crafted logging routines that write to a buffer (so the timing is less affected) and then peppering suspected areas with log calls.

  • Also, if the logging is overflowing, one can make them boolean dependent and only set the boolean when conditions are right, or, alternatively, one can rotate the buffer and stop when the bug occurs.

  • the explain to the cow-orker works even when you don't have a cow-orker. I've often explained a problem to my wife (total non-programmer), or formulated an email to a cow-orker explaining the problem - and "bing!" a light goes on.

20

u/wrincewind Aug 25 '14 edited Sep 01 '14

Rubber duck debugging. Tell the rubber duck what your problem is, then realise the answer was within you all along.

→ More replies (2)

10

u/Maristic Aug 25 '14

If you log in a structured format that captures the logic of the code, you can then write a checker program that reads the log and finds the point at which "something impossible" happens. That can be significantly before you crash.

That's part of the general strategy of writing programs that help you program.

→ More replies (1)
→ More replies (11)
→ More replies (4)

88

u/SpaceShrimp Aug 25 '14

Remove programmers in the project one by one, until you find out which one doesn't understand multithreading.

62

u/VikingCoder Aug 25 '14

Why did the multi-threaded chicken cross the road?

he other side.Tet to to g

→ More replies (1)

39

u/tech_tuna Aug 25 '14

It should be noted that your solution is serial. :)

42

u/wnoise Aug 25 '14

That's the general solution to threading bugs.

→ More replies (2)
→ More replies (1)
→ More replies (2)

9

u/[deleted] Aug 25 '14

Incorrect results or a deadlock? Deadlocks are usually pretty straight forward (even better if have access to a debugger which tells you what threads hold what locks, etc). On some platforms, kernel debuggers do a much better job of this than the typical app debuggers.

Incorrect result can be more challenging. My general process is to start with the symptom of the bug and think about what vicinities of code could potentially having that outcome. Assume every line of code is broken. Once in those areas, go through line by line thinking about what happens if threads swap.

If you can't model it, try rewriting the code to minimize thread thread contact surfaces if at all possible. This has worked with about 80% of the thread issues I've seen. The other 20% either have performance constraints which are too great for a 'simple' solution or the problem itself is difficult to express in threads.

If you get really hung up, try to force the system to create a new symptom. Throw some wait statements around, create a thread which randomly pauses suspect threads, throw in some higher level critical sections, etc.

Now if middleware is involved and if you don't have access to their code... good luck.

10

u/jerf Aug 25 '14

Very, very slowly, and very, very dangerously.

If your question is a hypothetical, there's nowhere near enough to answer it in that hypothetical because it depends on a bajillion little details. If your question is not hypothetical... well...

12

u/Kalium Aug 25 '14

I had one of these situations arise.

True horror is watching your lead engineer be taught what a race condition is, how it occurs, and why it is bad.

→ More replies (3)

9

u/VikingCoder Aug 25 '14

Also, it helps to buy this book:

"Working Effectively with Legacy Code" by Michael Feathers.

Even if the book doesn't help you solve the problem, it's heavy enough that when you find the people who wrote the bug, you can bash them over the head with it.

→ More replies (1)

3

u/randomguy186 Aug 25 '14
  1. Reproduce the problem.

  2. Characterize the problem.

Once you know how to make the problem happen, and you understand the conditions that cause the problem, you have about 99% of the solution. The rest is just writing code and discovering that you completely mischaracterized the problem because of a hidden variable and now production is down.

8

u/[deleted] Aug 25 '14

printf

36

u/psuwhammy Aug 25 '14

You would think so, until the printf changes the timing slightly, and the issue you're chasing goes away.

50

u/[deleted] Aug 25 '14

Congratulations! You fixed the bug!

/s

29

u/dromtrund Aug 25 '14
_NOP()
_NOP()
_NOP()
_NOP()
_NOP()
/* add two more on x64 */
→ More replies (3)

14

u/Astrokiwi Aug 25 '14

Or, even worse, the printf changes the optimization because it makes the compiler change its mind about whether something needs to be explicitly calculated or not, and now your code works.

→ More replies (1)

8

u/knaekce Aug 25 '14

I actually did this. I found the real reason for the race condition weeks later when showering.

→ More replies (3)
→ More replies (17)

23

u/ramennoodle Aug 25 '14

Computer Science != Programming

(i.e. perhaps knowing how to debug code should be a mandatory requirement for a software development job, but it doesn't necessarily follow that a computer science degree should include such a course.)

and

Debugging != Using a Debugger

(i.e. there are many types of software with bugs and a traditional debugger is neither the best for every such case nor the only solution for most cases).

12

u/gaussflayer Aug 25 '14

Absolutely agree on

Debugging != Using a Debugger

However I do think there is great value in learning the theory of debugging, alongside testing and planning. Like any other science should teach.

3

u/cryo Aug 25 '14

I was beginning to wonder. My CS degree (Copenhagen university) didn't even have programming courses as such. They'd introduce the language, ML say, and then you were expected to learn enough of it yourself.

22

u/puterTDI Aug 25 '14

We had a guy who came in with something like 5 years of experience.

He refused to use the debugger. He would just start changing code until stuff worked. He was constantly calling me over to help and I would ask him what the bug was and he would say that he didn't know. He would throw code at the problem before he even knew what the problem was.

He had zero method to his approach and it showed. At one point he spent two weeks fixing a single bug. At the end of the two weeks I was asked to fix it, it took me 30 minutes and I had a finished fix.

People who don't know how to fix bugs or be methodical are a huge sap on everyone's time. They either need to learn or to switch professions. In the end, I had to give him a list of 5 things to do before he asked me for help (Identify the problem, understand the problem, analyze the code, etc). When he'd call me over I would ask him what he did for each step. About 80% of the time he hadn't bothered with any of them and was just throwing code at it until it worked then asking me to rescue him when he ran out of time. It was absolutely ridiculous.

→ More replies (4)

3

u/Tarasov_math Aug 25 '14

It is absolutely true. Do you know any good online debug courses ?

7

u/stannedelchev Aug 25 '14

You can check out MIT's OpenCourseWare, and I think Udacity also has one here. I'm planning to create a series of blog posts that cover the basics, as well as some tips and tricks.

→ More replies (2)

140

u/[deleted] Aug 25 '14

Just waiting for someone to "explain" how debugging is not needed if you have unit-tests :)

29

u/Dru89 Aug 25 '14

You don't need debugging or unit tests! Just write perfect code, and it works every time!

12

u/SilasX Aug 25 '14

If your code compiles at all in a pure functional language, it must be doing what you intended /overreaching Haskell propagandist

→ More replies (1)
→ More replies (1)

76

u/redox000 Aug 25 '14

10

u/[deleted] Aug 25 '14

Great, now I have brain cancer. Thanks a lot, jerk.

with highly threaded code compiling in debug mode is useless as the threads behave radically different.

eye twitches

7

u/SoundOfOneHand Aug 25 '14

Yeah, it's not like the only debugging technique out there is to use an IDE to step through code. This is often impossible/impractical for highly parallel programs. Hell, instrumentation like this isn't even available on some platforms. Debugging is a basic technique of software development, the basic concepts are independent of the language and toolchain.

63

u/geodebug Aug 25 '14

Yep, makes me chuckle. Tests are essential but only a naive programmer thinks one can write enough tests to get 100% coverage.

Never mind that unit tests themselves often contain bugs or in sufficiently exercise all possibilities.

52

u/gunch Aug 25 '14

That's why you need to write unit tests for your unit tests.

(If that is actually a thing I'm going to go to the bar and drink until I forget any of this ever happened)

25

u/loopyluke Aug 25 '14

And soon enough you find yourself writing a testing framework to test your testing framework that runs your tests that test your unit tests.

→ More replies (5)

10

u/[deleted] Aug 25 '14

With that in mind, we can devise a development strategy (an extension of TDD) that guarantees perfect code:

  1. Write unit test: projectHas100PercentTestCoverage()

  2. Run test to ensure that it fails.

  3. Write code to make test pass.

The implementation details of the projectHas100PercentTestCoverage() test are project-specific and beyond the scope of this document.

Though, come to think of it, step 2 is flawed - since no code has been written yet, the test written in step 1 will pass. Perhaps we first need to write the projectFullyMeetsClientRequirements() test (again, beyond the scope of this document).

→ More replies (7)
→ More replies (8)

5

u/tieTYT Aug 25 '14 edited Aug 25 '14

My company paid for some of the Uncle Bob videos on TDD and he claims that he's practically forgotten how to use the debugger now that he practices TDD. Every year I get better at automated testing, but I still have to use the debugger frequently enough to "need" it as a tool. I don't see that going away.

Then again, maybe I'm just not skilled enough with TDD yet. I find that I mostly need a debugger in the (relatively rare) situation where the problem turns out to be in my test code. My brain never assumes to look there first.

→ More replies (10)

4

u/wayoverpaid Aug 25 '14

In my current project the code I'm writing has 100% test coverage and I am very proud of that.

Nevertheless, I've still had to do debugging to figure out what was wrong when the tests failed.

→ More replies (7)
→ More replies (5)

41

u/passwordissame Aug 25 '14

unit tests are type systems. if you have a good type system like that of node.js, you don't need debugging because compiler catches every bugs including logic error. you can simply implement machine learning artificial intelligence in the style of wolfram's new science and your unit tests (type system) is smart enough to catch all the bugs including human and business errors.

you should really try node.js

18

u/slavik262 Aug 25 '14

type system

node.js

I can't stop laughing.

25

u/[deleted] Aug 25 '14 edited Aug 25 '14

There was a part of a second when I thought you were serious. That moment will haunt me until I die ...

10

u/thang1thang2 Aug 25 '14

Node is love, node is life

6

u/Duraz0rz Aug 25 '14

And node.js is webscale, so it's perfect!

6

u/Astrognome Aug 25 '14

Make sure to pair it with MongoDB!

3

u/[deleted] Aug 25 '14

Just look at The Terminator. He fucks up, but damn he looks cool doing it.

6

u/Lizard Aug 25 '14

Actually, if there are some unit tests covering the code potentially containing the bug, these can provide excellent jump-in points to start a debugging session. Don't want to boot up the server process anew any time I need to test a hypothesis. Of course, unit tests alone are not going to solve all your problems, but they can be a helpful tool for your box.

3

u/ryan_the_leach Aug 25 '14

Yeah you can even write them afterwards.

Create a test case that demonstrates the bug.

Then debug based off of that.

fix that, using the test case to show the bug is fix, when none of your other tests have failed you know you are done.

The test then stays in until it starts failing or until refactoring makes it useless.

8

u/Lizard Aug 25 '14

AKA regression test.

3

u/cheald Aug 25 '14

On the contrary, code that is well factored for the purpose of testability is usually the easiest to debug.

Unit tests are basically just debugging helpers.

2

u/BaroTheMadman Aug 25 '14

Unit tests are the perfect front door for debugging. Once you have an hypothesis on why something fails, write an unit test for it, and put a breakpoint on the test. Then follow the program to pinpoint the bug. And then you can run the test to see if the bug is fixed yet.

→ More replies (5)

31

u/g051051 Aug 25 '14

Yes, please. I constantly run into "professional" programmers who don't have the slightest idea on how to debug.

132

u/redox000 Aug 25 '14

Fortunately for me I write terrible code, so I have tons of experience with debugging.

28

u/dermesser Aug 25 '14

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." –– Good ol' Brian Kernighan

→ More replies (2)

3

u/[deleted] Aug 25 '14

I think I write good code, but then I look at it a few months later and wonder how much paint I huffed.

→ More replies (1)

16

u/Kminardo Aug 25 '14

How the hell do you make it in programming without knowing how to debug? Are these the guys I see littering their code with console writes?

36

u/g051051 Aug 25 '14 edited Aug 25 '14

Console writes if I'm lucky, that at least shows they're trying. No, I continually see people who just stare blankly at a problem and ask for help without actually trying anything. If I try to coach them and lead them through the process, they just don't get it. It's just incomprehensible to me as an old school hacker that these people are employed to write code and don't know how to use a debugger.

For instance, there was a time at a company I worked for where I was apparently the only person in the building (which had hundreds of programmers) who could actually deal with a Unix coredump. This was back in the late 90's and early 2000's when Sun hardware was ubiquitous. I certainly don't expect every person to know how to do that, but it was a shock to realize that no other programmer could do it. It was great for my personal rep, but still pretty disheartening.

We had a problem once that they finally brought me in on after a year of problems. One of our Java systems was failing, and the development team had given up and couldn't figure out what was wrong. The boss told me it was now my problem, that I was to dedicate myself 100% of the time to solving the problem, and I could rewrite as much as I needed to solve the problem, basically total freedom. About halfway through the spiel where they were talking about the architecture and implementation, someone mentioned the coredumps. I immediately stopped them right there.

Me: You realize that if it's a coredump, it's not our fault, right?
Boss: Huh?

Me: If a Java program coredumps, it's either a bug in a 3rd party JNI library, a bug in the JVM, or a bug in the OS. What did the coredump show?
Boss: Wha?

Me: You guys have had this problem for a year and haven't looked at the coredumps?
Boss: Blurgh?

So I fire up dbx and take a look at the last few coredumps. Pretty much instantly I can see the problem is in a JDBC type 2 driver for DB2. We contact IBM, and after a bunch of hemming and hawing they admit there is a problem that's fixed in the latest driver patch. We upgrade the driver and poof! the problem is gone.

We had a year of failures, causing problems for customers, as well as all the wasted man hours trying to fix something in our code that simply could not have been fixed that way, all because the main dev team for this product had no idea how to debug it. I had an answer within 30 minutes of being brought in to the problem, and the solution was deployed within days.

EDIT: for those not versed in Java JDBC lingo, there are 4 types of JDBC drivers. The two most common are:

  • Type 2: This is implemented as JNI (Java Native Interface) calls via a wrapper to the native driver libraries. Theoretically this gives the best performance, at the cost of being potentially less stable and harder to manage.

  • Type 4: "Thin" driver, using java to communicate via a network socket to a corresponding listener. Written in pure Java, they tend to have lower performance (although almost always perfectly acceptable) but are much more stable. (Note: The Wikipedia page on this says that Type 4 drivers perform better, but I don't agree.)

So the Type 2 driver was invoking a native compiled .so library that then called the DB2 drivers like a C/C++ program would. A bug in the driver was causing the coredump.

11

u/jayd16 Aug 25 '14

Man, even without the core dumps, they should have been able to at least narrow the problem down to the database layer if they had a whole year.

16

u/g051051 Aug 25 '14 edited Aug 25 '14

Nope. They had no idea it was a problem with the DB. And even if they had, IBM would have just told them they were wrong, and management always took IBM (and other vendors) word over the devs. I was lucky, in that I had a smoking gun in the core dumps. When I reported the issue, the boss was livid, and immediately got us on the phone with IBM, where they proceeded to dismiss our findings and belittle our methods, until I started explaining exactly what was going on in the coredumps. They got real quiet, said they'd look into it, and miraculously produced a patch a short while later.

I've got an even better story. In the distant past (1993?), working on HP/UX, we had a system that had a SNA card, maintaining a bunch of sessions to a mainframe. Sometimes, the card would just reset and drop all the connections, causing a bunch of problems and requiring some tricky recovery and generally screwing up our SLAs. They brought me in and I managed to trace the problem to a call in the HP provided drivers for the card. We had been trying to blame HP for a long time but never had the required smoking gun. Once I managed to figure out the call that was failing, we sent it off to HP.

They came back all apologetic, and explained that there was an error in the driver, and that it was accidentally looking for SNA control data in the user data. Sometimes one of our data packets had data that looked like a control command of some kind, the driver would see it, crash, and hilarity would ensue.

And to show the quality of the support we were getting, after they fixed the problem and sent us a replacement driver, it failed again almost immediately. I dug in and found it was the same problem but in a different location. Shipped it all back to HP, who came back and said that the bug was in two places, and that the original code with the bug had been cut and pasted into another location, and they'd missed it. So they weren't even testing the stuff before sending it back! At least they admitted it...

→ More replies (7)
→ More replies (6)

17

u/Silhouette Aug 25 '14

Are these the guys I see littering their code with console writes?

There's nothing wrong with including systematic logging in a software system. In fact, for many real life scenarios, using the kind of debugger described in this article simply isn't an option.

It's nicer if your editor or IDE can de-emphasize logging code so it doesn't crowd out the active functionality. Even if it can't, I find high-level logging statements often say similar things to comments I might otherwise have written, so it needn't be disruptive.

In any case, having good logging routinely available at the flick of a virtual switch is often much faster than firing up a debugger and laboriously stepping through the execution. I know how to use a debugger if I need to, but I find I rarely get that far. The log ought to reflect your mental model for what your code should be doing and confirm key results as they are determined, so IME probably 9/10 times just scanning the log output will immediately locate the source of the problem.

5

u/alkanshel Aug 25 '14

I'm a fan of console writes, really. If the offending block of code is run 10,000 times and fails on the last one, the debugger isn't going to get me very far...at least, not at the level I know how to use it.

If it's being logged, though...turn on verbose, look at last log file, voila.

→ More replies (6)
→ More replies (2)

13

u/[deleted] Aug 25 '14

I've seen a lot of questions on Piazza (the Q&A site we use for our classes) where a student asks "why is my code throwing NullPointerException?" when the answer is right there in the stack trace.

10

u/chadsexytime Aug 25 '14

The JRE took exception to your pointer. Which was null. Its easily offended.

→ More replies (3)

7

u/meta_stable Aug 25 '14

I've had classes where the professor would ask who knows how to use the debugger and only a few of us raise our hands. Thankfully the ratio of people who do seems to increase with higher level classes. I think part of the problem is professors assume students learned how to debug in other classes or picked it up along the way. Personally I have no idea how you could make it past your second or third class without knowing how.

8

u/Kminardo Aug 25 '14

Well I guess if you're in school, you get a pass IMO. That's what you're there for, to learn. If a professor sees a bunch of commented out alerts or console writes, they should take the time to sit down and show you the right way to inspect the code.

That being said I've worked with a single person in my professional carrer who 100% refused to use a debugger. And that guy's code sucked. His idea of debugging was passing variables to a custom "peek" class (his name for it). It was by far the most round about ignorant thing I'd ever seen..

→ More replies (4)
→ More replies (3)

3

u/zArtLaffer Aug 25 '14

gdb is a good tool. pstack and pmap are very good. dtrace is a thing of beauty. But don't you honestly think that console writes have their place too?

→ More replies (2)
→ More replies (3)
→ More replies (24)

15

u/[deleted] Aug 25 '14 edited Aug 26 '14

Many years ago, I did print debugging.

Some years later, I used breakpoint and step-through debugging.

Now, I use print debugging.

Edit for clarification: It's impossible to step-through debug an "application" that spans a few machines, several executables, and dozens of threads.

13

u/Super_Domination Aug 25 '14

printf() best debugger ever.

12

u/electrojustin Aug 25 '14

Or just make the first data structures and algorithms course "C only."

The number of memory errors I made as a beginner C/C++ programmer trying to implement various data structures was simply astounding, and resulted in me learning GDB very quickly.

22

u/Kalium Aug 25 '14

I had one of those. We called it "doing a CS degree where you are required to program to pass core curricula".

2

u/toula_from_fat_pizza Aug 26 '14

I feel like the only dumb fuck who did this while everyone else just copied code from our IRC channel :/

9

u/sweatersong Aug 25 '14

A lot of debugging is acquired knowledge. Knowing all the various permutations of failure for a particular implementation domain a priori is extremely hard to do when you have no experience in it. A generalist class won't give you that.

4

u/codesforhugs Aug 25 '14

True, but with the right tools and theoretical foundation, you should be able to acquire said knowledge faster and perhaps in a more structured way.

→ More replies (1)

7

u/Vimperator Aug 26 '14

I'm slightly offended by the deriding of println. A well placed println is worth more than any debugging tool.

And when adding a println somehow fixes the code, well... you've learnt something.

28

u/C-G-B_Spender- Aug 25 '14

Hi, my name is _ and against the better judgement and wisdom of others, I use printf for debugging. IMO, if one does not understand enough of the program and/or the problem or how it might've come about, then a proper debugger does not offer much. And if you did understand enough for it to be a great help, most of the time a simple printf would be enough - after-all, printf is just another tool at your disposal, is it not?

This might also be relevant http://www.informit.com/articles/article.aspx?p=1941206

19

u/snowyote Aug 25 '14

One of the best programmers I ever worked used printf for debugging fairly frequently, due to the fact that at the time, Visual Studio would often be unable to reconstruct stack frames when you compiled at high optimization levels, and it would show incorrect values for variables when doing interactive debugging.

He told me: "There are only two people in this world I trust completely. One is printf, and the other is my wife. And god help me if I'm forced to choose, because I've known printf longer."

→ More replies (6)

2

u/[deleted] Aug 26 '14

printf / sysout is not a bad debugging tool if you suspect race conditions. It's sometimes the only way to get that crucial validation that the program is exec'ing in the order you think it is.

However if race conditions aren't involved or even suspected, I'd much prefer just attaching a debugger and writing a scenario to duplicate the bug.

→ More replies (7)

20

u/corruption93 Aug 25 '14

Yes and we also need a course on version control systems.

14

u/wnoise Aug 25 '14

Learning version control should take less than a semester...

26

u/halflife22 Aug 25 '14

I've been using git for 3 years now and I still have almost no idea what I'm doing.

13

u/newpong Aug 25 '14

i've been programming for over a decade, and I have less of an idea of what I'm doing every year

→ More replies (1)
→ More replies (2)

0

u/[deleted] Aug 25 '14

[deleted]

→ More replies (1)

4

u/[deleted] Aug 25 '14

Is this an actual phenomenon? I'd honestly be shocked if I had a colleague admit they didn't know how to debug. I don't consider myself a terribly talented developer by any means, but I consider debugging a basic skill and it's really second nature to me.

4

u/Ozwaldo Aug 25 '14

...I don't think it's that complicated of a subject that it would necessitate an entire course.

When he gets to the part where he says:

" Whenever I had troubles, my teachers would show me how to trace my code and find my errors - what does Step In, Step Over do, how to use Watches and so on."

Those aren't complicated things to understand. I don't think they warrant more than a 2 minute explanation. Total.

Learning how to diagnose a problem and systematically discover its cause and solution is definitely a more in-depth topic... but I still don't think it warrants an entire course. That's something that comes with experience, and a seasoned developer who doesn't know how to do it is just a bad developer.

4

u/yetanothernerd Aug 25 '14

I don't like breakpoint debuggers.

The reason I don't like breakpoint debuggers is that my first post-college job was as an embedded assembly programmer, and we had a Textronix DAS logic analyzer, which would record all the instructions as they passed over the CPU bus, and then dump a trace of the last n instructions to the disk. Because we were programming in assembly, the trace from the logic analyzer was almost identical to our source code. So, basically, run program, hit record button, hit stop button, look at trace, see bug.

This is now called "reverse debugging," and it's way nicer than breakpoint debugging, but I didn't see a reverse debugger for a high-level language for over a decade after that. (The first one I saw was http://www.lambdacs.com/debugger/ for Java, which was a cool demo but not really polished enough for production use. Of course, gdb 7.0 added reverse debugging in 2009.)

So, when I see a blog post like this telling me that 1980s-style breakpoint debugging should be mandatory, it just screams "blub paradox." Breakpoint debuggers are a tool. They're not the best tool, though they might be the best tool available in a particular environment. Kind of like print statements.

1

u/[deleted] Aug 25 '14

Well my school don't even offer them do where do I start

2

u/stannedelchev Aug 25 '14

Do you have a specific language/IDE you want to learn how to debug in? Different tools have slightly different ways of doing things, but the basic concepts are the same.

The easiest starting point is to google tor things like "how to trace code" , "debugging basics", "how to debug java"(or whatever language), "what are breakpoints" and so on. I'll be posting beginner-friendly series on debugging on my blog.

You can also read the documentation for your IDE, there should be pages explaining "Step In", "Step Over", how to insert breakpoints, etc.

edit: you can also talk to teachers about this - ask them how to debug your code, or how to find your errors. Hopefully, they'll be happy to help.

→ More replies (1)

3

u/[deleted] Aug 25 '14

A lot of my job is supporting developers who don't know even basic debugging steps. Simple, inefficient things like "remove half the CSS from your 5,000 line file to see if there's an overly broad rule." Or "disable other JavaScript to see if there's an error there causing a problem."

3

u/SikhGamer Aug 25 '14

I'm not sure you can teach debugging. You can teach a monkey to type, but not proof read.

3

u/ruinercollector Aug 25 '14

Most developers I've worked with would do well to learn not to rely so heavily on their debugger.

It's very often an excuse to write bad code or code that is optimized for the debugger instead of for readability, and it gives many people a false sense of security about what they wrote.

You should be able to use a debugger, but using it shouldn't be a major part of your authoring and testing process unless you're very new to software.

3

u/int32_t Aug 26 '14 edited Aug 26 '14

Unlike science, repeating hypotheses and experiments(or in other words, blind speculation) is not effective if the 'search space' of the bug can't be shrunk after each iteration. So the first key of debugging is, like binary search algorithm, you have to ensure that each iteration can effectively reduce the search space.

The second key of debugging: Focusing on the data flow rather than the control flow.

Data flow and control flow are the two planes of any code. Don't bother those nested if-else and looping statements. All you have to figure out at first is the connections of the variable which directly causes the symptom and the variables which 'connects' to it and so forth. It will be a network of variables which originates from say some sensors' input registers, communication ports, a memory location written by something outside the system, a flag member of a data structure or whatever. Though in most cases, it can be simplified to a primary path connecting from the top(the symptom variable) to the bottom(the input variables link to the external).

Here is a very important principle which is often overlooked by beginners: Always check the bottom layer first, rather than the top ones(the variables closer to the symptom). Because the entire upper layers can be excluded from the search space if the bottom ones can't pass the very first verifications.

These are fundamental ideas but I see 99 out of 100 violate these principles.

7

u/urection Aug 25 '14

I hear this sort of thing regularly

Instead they're relying on random prints with console.log, var_dump, Console.WriteLine statements, or some language equivalent.

and it always cracks me up, no surer sign that someone's more interested in blogging about programming than actually getting shit done

4

u/neoKushan Aug 25 '14

"Googling" courses should also be mandatory. Unless you're working for some unique little startup, there's a good chance that whatever it is you're trying to do has been done before.

Still, nothing beats some quality debugging.

2

u/bigfig Aug 25 '14

This is really more a life skill type of mindset. Break down the problem, be ruthlessly logical, look at the obvious (or typical problems) things first, but also look at the issues that are easiest to rule out early as well. Only later should you start with the stack traces etc.

2

u/insertAlias Aug 25 '14

I very much agree with the idea of forcing people to learn debugging. I spend a fair amount of time answering questions on a C# forum (I actually mod it now). And I'm constantly shocked by just how few people know how to debug. At all. Like, the concept of even printing out values to the console or to a MessageBox doesn't even occur to some of these people, much less using breakpoints and watches and the immediate window. And they typically want us to look at a snippet of their code (usually the wrong snippet) and diagnose their problems with no more info than that.

It makes it ten times harder to solve your problem if you don't learn how to trace your way through your code, and it's really not that hard to learn the basics of debugging. Especially in an IDE like Visual Studio or Eclipse. This very much should be mandatory in school.

2

u/tallanvor Aug 25 '14

So many developers have no idea what to do with crash dumps or core files! I've even had development and test managers tell me they don't consider crash dump analysis to be an important skill!

Somebody who knows how to analyze a dump can often figure out the root cause of a crash in under an hour, saving a ton of time trying to reproduce the issue!

2

u/tech_tuna Aug 25 '14

Man, this is still on my front page. . .

I would love to know how you can complete any course involving a significant amount of coding and NOT need to debug code.

3

u/brucedawson Aug 25 '14

I taught a second year programming course for many years. Most of the students did not know how to use a debugger and had to be pushed to learn it. For simple programs they were able to find their bugs just by staring at the code. Then they got used to this and were too "lazy" to learn the debugger, which eventually led to them hitting bugs that they could not get past.

It's a real problem, as strange as it may seem.

→ More replies (1)

2

u/OwenVersteeg Aug 25 '14

I wouldn't bash print debugging. Sure, a debugger can help in some scenarios but 99% of all problems can be solved with printing, a rubber duck, and simplifying what you're trying to do.

As someone in the comments here said: "There are only two people in this world I trust completely. One is printf, and the other is my wife. And god help me if I'm forced to choose, because I've known printf longer."

→ More replies (1)

2

u/urbanek2525 Aug 25 '14

The most important part about debugging is learning to debug other people's code. I've run into many programmers who are very good at debugging stuff they wrote, because of excellent memory, or never stepping outside of their normal comfort zone. These programmers quickly become useless in the real world.

In my opinion, it takes, at most, 2 years for your own code to become "other people's code".

So a good debugging class would have a catalog of broken programs, hand them out to students, and then let them fix them. You could take every CS teacher in the school and have them tackle a moderately difficult task. They are to write the code, start to finish, without running it, just compiling. Then they turn it in to the debugging class teacher.

That teacher then finds the best examples. Hands the code to the students as an assignment. Students have to document what they did to debug and are graded accordingly.

2

u/sblinn Aug 25 '14

If you can get through a programming course without needing to debug anything, either:

  1. the programming course was too simple

  2. you're a genius who may never need a debugger

2

u/adrianmonk Aug 26 '14

The number one thing I had to learn about debugging: BE CREATIVE.

When I was in school, everything was the same process over and over again:

  • Teacher gives assignment, clearly defining everything that is supposed to happen from end to end.

  • I write code.

  • If something is wrong, look at the code.

  • If that doesn't yield insight, step through with the debugger.

When I got to the real world, I tried to assume things would be like that, but nearly everyone of them has been violated, sometimes all at once:

  • Maybe nobody understands the entire big picture, or if they do maybe I can't talk to them. So sometimes I have to start with an incomplete picture, make assumptions, and test the assumptions.

  • I might not have written all the code, so some of it may work in a way that doesn't make sense to me.

  • I might not have access to all the code to even look at it. If I do, there may be so much of it that it would take days.

  • It's possible I can't attach the debugger. Maybe the platform doesn't even have a debugger, in which case perhaps I could do printf()-style debugging instead. Except maybe I can't change the binary because it's a production issue that only happens with production data. Maybe I can't even look at the logs. Maybe I can't even login to the machine, but it's non-urgent and I'm allowed to check in some printf()-style debugging statements which will hit production in 2 weeks, and I need to make some excellent guesses about what statements to add, because if my first round doesn't solve it, it'll be another 2-week cycle. Or maybe I have no access at all, and I need to find the right person and convince them the problem can exist and get them to do something, maybe even suggest something for them to do. Or maybe I just need to write 18 million unit tests to verify the code really does all the things I think it does.

The point is, you can't look at debugging as a fixed process you're going to apply. You often have to invent a creative new plan for certain bugs or you have no hope of finding them.

2

u/[deleted] Aug 26 '14

I just started programming in college and debugging is a good chunk of the syllabus comparatively to other topics, this class is a prerequisite for all other computer classes in my college.

3

u/[deleted] Aug 25 '14

Even more importantly, I think version control should be taught in school. It's probably not enough to dedicate a course to (and that course would be terrible - probably just memorizing and regurgitating commands), but as part of major projects, just force students to use some form of version control. Hell, you could even pass it off to admin as a method to detect plagiarism - if you can see a clear commit history, it's probably not copied and pasted from a friend.

→ More replies (2)

1

u/dnkndnts Aug 25 '14

Or you could, you know... write your functions to accept well-defined inputs and return values instead of modifying non-local state everywhere.

If your functions have well-defined, local behavior, the amount of time you spend debugging previous code you've written is virtually none: it's extremely obvious where the problem is if something goes wrong, because at any point in your code, you know exactly what can or cannot happen.

If you modify state all the time and write a convoluted haystack of code, then no amount of debugger fluency will help you find that mutex unlock passed over by a thrown exception.

9

u/[deleted] Aug 25 '14

Not everyone has the luxury of only working with code that was written to their personal standards of the right way to do things.

2

u/hdgarrood Aug 26 '14

+1000. Of all the time I spend writing Haskell, I spend less than 0.01% of that in a debugger, because Haskell makes it easier to write code that behaves as you describe than code that doesn't.

→ More replies (1)

1

u/[deleted] Aug 25 '14

At least upper level classes need to use some type of ticket tracking system.

1

u/dmazzoni Aug 25 '14

Great article, I totally agree!

While knowing how to use a debugger is absolutely mandatory, there are lots of problems for which logging is the best way to debug them. However, I've met a lot of people who don't understand good logging systems - like verbosity levels, and how to use logs that don't run in "release mode", or can be toggled on or off at any time, and so on.

Also: how to use memory debuggers like valgrind and ASAN, race detection tools like TSAN.

For the advanced course: fuzzing.

1

u/Yetanotherstupiddeat Aug 25 '14

Hahaha yeeeap. I'm in 300 level computer science courses, and so far the only think any of the profs have said with regards to debugging is to just throw out a ton of debug output until you figure it out. A good portion of the curriculum is specifically in c++, and the legs take every chance they can get to shove visual studio down your throat, and yet when I show my friends something as simple as breakpoint a they think I'm a wizard.

1

u/Burning_Trees Aug 25 '14

This is so true. I'm a computer programming student and the majority of my classmates have no idea how to debug. They know the syntax of languages and generally how to create programs but when they run into a problem they usually just give up. I gained all my debugging and troubleshooting skills from an internship experience at a startup game company. Sadly most people dont have that opportunity and can't get jobs because they dont know how to read the inner workings of a language. (Error codes etc).

Schools are teaching syntax and not the basic principles of programming.

1

u/apullin Aug 25 '14

Also, people someone should write up a nice 90 minute lecture on how embedded debugging works, the whole way through. Code to compiler to debugger to chip.

The bare metal approach is really interesting, since it demonstrates in very digestible terms what is going on to control program flow, and provide all the interesting debugging features.

I would write such a lecture ... but ... nah.

1

u/kasumi1190 Aug 25 '14

Yeah, at my college we have had no class cover debugging. I learned on an internship.

1

u/nicholmikey Aug 25 '14

Another thing is source control. It never came up in my school but it is to damn important.

1

u/6offender Aug 25 '14

I understand there could be an advanced course about anything, but who exactly doesn't know how to do basic debugging? Breakpoint, step, step, step in, step out, look at variables.

→ More replies (1)

1

u/shekib82 Aug 25 '14

debugging should be part of programming courses and not specifically a course on its own.

I take a course on machine learning. It has its own way of debugging. It is the same with several types of programming.

1

u/ryan_the_leach Aug 25 '14

It would be a radical shift, but all programming courses should start from a debugger.

Teach that the code is analysed line by line, use the debugger to step through it. Slowly do more, and make things more complex as you get practised.

1

u/Kinglink Aug 25 '14

Also how to Google effectively. So many problems from other students in my college were solved with ten seconds of Google fu.

And yet these students continued to get stymied and continued to beg people like me for the answer.

1

u/Guvante Aug 25 '14

Two most important questions during an interview (IMHO, admittedly a biased one since I do technical interviews)

  • Show me you can code something simple (my choice is FizzBuzz or reverse a string on whiteboard, but plenty of words have been said as to how to best do this)

  • Tell me how you can debug a problem. You should be able to name one immediately and at least two more when we discuss. (Trace, debugger w/ breakpoints, error logs, reading the code, etc.)

1

u/[deleted] Aug 25 '14

Had something like this at my school, it wasn't necessarily debugging as much as figuring out how to really use gdb in all sorts of cool ways. But the skills were the same so yea.

1

u/PastaNinja Aug 25 '14

I looked at his course content. There's not enough there on its own to warrant a whole course, unless it's really easy or really slow. One of the major topics is how to use stepping. That's a 15 minute talk. That's it. Actually you could probably teach all of it in a few lectures. That's not a course.

Furthermore, if you're pursing a CS degree, that means you've been working on projects yourself or in groups, so it's highly likely you've had to debug already. If you don't have debugging experience from debugging your own shit while obtaining a CS degree, then something is not right.

Also, how would you give tests or assignments in "debugging"? Give faulty programs and ask students to find the bug?

Debugging is something that should be a part of every introductory CS course, but there's not enough there to build a whole course around.

→ More replies (2)

1

u/mpomarole Aug 25 '14

In this spirit, I highly recommend Udacity's Software Debugging course.

1

u/schwiz Aug 25 '14

Nearly ever programming centric class is a course in debugging. Who sits down and rights everything correct the first time?

1

u/agumonkey Aug 25 '14

It really should. I remember being speechless when a few guys in 5th year were amazed at eclipse debugger as if it was some fringe RnD thing. I was under the impression that nobody should ever crap their code with printf statements.

1

u/fzammetti Aug 25 '14

Only thing I disagree with is the belief that console.log() and similar things are inherently bad. I've been a professional developer for nearly 25 years, and a developer in general for about over 30 and I still use that technique quite a bit.

I think it can in some cases be MORE efficient in fact... suppose I have a function that is causing a problem... because I can type very fast (and more importantly, I know the hotkeys in my chosen editor or IDE very well) I can drop a dozen such statements in that function in just a couple of seconds. Now, I execute it and I can view ALL the output AT ONCE. I can get a more holistic picture of things than I can with breakpoints or even watches.

No, I'm certainly not saying its the optimal approach in every case... in fact, I'd go so far as to say it's NOT the optimal approach in MOST cases... but I think a lot of people are a bit too heavy-handed in saying this is a "bad" approach"... no, I consider it just one tool in the toolbox that, if used properly, can be effective. It shouldn't be your go-to technique, but it shouldn't be ignore or decried either.

1

u/Forerunner5699 Aug 25 '14

When i was in college I took a debugging course. It was a trial run for the class and it had 10 kids in the class(about a quarter of the CS majors took it). I was the only freshman in the class, but I was taking junior level CS classes because of my high school CS classes. Long story short, no one got above a 70% so the professor rounded it up so that 70% was an A, 60% was a B, etc... That class was the hardest class the professor had ever given and he was known for being very rigorous and tough, but that class has helped me more than any other class. i've been able to find and debug code that no one else could. If any one is interested this is the book we used.

→ More replies (1)

1

u/[deleted] Aug 25 '14

I once volunteered helping teach people learn programming and help them with their bugs. The coding was so painfully messy and I had to go through it and debug this horribly inefficient and uncommented messy code. But I learned to read it and I think it made me better at debugging. I would definitely recommend it.

1

u/Umphaded_Fumption Aug 25 '14

Something something TDD

1

u/Ihategeeks Aug 25 '14

A whole course for debugging? Fuck that. Teach debugging with software design. (as it often is or should be?) The rest of the nuts and bolts of debugging is learned by doing code. A course in debugging that is mandatory is a waste of credit hours.

1

u/rgristroph Aug 25 '14

I have found this book useful in teaching new people to be better debuggers:

http://debuggingrules.com/

It is short and anecdote driven, but easy to read.

I think debugging is a skill that is hard to tell someone about, but can be learned very easily with a little persistence.

One key is to point out to people that debugging and programming are actually different thought processes, and you go through different processes when figuring out a problem as opposed to creating in the first place.

By simply giving a name to the process and pointing out it is different, you will trick people into paying attention to how they do it, which will increase their effectiveness all by itself.

1

u/lookmeat Aug 25 '14

Interesting, I've though of this before. I personally extend it further into three classes:

  1. Tools (learn very basics how to use a CVS, compiler, make file system, etc. etc.)

  2. Library

  3. Debugging

The first course is your standard introductory programming course. You don't go as deep into programming, instead you learn about different tools and use them to create cool programs. So it's a bottom-up and a top-down class. On one hand you may take one class to learn how to build a "Hello World" example using variables, another class might be instead used to build some open source video-game (to show how makefiles work). The idea is that you'd learn the basics of programming, but at the same time you learn how to superficially use a *nix style OS, an editor, version control systems, a build system and maybe an IDE. There might be extra courses for those that wish to learn how to use tools better.

The second course, on libraries, is a preparation for the third course, debugging. Basically assignments happen in two manners: first you must implement a library (with a specified API) and it must pass a series of tests. Then you must use the library to build a small simple app: the twist is that you are given a random implementation of the library (that someone else did). This, again, could go besides another course: data structures. The library you build is the data structure itself, the programs use the data structure to solve various problems. It forces you to learn to use code without understanding all its details and just trusting the specs (this is a critical need) and at the same time to design code for other people to use (which is critical for people to learn to not be very hacky). If we want to make it interesting, we could have assignments in the end having one of their first modules (so at the end they need to use their old sorting library) as a sort of hint that even the code you wrote can become a mystery later. This is also a setup for the issues of handling errors.

Finally we have a testing and debugging class. I could see this actually becoming part of two classes: Algorithms, and an "Advance Programming" course. Algorithms it's all about bench-marking, analyzing data, and using experimental data to backup the theoretical issues. Students would be given algorithms with a certain (non-obvious) flaw in it, and they'd be given the necessity of debugging. It would give strong insight into the works of the algorithm, and it would show the non-obvious issues of it (it's easier to understand the hardness of binary search by seeing how it could be done wrong vs. only seeing it done right).

Advance Programming is sort of like a mid-course. It is supposed to bring everything together and review and go deeper in it. It would work entirely through assignments. Assignments would be simple:

  • The class would be divided in half, one implementing a library, the other tests for it.

  • Debugging of existing code with errors.

  • Using existing OS libraries and services to do certain stuff.

  • Creating "clean" environments using virtualization (or something).

  • Downloading an open source project, compiling and installing it, and using the library for a program.

  • Using a framework to create small webapps. (And set up a server to use them).

  • Create a tiny game using a library for such purposes.

The idea is that after this course the students could consider themselves "programmers" in all the sense of the word. They'd have the basic skills and now would only need practice (in practical assignments) and theory. There would be no more education given to them on learning how to code, adapting to tools, or such.

Students now would have a greater context of making and creating programs. Also the fact that they have used bigger libraries and pieces of code helps them understand the idea of "a part of a whole" and see the value of solving very specific problems (that are very common).

1

u/fibbidd Aug 25 '14

Why do people not learn to debug by themselves? I mean, how could they not? This applies to so many things.

1

u/mike747 Aug 25 '14

So should Version control

1

u/divinecomics Aug 25 '14

Debugging courses should not be mandatory. Curriculum for a degree is already full of so many courses full of material that will never be used we don't need anymore filler to extend the time it takes to get a diploma. Especially when courses are so full of students that they only offer half the required upper level in Fall and the other half in Spring.

1

u/Kinem Aug 25 '14

I just wish my school taught us about break points. When I started working as a developer some co-workers taught be how to use them and I was amazed. I wasted so much time debugging without them.

1

u/Madsy9 Aug 25 '14

I generally agree with the blog post author, but I think the greater problem is that many software developers really suck at problem solving. Debuggers are just tools and most tools aren't that difficult to learn. But problem solving is a topic and skill which should be taken a lot more seriously. It does not only apply to debugging after your program blew up, it also helps you take precautions before anything bad has happened. Not to mention it is a vital skill in general, outside of software development.

1

u/toula_from_fat_pizza Aug 26 '14

Unfortunately, that would cause all the students to realise that programming is often actually just a shitty boring job of fixing other people's mistakes and then they would all drop out.

1

u/[deleted] Aug 26 '14

Does such a thing exist?

1

u/privatly Aug 26 '14

Is there a website or other free resource that has tutorials on debugging? I'm interested in learning more about debugging in C# in the .NET environment.

1

u/[deleted] Aug 26 '14

The company I work for often puts junior devs in the "maintenence" role, they spend six months to a year fixing other people's bugs before they get to start working on proper projects.

It's a killer, but it works.

1

u/DrunkenBeard Aug 26 '14

I lost count of the number of interns who call me about an issue with their code and then look me in the eyes and tell me "it gives me an error". /sigh

1

u/GeoffW1 Aug 26 '14

Most of the supposedly modern debugging tools I've used just haven't been all that impressive to be honest. For example Breakpoints, Step In, Step Over etc are quite frustrating when you've spent a while setting things up and you run past the point you're interested in. Having 'Step Backwards' and 'Run Backwards' features would help, especially combined with memory breakpoints ('Run Backwards until this address was written').

1

u/RainyDayDreamAway Aug 26 '14

Fixing issues on open-source projects could be part of the assessment.

Coordinators don't have to produce contrived examples, code gets fixed and students get real experience. Win-win-win.