Debuggers are one of those things that I almost never use, and have a completely unearned distaste for. Literally every single time I've used a debugger it's been useful, but it's never something I think about using off the cuff. Maybe I'm just an incompetent goober who spends too much time on IRC :)
I've been getting into Julia a bit for personal projects, since I like it better than Python, so maybe this will be a good excuse to learn how to use debuggers more effectively.
I know how to use a debugger, at least how to set a breakpoint and step through stuff. I'm sure there are features I'm not familiar with, but I at least understand the fundamentals.
I think part of it is that for the last 5 years , every single language I've used with any kind of professional capacity (JavaScript, Haskell, Erlang, F#, Clojure, Scheme) has had a REPL, so I can quickly play with and reload code, making debuggers a bit less necessary than if I were to do a purely-compiled language.
I definitely would benefit from learning more about performance profilers though. You've given me an idea of reading material for the weekend.
Sorta. I feel I was taught to program by basically being taught how to be my own debugger/stepper. That was literally a term's worth of tests. "Write down the state of the variables in this function when it is called with these inputs." was a common test question.
So, yeah, learning the keyboard shortcuts for how to step through something takes effort. However, it is doing basically what I was taught to reason about programming.
Functional idioms throw a lot of this a giant curve ball. Heaven help the person that was used to stepping through a for loop that steps over a map call. Oops. Worse if it is lazy.
That said, they are not competing ways of thinking. Just different ways. If you are having trouble with one, try the other.
(I do note that the difficulty of working in a debugger is ironically one of the major criticisms of macros in lisps.)
Turbo Pascal 5.0
Is important to note how MUCH better some debuggers are than others. Pascal was amazing, specially if you compare to C.
Good debuggers:
- Pascal
- Delphi
- FoxPro /VisualFoxPro (the best of all, IMHO)
Others more common debuggers (Visual Studio, Xcode, IntelliJ, maybe others I don't remember), have issues, like the amazing "feature" of show opaque values, not allow to inspect stuff or requiere extra steps.
But the worse of all? Them are SLOW. Do "step" is slow. Waiting to see if evaluating values? slow.
Python have almost good, but mostly because python allow to see a lot. GDB sucks as is, but python make it look good.
But really, what do you use in their place? Do you work in an environment that is "debugger by default" (as opposed to a separate step where you need to "debug" instead of "run")?
"println debugging" is a tried and true strategy. Debuggers' firehose of information can start to get really hairy when you have multiple threads of execution, for example. "println debugging" (if you have the right tools) can get you 98% of the way there and show you exactly only the relevant information.
A lot of debuggers have a feature where you can stop the execution of threads you don't want to bother with, which I find to actually be more useful than println debugging.
It's not a satisfying answer really, but I use a bunch of log statements. It's definitely not as good as a debugger, but 9 times out of 10, it's sufficient.
This is one of the main things which has driven the development of julia's logging system; it seems that some people just don't like debuggers very much (I'm one of them) and find staring at logs and attempting to run the code in their head to be a productive alternative.
I think it's the difference between inspecting local vs global program behavior. A debugger gives a very local view of the program but the most difficult bugs are ones where the local behavior is (or seems) correct but the global behavior is wrong. In that case it can be much more useful to run the program to completion with plenty of logging and then to carefully inspect the record of how the state changed.
Yeah, and when I did node.js programming, the one time I ever got node-inspector working, I even would inject code in while paused on a breakpoint, which is undeniably useful.
Could be because you've never used a good one. I could see how that distaste would form if all you've ever used was the likes of gdb, lldb, of (if you work in Python) pdb. But when I was switching away from Windows entirely 15 years ago, giving up windbg and Visual Studio debugger was HARD. It's so convenient when you can just _see_ what your program is doing without a lot of extra friction. The downside is, this very much disincentives the writing of tests, because you can get non-trivial pieces of code working without any tests. But with a little self-discipline, I think having a great debugger was a net positive for me, both code quality and productivity-wise.
Throughout my career, I have never met anyone who used MS tools that did not find them excellent and productivity enhancing. In fact I could probably add to MS any of the language vendors from years ago. I remember using Borlands terminal based C++ environment back in the early 90's. That's about 30 years ago and that environment is better than what I use programming on Linux today.
I have often thought that programmers posture over their tool independence to signal their excellence. Before the current generation of programmers, many programmers would proclaim how they didn't need to use higher level languages to assist them in programming because assembly language was sufficient given their reasoning powers. Today programmers proclaim they don't need types to insure data invariants as their reasoning powers are sufficient. They proclaim they don't get any value from unit testing because they can maintain correctness across all development phases using their reasoning powers alone. They proclaim they don't need automatic garbage collection because they can insure correct memory usage using their reasoning powers. They have no use for IDEs, debuggers, or profilers because they believe none of these tools could augment their reasoning powers.
Excellent programmers can indeed compensate for poor tooling through their reasoning powers alone. But if history is a guide, people who don't use the best tools, practices and technologies to produce the best work, at some point, wont produce the best work.
I think the situation on the FOSS side is compounded by the fact that gdb, while it's unquestionably not in any way "state of the art", is also not totally useless, so there's less of a reason to create something that's truly excellent. Moreover, there are whole generations of programmers now who think that tooth extraction compares favorably to using a debugger.
If there wasn't gdb/lldb at all, I'm pretty sure Linux/BSD would have a debugger that's far better than any closed source counterpart.
I think the main problem with debuggers is that I've seen people crippled by the need of them. Literally unable to simply stop and ask what could possibly have caused the outcome they saw. Having to use a program to step through with the required values to reproduce what they should already know will happen when those values are present.
Which isn't to say that live coding and debuggers are bad. However, they are usually much more useful to find out either how something got to where it is, or to augment what you have until it is ready to send for review.
Which languages have you tried to use a debugger with? Debuggers like gdb look awful (at least without a GUI). On the other hand, Chrome's JavaScript debugger is a joy to work with.
I've used Chrome's JS debugger, which I agree isn't so bad (though I don't really do frontend work, and I only managed to get node-inspector working once).
I've also used the Visual Studio debugger for F#, and I think I did gdb with Eclipse a couple years ago when I did C.
Comments
Debuggers are one of those things that I almost never use, and have a completely unearned distaste for. Literally every single time I've used a debugger it's been useful, but it's never something I think about using off the cuff. Maybe I'm just an incompetent goober who spends too much time on IRC :)
I've been getting into Julia a bit for personal projects, since I like it better than Python, so maybe this will be a good excuse to learn how to use debuggers more effectively.
I have been using debuggers since Turbo Pascal 5.0.
My experience regarding people around me that don't use them is that they never actually bothered to learn how to use them.
Same applies to other development tools like profilers and static analysers.
I guess I was quite lucky with some of the teachers and professors that crossed my path.
I know how to use a debugger, at least how to set a breakpoint and step through stuff. I'm sure there are features I'm not familiar with, but I at least understand the fundamentals.
I think part of it is that for the last 5 years , every single language I've used with any kind of professional capacity (JavaScript, Haskell, Erlang, F#, Clojure, Scheme) has had a REPL, so I can quickly play with and reload code, making debuggers a bit less necessary than if I were to do a purely-compiled language.
I definitely would benefit from learning more about performance profilers though. You've given me an idea of reading material for the weekend.
Debuggers aren't exactly self-explanatory so the role of good teachers should not be underestimated
Sorta. I feel I was taught to program by basically being taught how to be my own debugger/stepper. That was literally a term's worth of tests. "Write down the state of the variables in this function when it is called with these inputs." was a common test question.
So, yeah, learning the keyboard shortcuts for how to step through something takes effort. However, it is doing basically what I was taught to reason about programming.
Functional idioms throw a lot of this a giant curve ball. Heaven help the person that was used to stepping through a for loop that steps over a map call. Oops. Worse if it is lazy.
That said, they are not competing ways of thinking. Just different ways. If you are having trouble with one, try the other.
(I do note that the difficulty of working in a debugger is ironically one of the major criticisms of macros in lisps.)
Good debuggers:
- Pascal - Delphi - FoxPro /VisualFoxPro (the best of all, IMHO)
Others more common debuggers (Visual Studio, Xcode, IntelliJ, maybe others I don't remember), have issues, like the amazing "feature" of show opaque values, not allow to inspect stuff or requiere extra steps.
But the worse of all? Them are SLOW. Do "step" is slow. Waiting to see if evaluating values? slow.
Python have almost good, but mostly because python allow to see a lot. GDB sucks as is, but python make it look good.
Step being slow? How long you don't use debuggers?
Plus it is not like one needs to single step all the way, there are plenty of ways to control execution flow.
Stepping can be slow if you setup a lot of watches that get evaluated every time
That is what trace points like IntelliTrace are for, no need to single step.
Like 7h ago?
Then what about learning their advanced features for tracing and scripting instead of always single stepping?
That is a snarky way to answer.
But here, I was talking how other debugger have not the same problems.
Maybe you just don't write bugs ;)
But really, what do you use in their place? Do you work in an environment that is "debugger by default" (as opposed to a separate step where you need to "debug" instead of "run")?
"println debugging" is a tried and true strategy. Debuggers' firehose of information can start to get really hairy when you have multiple threads of execution, for example. "println debugging" (if you have the right tools) can get you 98% of the way there and show you exactly only the relevant information.
A lot of debuggers have a feature where you can stop the execution of threads you don't want to bother with, which I find to actually be more useful than println debugging.
It's not a satisfying answer really, but I use a bunch of log statements. It's definitely not as good as a debugger, but 9 times out of 10, it's sufficient.
This is one of the main things which has driven the development of julia's logging system; it seems that some people just don't like debuggers very much (I'm one of them) and find staring at logs and attempting to run the code in their head to be a productive alternative.
I think it's the difference between inspecting local vs global program behavior. A debugger gives a very local view of the program but the most difficult bugs are ones where the local behavior is (or seems) correct but the global behavior is wrong. In that case it can be much more useful to run the program to completion with plenty of logging and then to carefully inspect the record of how the state changed.
Have you tried using a debugger as a "dynamic print statement"?
Yeah, and when I did node.js programming, the one time I ever got node-inspector working, I even would inject code in while paused on a breakpoint, which is undeniably useful.
Could be because you've never used a good one. I could see how that distaste would form if all you've ever used was the likes of gdb, lldb, of (if you work in Python) pdb. But when I was switching away from Windows entirely 15 years ago, giving up windbg and Visual Studio debugger was HARD. It's so convenient when you can just _see_ what your program is doing without a lot of extra friction. The downside is, this very much disincentives the writing of tests, because you can get non-trivial pieces of code working without any tests. But with a little self-discipline, I think having a great debugger was a net positive for me, both code quality and productivity-wise.
Throughout my career, I have never met anyone who used MS tools that did not find them excellent and productivity enhancing. In fact I could probably add to MS any of the language vendors from years ago. I remember using Borlands terminal based C++ environment back in the early 90's. That's about 30 years ago and that environment is better than what I use programming on Linux today.
I have often thought that programmers posture over their tool independence to signal their excellence. Before the current generation of programmers, many programmers would proclaim how they didn't need to use higher level languages to assist them in programming because assembly language was sufficient given their reasoning powers. Today programmers proclaim they don't need types to insure data invariants as their reasoning powers are sufficient. They proclaim they don't get any value from unit testing because they can maintain correctness across all development phases using their reasoning powers alone. They proclaim they don't need automatic garbage collection because they can insure correct memory usage using their reasoning powers. They have no use for IDEs, debuggers, or profilers because they believe none of these tools could augment their reasoning powers.
Excellent programmers can indeed compensate for poor tooling through their reasoning powers alone. But if history is a guide, people who don't use the best tools, practices and technologies to produce the best work, at some point, wont produce the best work.
I think the situation on the FOSS side is compounded by the fact that gdb, while it's unquestionably not in any way "state of the art", is also not totally useless, so there's less of a reason to create something that's truly excellent. Moreover, there are whole generations of programmers now who think that tooth extraction compares favorably to using a debugger.
If there wasn't gdb/lldb at all, I'm pretty sure Linux/BSD would have a debugger that's far better than any closed source counterpart.
Well, cite, please.
I think the main problem with debuggers is that I've seen people crippled by the need of them. Literally unable to simply stop and ask what could possibly have caused the outcome they saw. Having to use a program to step through with the required values to reproduce what they should already know will happen when those values are present.
Which isn't to say that live coding and debuggers are bad. However, they are usually much more useful to find out either how something got to where it is, or to augment what you have until it is ready to send for review.
Which languages have you tried to use a debugger with? Debuggers like gdb look awful (at least without a GUI). On the other hand, Chrome's JavaScript debugger is a joy to work with.
I've used Chrome's JS debugger, which I agree isn't so bad (though I don't really do frontend work, and I only managed to get node-inspector working once).
I've also used the Visual Studio debugger for F#, and I think I did gdb with Eclipse a couple years ago when I did C.
GDB is very useable with the TUI mode or the Emacs integration.