1. 23

  2. 8

    This is not so much puts debugging. It looks like Ruby provides enough introspection that its runtime can be used to debug itself. Even coming from a Python background, I was surprised to see that so much of this was possible.

    1. 4

      The only debugger I’ve found to be worthwhile is the one in Visual Studio, for any language (I’ve done C# and JS in it so far) - anywhere else, I’ll just put printfs. VS all the stuff you’d expect and puts it together well.

      1. 1

        The fun starts a few iterations in, once you discover that you want to puts something slightly different from what you originally wrote. Then you have to alter the puts, load up the entire application again (which can take minutes, depending on the size of your codebase) and navigate it back into exactly the state you had before. (Hope you kept a lab notebook!)

        1. 3

          As another puts debugger (well, print because Python) I’d always wondered what was so great about debuggers that people made such passionate defenses of them, and worried that maybe I was missing some crucial tool or insight.

          However, I don’t think I’ve ever had to debug problems other than (a) tools that run deterministically to completion in minutes at most, or (b) production systems where debugging is impractical anyway. So I guess I’m just outside the debugger target demographic.

          1. 10

            I agree that it’s not especially practical to attach a “stop the world” debugger (like gdb) to a production process. But this is most definitely not the only kind of debugging tool that exists.

            I make extensive use of DTrace to collect data about function calls and other events; both in the operating system kernel and in various user mode software. I can dynamically enable instrumentation to track the frequency of, and arguments to, many different kinds of probe points. For example:

            • system call entry (with arguments) and exit (with return value)
            • C language function entry (with arguments) and return (with return value)
            • user-defined probe points (USDT) that can be created from C, or Javascript, or many other languages
            • when a process goes to sleep (for I/O, or other reasons) or when it is woken up
            • profile data gathered at a regular interval

            This tracing data can be aggregated into a number of interesting visualisations to assist with reasoning about the dynamic behaviour of a process when running in production without inducing significant overhead. One of the most compelling is the flamegraph. Combining a tool like stackvis with DTrace profiling data, I can generate flamegraphs of different types to better understand what a busy program is doing.

            There is also post-mortem debugging: when a production process experiences an unanticipated state it should abort, allowing the operating system to create a core file. This process can happen quickly and the process can be restarted by the supervisor, returning the system to service automatically. This core file can be loaded at my leisure into a debugger like the illumos modular debugger, mdb. With mdb I can inspect the entire state of the program at the time it failed and hopefully find the bug. This kind of debugging is especially helpful with issues that are not reproducible, or where the failure mode is extremely rare. Sometimes a bug might only be seen once, and a single core file can provide enough data to determine the cause. With a tool like mdb, I have access to an incredible amount of information about the process at the time of failure, even if some of the program is written in something like Javascript.

            The reason I am so enamoured of these tools is that they allow me to instrument software in production without modifying and redeploying it. Depending on how you use DTrace it can have low, or even near-zero probe overhead when enabled – when disabled, there is generally no overhead. I can even get insight into programs I did not write or compile myself, which has been instrumental in work on the LX brand at Joyent. We often deal with bugs that are not reproducible, or which disappear when the program is modified to include debug output: the extra work of logging can introduce variations in system behaviour. Safe, low impact, feature-rich debugging tools are (in my experience) a vital part of operating a production software system.

          2. 0

            Lots of things are too annoying to be feasible if you have a system that doesn’t let you reload files on an individual basis. Doesn’t mean the technique is worthless for people who do live in the 21st century.