Go has a debugger and it's awesome
blog.cloudflare.com
blog.cloudflare.com
Note that this needn't mean that the tools themselves run in production: for example, Valgrind is incredibly useful because it finds really nasty, production-grade issues -- even if it is only meaningfully usable in development. Similarly, postmortem debugging tooling is extraordinarily valuable for production problems -- and requires no tooling in the production environment itself. We have developed such tooling for node.js[2], and found it to be invaluable. There is nascent postmortem debugging support for Go[3], but there is much more to be done -- just hoping that some in the Go community see the value of debugging production problems!
[1] http://www.infoq.com/presentations/Debugging-Production-Syst...
Some of us do. As I said in another post, Solaris support will only get better. As for Linux, some people obviously care, Go had some form of gdb support from quite early on. Unfortunately, it's not that people don't care about making the gdb support better, it's just that this is all that can be done with the gdb-python interface right now, due to the limitations of gdb...
At least, now with frame pointers, dynamic instrumentation works better.
I just can not remember where I heard it (some podcast maybe), but is my understanding that the Go Team hinted the possibility of something like JMX coming to the Go runtime.
Not all bugs only happen on production load, architecture, etc. Many times (with DNS servers even more so, I'd say) bugs are simple state or logic bugs. The Heisenbugs exist. The complex resource-constrained races exist. And I find it fun to track them down, but many bugs are much more mundane, and godebug is a great tool for catching those.
Speaking instead about hard to trace production bugs, I think the Go design and library deserve their daily share of praise here, since they solve many of those problems. Take Valgrind (or ASAN). Amazing tools. Completely useless in Go -- the language is memory-safe and will make that kind of bugs both hard to introduce and immediately detectable.
And about concurrency, first of all the simple design makes bugs harder to introduce and easier to reason about. But even when they make their way in I find provisions like net/http/pprof and its various profile a pleasure to work with. And finally there's obviously the race detector.
Still, I can't wait to see more tools developed to cover different Go debugging needs. Today I'm just happy about making my println() session much more pleasant and elegant :)
[1] http://dtrace.org/blogs/ahl/2004/07/13/number-11-of-20-libum...
[2] https://queue.acm.org/detail.cfm?id=2039361
Edit: added a much better reference.
For a specific kind of leak. Java heapdumps and MAT are great postmortem heap-debugging tools (of course, Java Flight Recorder is even awesomer, but unfortunately not part of OpenJDK).
No! You can enforce memory safety at compile time and use the platform's native memory allocation subsystem. There's no need for memory safety to imply any extra runtime support.
[1]: https://github.com/rust-lang/rust/blob/master/src/liballoc/h...
This is a problem of GC, not of memory safety. Memory safety does not require GC.
> More generally, do not fall into the trap of correctness from smugness: nasty production bugs can exist in any language, and time is much better spent on the production tooling to debug such problems rather than simply asserting that such bugs are tautologically impossible.
The failure modes of the lack of memory safety range from "annoying crash due to null pointer dereference" up to "millions of users at risk of 0-day RCE due to use after free". When the stakes are that high, it's worth spending time to attack those bug classes systematically as opposed to just tackling these bugs in production one-by-one.
No, it doesn't. That's literally what Rust (what I worked/work on) is all about. Memory safety is all done at compile time, and it's boiled away to direct access to the platform's native memory subsystem. Platform-native tooling "just works", and I use it every day.
We had a client once using our system, who would see anomalies only after long uptimes at sustained high loads. It took six months to find the cause (a race condition in the database code) because we had so few tools at our disposal to look at the post-mortem state of the program. Running the software at those loads for the weeks or months it took to reproduce the problem under a debugger was obviously not a tenable proposition, and reproducing the variability of the particular real-world traffic was difficult to do in a controlled environment. And the software wasn't written with any eye towards making state available for post-mortem debugging.
I guess "don't write complicated multi-threaded software in C" is a pretty good response to the above too. That particular bug couldn't have happened in say Rust (though it could have in Java).
[1] https://github.com/joyent/illumos-joyent/blob/master/usr/src...
When all else fails this is really all you are going to have to go by. Coming from the Microsoft side of the story I have come to a conclusion that any sufficiently well designed postmortem debugger is a few steps away from being a live/production debugger. Windbg, as a prime example of this, can be used to debug memory dumps, live processes and remote (TCP) processes using exactly the same debugging tools binaries (and scripts/plugins that you write).
Debuggers have to be the biggest source of friction, for me, when adopting things like Go. If you are in charge of "production" you can throw in a few printlns, however, you can't just approach someone like the HP and say "can I put this debug binary on your production system?" No, the absolute best you can hope for is a memory dump and those memory dump had better count as you are only going to get maybe a few.
Maybe it's because not many devs deal with this kind of stuff, which is probably why it isn't a top priority for things like e.g. Go. To some of us, though, the most important language of a feature is easily the quality of the debugger associated with it.
Either way, great slides Bryan - it's nice to see at least one "modern" language taking these issues seriously.
Meanwhile, outside my windows, it seems the world pretty much just rejected types, debuggers...
"You can do println debugging and generics will just make the language too hard to learn and the runtime too complex".
It used to be the other way around. I was young and the old guys used to say "I'll use my punchcard/command line debugger/whatever, you kids can use your fancy IDE all you want".
Now I sound like a dinosaur for wanting to edit my code in place while debugging, and for being whiny about type systems. What the hell happened?
Also, get off my lawn.
They added that two years ago:
http://blogs.msdn.com/b/visualstudioalm/archive/2013/06/26/d...
> or how watch expressions can't have lambdas in them.
That's a limitation on how lambdas work. Doubt it could be solved.
AFAIK, this wasn't a problem with Smalltalk. Watch expressions would have worked in somewhat the same way as conditional breakpoints, and you couldn't have those without allowing Blocks, which are the equivalent of Smalltalk lambdas.
This may be a problem with the CLR, though.
Solved in VS 2015.[1]
[1]: http://blogs.msdn.com/b/visualstudioalm/archive/2014/11/12/s...
When your system interacts well with the larger world, this results in more "commerce" with the larger world, which tends to result in greater recognition and larger and healthier communities. It's a virtuous cycle.
Having the best, most well developed developer tools is a win for the individual developer, but fitting in well with the larger world is a win for the entire developer community. The latter is going to be 10X more visible than the former. (Also, think about which communities manage to have both!)
Also, get off my lawn.
Yeah, kids, get off my lawn! At least do enough research to know what's gone before! (Re: Alan Kay's quip about "almost a field.")
Most mainstream programming languages fit in well with the larger world, that's why a lot of people use them. They also have working debuggers, a ton of libraries and tools.
I placed the concern into a historical context re: language comparison wars.
Most mainstream programming languages fit in well with the larger world, that's why a lot of people use them.
Deployment is a big issue. Go really shines in this regard.
They also have working debuggers, a ton of libraries and tools.
My point is precisely that the 1st and last items above aren't everything.
If you want to attach to running processes, use delve, it's awesome. For me personally, even with Go's short build times, you can't just deploy a new binary into a running system to see where a problem lies. Sometimes there is just no way around a traditional debugger.
http://plan9.bell-labs.com/sys/doc/acidpaper.html
or on Unix
https://swtch.com/plan9port/man/man1/acid.html
Watch it in action
Go is really annoying to debug in acid though, because symbols contain dot characters. Somewhat ironically this was done because Unix debuggers were getting confused by the unicode middle dot character, so the unicode middle dot is replaced in the symbol and debug tables with a regular dot.
But on Plan 9 we should not do this process and we should keep the original middle dot.
The very fact that that is a headline make me think I'll wait a bit before introducing Go into my tech stack.
https://github.com/derekparker/delve delve as mentioned other places is more of a true go debugger
Mdb support for Go will be significantly improved in the short term.
Also note that since Go has (optional) frame pointers, tools like DTrace, ktap, kprobes and uprobes, etc work much better (almost as well as for C). SystemTap works too, just that it chokes on Go DWARF without a patch. I will probably fix this soon.
Yes, a lot of people have gone to production with crappy technologies, this is meaningless. The real question is: could they have done it more easily using a better technology?
I don't think that's meaningless. I take it to mean that your (our, my) valuation of technologies does not hold the relative importance (or correctness) that it's perceived to hold.
As a programmer using Go, I think the comparison is spot on -- if you credit Go for having a much cleaner architecture, vastly better design around security, and profoundly well thought out trade offs.
With some work on libraries and tooling, Go could well become the basis of the next PHP, and become the tool of choice for small web projects. If this happened, the world would be a better (in terms of software-sanity, performance, and security) place.
50 years ago there were a ton of companies that were confidently using hex machine code for large systems in production. That doesn't mean things wouldn't have been 100x easier for them with higher level languages and more modern tools.
Of course I can get by without a debugger if I really need to, but that doesn't mean I won't be a lot more productive with one.
Go, however, is kind of like a memory-safe C...it's almost impossible to actually create super high-level abstractions where you can't tell what the code is doing.
For me, unit tests and the occasional log/print cover 99% of my Go debugging needs.
1. If you debug with this, you're debugging different code to what blew up in production for example. Subtle timing issues wiped out instantly and memory ballooning masked etc.
2. If you leave it in for prod, it's going to have masses of call overhead.
You can debug well with assertions, logging and unit tests. There is no need for this. I rarely have to spin up a debugger these days.
It's as worthwhile as the bugs they can find with it. I wish the author would tell us if he found the bug in the dns program.
This is not unique to Go: python's several debuggers require cooperation with the inspected process. This is exactly the opposite of a buggy situation. gdb's python support is very limited in terms of debugging capabilities, yet it's the only option you have if you're using an external event loop handler, such as gtk/qt/glib (not so uncommon). I guess I should be grateful I have those at least.
http://blog.mailgun.com/introducing-a-new-cross-platform-deb...
Source rewriting is indeed quite powerful. You can use this technique to write a code coverage tool in Smalltalk. (Grab the source code of a method, apply parser-transformations, compile an instrumented version, swap the bytecode of the original method with the instrumented one. Make the instrumented method know how to swap itself back when everything is triggered.) A typical developer can write such a tool and have it become functional in one or two days. An exceptional one can do it in hours.
Iterating more produces more innovative applications and software tools. This is why fast compiles and parser tools are a winning combination.