Hacker News new | ask | show | jobs
by temporallobe 951 days ago
None of these are weird or something the browser is trying to hide from you, just things that an experienced front-end developer would probably know, although I was not aware of the monitor() command.

That being said, I am pleasantly surprised at the debugging and development tooling that is built right into most modern browsers. It really does make the UI development experience very powerful. I wish more back-end languages had this experience.

4 comments

> I wish more back-end languages had this experience.

I know what that feels like. I have that same feeling about a whole bunch of languages that has been available in .NET for at least 15 years now.

When I got into programming, I moved from VB6 to VB.NET to C#, the latter two using a cracked version of MS Visual Studio I downloaded at school. I only started seriously using the debugger somewhere around the time I taught myself C#.

Because of this, I got used to the idea that in a normal debugger, you could just click and drag back the point of execution, modify the code, and hit resume. The VS time traveling debugger will actually revert variable assignments, recompile the modified code, insert it in its place, and continue execution. This wouldn't work with P/Invoke calls, but it worked great for what I was trying to do. Debugging and fixing mistakes was absolutely trivial.

Imagine my betrayal when I found out that there was nothing like this in C++, or Java, or Javascript. Java has gotten a similar feature, but I've never worked with an IDE that integrated it even close to how well VS 2008 integrated it.

Even today, this seemingly basic feature that I took for granted just isn't available in many modern IDEs. I understand natively compiled languages like C/C++/Rust/Go not supporting the inline code replacement feature, but the hot reload in languages like Kotlin, Java, and Javascript just don't work like it did for me back in 2008.

As for all these tricks: I think most of them are available in most IDEs. Anything involving conditional breakpoints will work regardless of the language you use (although languages like Rust can have some restrictions). Tracing callers should work in any decent debugger. Timing individual functions may require writing out long package names to get to the right methods, but they should be available. The monitor() trick can be replaced by a logging method breakpoint.

How well DOM-related debugging works, will depend on whether or not your GUI framework uses a DOM and how it's constructed. If you're composing a DOM from multiple individual functions (like in React/Flutter/Kotlin Compose) then you can add breakpoints to all the relevant state alterations. If your tooling uses a more C-inspired windowing mechanism, you're probably going to have to get creative.

When you get down into the weeds of it, I think you'll find that more of these features are available for backend languages than you might expect. I would recommend any developer to occasionally read the changelogs of their IDEs (or to grab an IDE if you normally don't use any) and take a few moments to explore the possibilities of modern debuggers.

I love your description of undoing code execution, modifying the code and continuing. I think too often these days because of the UNIX philosophy of doing one thing well, the debugger and the compiler and even the linker are different projects, making it unnecessarily complicated to combine these tools other than passing blobs of output into another tool's input. We should aim higher.
What pre-historic Java IDE were you using ? Intellij has supported time travel debugging in Java for nearly a decade.

https://www.jetbrains.com/help/idea/altering-the-program-s-e...

Back then, Eclipse was what every guide and book told me to use, so that was where I started. These days I'm mostly on Jetbrains products. Microsoft made VS a weirdly slow, bloated piece of kit, but I still miss some of the features they have had for ages.

I don't get automatically reloaded classes in IntelliJ, though I think there's a button to manually reload code manually? The whole ease of development came from not having to manually pick what code to reload while debugging. Java also seems to have a bunch of limitations that C# doesn't have (and didn't have back when I tried it on Windows). For example, you can't add a method, or alter the return type of a method.

As for time travel debugging, I'm not sure how you do that in IntelliJ? I can't even see any way to undo the previous line of execution, let alone step through code in two directions. It looks like there are plugins for a bunch of languages, though, but those are all external tools built by third parties.

Rolling back executed code seems to work in Rider, but I don't seem to get any Edit and Continue functionality on Linux, which is probably a Microsoft thing.

It looks like I was mistaken though, "IntelliTrace" was a VS2010 feature, not 2008: https://learn.microsoft.com/en-us/archive/msdn-magazine/2010...

> Imagine my betrayal when I found out that there was nothing like this in C++, or Java, or Javascript.

For compiled languages (C, C++, Go, Rust etc.), check out https://rr-project.org/

This looks rather neat, and there seems to be ample IDE support as well! It looks absolutely perfect, but makes me wonder why this isn't included in VS Code and IntelliJ by default when you install a (supported) language's debugger.
> I wish more back-end languages had this experience.

the jvm debugging experience is pretty good imho.

It's the compiled languages that have a poor experience with debugging - try injecting code to execute in a c debugger! It's hard as hell to do!

> try injecting code to execute in a c debugger! It's hard as hell to do!

I mean, theoretically, not really? Allocate a page RW, put in some compiled code, remap as R+X, redirect execution there, return code execution to where it was. Jumping through those hoops will be more expensive when you use the debugger like that (you'd need to hot patch some kind of jump statement to circumvent that) but it's not exactly impossible.

Things become difficult when the compiler starts optimizing out code, because the debugger would need to keep track of everything, but I don't see why it'd be technically impossible to do so.

Executing code in a C debugger is basically how modern reverse engineering works, it's a lot harder than in other languages but it's certainly possible.

Yeah, both GDB and LLDB know how to do this.
You know the tooling leaves something to be desired when editing instruction bytes is the best option to NOP out an assert - for example.
Generally a conditional breakpoint is good enough to do this (though perhaps not very fast).
It's a joke title.
I think the author was just having a bit of fun with the title