How do you use debuggers?


#1

Recently, we got tons of feedback about the need for a debugger in Julia:

I wonder how people rely on debuggers for day-to-day coding. I was trained to reason through code with my brain, and it typically works very well! The only time I really felt the necessity to use a debugger in my years as a programmer was when I was playing with heavy parallel programming on a cluster.

My impression is that people are overusing debuggers, but I may be wrong…

Today I saw a comment on the forum:

“I cannot upgrade to Julia v0.6 because it doesn’t have a debugger.”

I never used this criterion myself to choose a programming language! What is the rationale?


#2

I find a debugger very useful when I am learning about the internals of a library. Simply running one of the high-level functions and then looking at the callees is usually a very good introduction. One can of course gather all this information from the source, but working with the debugger provides a great first look.

Also, sometimes it is useful to look at the runtime state. I also try to force myself to write small functions which can be tested separately, but with non-deterministic code, a debugger is occasionally useful.

In any case, I hope Gallium will be fixed soon. I can get by without it, but it is a nice tool.


#3

Learning the internals of a library is definitely very interesting :slight_smile:


#4

I am very much dependent on the debugger when I work. It’s a huge timesaver when it comes to making my own code run properly, and it’s also the only way I can realistically be able to understand other people’s code.

I have adopted Julia 0.6 even without the debugger, but it’s frustrating when I move beyond toy projects. Every time something goes wrong, an index out of bounds, or my vectors all turn to NaNs, it’s a slog to identify the often tiny mistakes that cause this. Then I squint and print, and add plot statements, endlessly reloading Julia and trying to re-create the workspace as it was.

A bug that takes half a minute to track down in the debugger suddenly costs me half a workday or more. It is inconceivable that I could develop anything bigger than a couple of hundred loc without a debugger.

Without a debugger I also find myself frequently frustrated in figuring out how Julia itself works. To understand the behaviour of somefunction I call @less somfunction(someinput), only to find that it is translated to somefunction(identity, someinput), which calls _somefunction(io, identity, someinput), which goes to _blah_mapreduce__(identity, someinput, :compact, helloworld()), each time sending me back to the prompt trying to @less my way down the rabbithole. Then I give up.

With a debugger, it’s ‘step-in, step-in, step-over, step-in’ and voila! I understand what’s going on. I am one with the code and the program state, and everything becomes clear.

No-one ever trained me to do that, and when I try, it feels like crawling, blindfolded and hung over through a cactus field with both arms tied on my back.

Still, I vastly prefer Julia over Matlab, even with the latter’s awesome debugger.


#5

And in non-typical cases? If i look at my history working with debugging tools, in all usage scenarios the debugger was an additional way to understand which data was changed by which instance. Sometimes i use the debugger only to stop somewhere and write down some data on paper and walk away from the computer to build a mental model, what actually should and is happening (i recommend the garden as debugging tool, therefore). I learned to work with gdb running a julia session inside to debug some ccall magic. In most cases i use the debugger if i don’t have the option to change code - in libraries or inherited code.

Debugger falls in the domain of programming tools, like Profiler (memory and time), IDE, Coverage analysis, Lint, Autoformatter/Beautifier etc. It’s just a modern thing to simplify work.


#6

In v0.6 the stacktrace tells you exactly where the issue is, and you can just open the file to add some display commands and see what’s going on without restarting Julia. Since libraries in Julia are written in Julia (and so is Base), you can do this pretty much anywhere, so the need for a debugger is pretty minimal. I often times will print a few things, snag the code, get an example for the REPL, and try things out. So basically, you just get a stacktrace, add a print, fix it, and move on: not sure how much easier it can be.

As for digging deep, pretty much everything in a package “should” have a tiered API so that way you can bypass initialization phases anyway. For example, NLsolve and Optim allowing you to make the OnceDifferentiable functions and all of that, or out-of-place versions just allocating and calling an in-place version. If code is structured correctly like this (and most packages and Base functions seem to have something like it), then not only is there a pre-allocated and faster version of the code for repeat use, it also means that you already have the objects in the REPL to directly do the internal calls, meaning the REPL is essentially a debugger as a natural consequence of building a library in an extendable and composable form.

Still, it would be nice to have a debugger in the cases where someone names internal variables of a package in a silly way or globals get involved: debugger + workspace + interactive REPL is really the only way to decode that. And the previous structure fails if the problem is due to something like a floating point issue in a 200080th iteration of a loop: that’s when things get hairy and addings prints becomes a mess.

So while in most cases where a debugger is “necessary” the code probably just needs to be restructured, if you just want to bang out some code and have it work, a debugger can get you to the end goal with none of the work in the middle. For quick user-level work, this is much more necessary than package development since you want to just avoid “how things work” and just get your script working. But also it’s a time thing: when I first came from MATLAB/Python/R, I was so used to using a debugger that it was hard. But once I got a new workflow down it was fine. Not sure we can rely on people experimenting with workflows to get around what is natural in other languages though.

Lastly, it would probably be very helpful for new users who aren’t as familiar with git since then they won’t get stuck with dirty repos that they don’t know how to fix. Honestly, that’s probably the main reason for a debugger from what I can tell. Too many user issues seem to stem from having a repo which won’t update because it’s dirty from some small change while debugging awhile back and the user not just stashing or discarding the changes.


#7

If I would only use a debugger in cases where i get a stacktrace my life would a lot easier.
You describe the niche of: ‘why did it break’ and that’s maybe only a 5% of the cases. Debugging is lot more.


#8

First, I use the debugger to find the logical error by tracking the value change of the variables/data structure. I also use the debugger to understand others’ code by step-by-step run. For example, without a debugger, it is difficult to know how the MFC library works.

For the short programme, I can debug by printing the variables. But for the large project, coding without debugger always waste a lot of time.


#9

I’ve been coding fortran, C++, python and Julia (a little) for 20 years. I think I can count on one hand the number of times I used a debugger, which were all critical memory access issues in C++. These I now avoid with the tooling provided by clang (and recent gcc). I more or less follow the approach of @juliohm and @ChrisRackauckas

I suppose it depends on what environment you learned in. I have only ever used Vim and the command line, so I didn’t get used to the idea of immediate debugging. I spent a few afternoons coding c# in visual studio and noticed how it just drops you into the debugger on error. In that case I see how easy it is to get used to. Whereas I always just have to get myself inside the mind of the machine.

But as so many people are coming from Matlab I can appreciate the desire to get a good debugger for Julia. The one time I played with it, Gallium seemed to do all that was needed, so it doesn’t seem to far off to have this to everyone’s satisfaction.


#10

I am pretty much with you @jtravs, I am coming from C++ and plain terminals. The gdb debugger was my last resource when I couldn’t figure out the issue by just reasoning through the code and printing out intermediate values of computation.

After you do this exercise for a while, you learn how to find bugs systematically and efficiently. You become a better programmer as well. In fact, if you have the habit of writing tests for every feature you add to your library, a debugger is almost useless.

I think you are right that people are used to jump straight to a Visual Studio or MATLAB debugger, and are somewhat dependent on a tool that should be used on exceptional cases only.


#11

I find these remarks arrogant, ill informed and insulting.


#12

I don’t think they are, but if you feel insulted, sorry. The statement I made is general, not applicable to anyone specifically and very close to my understanding of the truth.

Debuggers aren’t a tool for day-to-day use IMO, they are there for helping in exceptional cases. Good programming habits with test suites, code coverage, etc. eliminate almost entirely the need for a debugger. Again, my opinion.


#13

I have been using them day-to-day for 15 years, and I can tell you that they are. No need to insult people who use them efficiently as inferior and helpless programmers.


#14

When did I say that? This is your interpretation of my sentence.

I can actually see one case where debuggers are relevant for day-to-day code, and it is case where you spend most of your time developing GUIs with lots of user interaction. Other than that, I stick with my argument that test suites and code coverage eliminate the need for a debugger almost entirely. Specially in scientific programming where the program flow is quite predictable (including stochastic algorithms).


#15

I think that a debugger is as much an asset in deducing issues, as a calculator is to compute numbers. Some people are quite good at crunching numbers in their head. If that is an advantage or not, now that calculators are everywhere, is debatable. I suspect that someone really skilled in using a calculator will outperform a human with less mental overhead, while on the other hand a skilled human will probably be able to navigate through most problems without much time penalty, while at the same time getting a cognitive benefit out from that brain exercise. Either way, the calculator is a tool and its useful.


#16

I relied on the stepper quite heavily when I used Matlab. I found it to be helpful when code was non-deterministic and when learning code written by others. Although I was willing to forego a debugger, many people are not, especially when there are alternatives with debuggers as well as other conveniences like larger package ecosystems. I think conveniences like debuggers will be helpful in expanding Julia’s user base.


#17

Of course it’s my interpretation. The insult is implied, as are most insults.

I have told you that I find debuggers extremely useful for my work, you tell me I’m wrong. That is the height of arrogance.


#18

I was under the impression that you started this topic to learn about how others use a debugger. Now you are making claims about the role of debuggers based on your coding habits. Given this, I don’t understand why this topic was necessary.

Learning about the practices of others may be useful. Debating about them is often less so, especially if they have evolved as solutions to different problems.


#19

@Tamas_Papp, you shared something interesting about learning internals of a library. I bought it. Now, I have my own opinions about the usage of debuggers and at no point in this thread I imposed them on anyone. All this useless debate again is happening because of this statement:

I think you are right that people are used to jump straight to a Visual Studio or MATLAB debugger, and are somewhat dependent on a tool that should be used on exceptional cases only.

If you read it again and again, you will see that I am not pointing any names and I am not enforcing any roles on anyone, I am just expressing an opinion. It seems that people are too sensitive to opinions that don’t match their beliefs.


#20

Without debuggers, the only way to debug a semi-complex piece of code (especially if you’re trying to debug the math at the same time as the code) is to add print statements everywhere. That gets tiresome really fast. Real Programmers who can debug code by just looking at it or Real Scientists who only write code they have proven to be true may not need debuggers; the rest of us do.