Live data from Hacker News

A cross-platform debugger for Go

blog.mailgun.com

41–50 of 65 posts

Re: A cross-platform debugger for Go

#41

Earlier quoted context omitted.

"Also, having the debugging library alter the semantics of the program is 100% guaranteed to lead to bugs that are not visible when using the library, etc" Can you give an example of the kind of bug you expect to see?

say you have: x = 1 x = 2 bar() You set a breakpoint on the call to bar and examine the value of x. You would expect it to be 2, but what if the compiler had decided to move the allocation of x = 2 to after the call to bar? There's no reason why it shouldn't. You'd then see x = 1, which would confuse you.

Thanks for the concrete example. The transformed source code that would get compiled for this example looks like:

  scope.Declare("x", &x)
  godebug.Line(ctx, scope, 3)
  x = 1
  godebug.Line(ctx, scope, 4)
  x = 2
  godebug.Line(ctx, scope, 5)
  bar()
The value of x is visible to all of the godebug.Line calls, so the compiler should know that it can't move x = 2 to after the call to bar.

Re: A cross-platform debugger for Go

#42
post #34
post #7

Earlier quoted context omitted.

> This demonstrates the power of Go generators. We're seeing what are typically language features such as generics and debugging being implemented before runtime using code generation. The result is more functionality without an increase in runtime size or a decrease in performance. Monomorphization is a bog-standard implementation technique for generics. It's not at all unusual.

source?

Just off the top of my head, C++, .NET (via a JIT), Rust, D, MLton, and (I think) Swift all do it.

Re: A cross-platform debugger for Go

#43

Earlier quoted context omitted.

Since it's modifying the source before compiling it, I expect that the compiler will conclude that most optimizations can't be applied when they cross breakpoint boundaries. So, when debugging is turned on, the code would return the right answers, but it wouldn't have the same performance.

"Since it's modifying the source before compiling it, I expect that the compiler will conclude that most optimizations can't be applied when they cross breakpoint boundaries." While true, this depends on the compiler knowing this is a magical breakpoint barrier it can't move things across. The compiler has no idea this is a magical barrier unless something has told it it's a magical barrier. Looking at godebug librar…

I think you're right that it's going to introduce bugs in concurrent code. For example, it's legal to send a pointer through a channel as a way of transferring ownership and never access the object again. If the debugger rewrites the code so that "never accesses it again" is no longer true, it's created a data race.

On the other hand, godebug generates straightforward single-threaded code that creates pointers to locals in a shadow data structure and accesses them later. There's no reason it shouldn't work if you're not using goroutines.

In particular, a previous call to godebug.Declare("x", &x) will add a pointer to what was previously a local variable to a data structure. This effectively moves all locals to a heap representation of the goroutine's stack, to be accessed later. It's going to kill performance, but it's legal to do.

Re: A cross-platform debugger for Go

#44

Earlier quoted context omitted.

say you have: x = 1 x = 2 bar() You set a breakpoint on the call to bar and examine the value of x. You would expect it to be 2, but what if the compiler had decided to move the allocation of x = 2 to after the call to bar? There's no reason why it shouldn't. You'd then see x = 1, which would confuse you.

Thanks for the concrete example. The transformed source code that would get compiled for this example looks like: scope.Declare("x", &x) godebug.Line(ctx, scope, 3) x = 1 godebug.Line(ctx, scope, 4) x = 2 godebug.Line(ctx, scope, 5) bar() The value of x is visible to all of the godebug.Line calls, so the compiler should know that it can't move x = 2 to after the call to bar.

Right, but now you have the opposite problem. Let's say that before the compiler could move x=2 after bar (let's assume bar does not touch x).

Now, in your world, it can't.

So before, you would have seen x=1 in the call to bar, and now when you use the debug library, you will see x=2.

Re: A cross-platform debugger for Go

#45

Earlier quoted context omitted.

"Since it's modifying the source before compiling it, I expect that the compiler will conclude that most optimizations can't be applied when they cross breakpoint boundaries." While true, this depends on the compiler knowing this is a magical breakpoint barrier it can't move things across. The compiler has no idea this is a magical barrier unless something has told it it's a magical barrier. Looking at godebug librar…

I think you're right that it's going to introduce bugs in concurrent code. For example, it's legal to send a pointer through a channel as a way of transferring ownership and never access the object again. If the debugger rewrites the code so that "never accesses it again" is no longer true, it's created a data race. On the other hand, godebug generates straightforward single-threaded code that creates pointers to loc…

"It's going to kill performance, but it's legal to do."

Sure, but it's going to cause the optimizer to do different things than it would have to that variable. As I said, this essentially changes what the compiler is allowed to do, and will expose or hide bugs (usually hide if it hurts the optimizer) :)

One only has to look at the bugzilla's of gcc and llvm to discover all sorts of fun things that barriers hide/expose.

Re: A cross-platform debugger for Go

#46

What an awesome idea to use gopherjs. Just added it to http://golangtoolbox.com/ - if you have more tools that are great please add them here.

Hi, not relevant to the topic. I visited your site, specifically "Homepage > Show all categories > Crypto" (http://golangtoolbox.com/categories/crypto) and was met with:

"template: views/layout:views/categories/show:1:301: executing "views/categories/show::main" at : nil pointer evaluating interface {}.Id"

Happens when viewing any category. Looks like a useful site though.

Re: A cross-platform debugger for Go

#47
post #34

Earlier quoted context omitted.

source?

Just off the top of my head, C++, .NET (via a JIT), Rust, D, MLton, and (I think) Swift all do it.

I was hoping for some article or wikipedia entry that would tie your comment with the parent's comment, and with the original article. Monomorphization is, to my understanding, taking a polymorphic function and instantiating it to the specific type requested. This is done at compile time. Now, the tool in this article interleaves debugging code with original source code. So the connection is... both monomorphization of generics/templates and this tool operate by emitting source code prior to compilation?

Re: A cross-platform debugger for Go

#48
post #12

Earlier quoted context omitted.

Thanks, I didn't know that. The go/token docs don't say much about it. Do you know if there is better documentation somewhere?

http://golang.org/cmd/gc/

I tried using this facility a few months ago based on this very short documentation but couldn't get it working, nor could I search out any further doco on it, so because it wasn't really important I gave up. Can I ask... have any of you ever successfully used this?

Re: A cross-platform debugger for Go

#49

Earlier quoted context omitted.

I think you're right that it's going to introduce bugs in concurrent code. For example, it's legal to send a pointer through a channel as a way of transferring ownership and never access the object again. If the debugger rewrites the code so that "never accesses it again" is no longer true, it's created a data race. On the other hand, godebug generates straightforward single-threaded code that creates pointers to loc…

"It's going to kill performance, but it's legal to do." Sure, but it's going to cause the optimizer to do different things than it would have to that variable. As I said, this essentially changes what the compiler is allowed to do, and will expose or hide bugs (usually hide if it hurts the optimizer) :) One only has to look at the bugzilla's of gcc and llvm to discover all sorts of fun things that barriers hide/expos…

It's clearly not useful for tracking down compiler bugs, but might still be useful for more ordinary bugs in single-threaded user code.

Re: A cross-platform debugger for Go

#50
post #2

This demonstrates the power of Go generators. We're seeing what are typically language features such as generics and debugging being implemented before runtime using code generation. The result is more functionality without an overall increase in runtime size or decrease in runtime performance. It's unusual and it's opinionated, but it works.

What is the difference between the generators in Python vs Go?
Post reply on HN