Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

"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?



Sure, i'll stick to bugs invisible with the library, and visible without it:

If you've inserted compiler barriers it can't move code across, the compiler will no longer perform the same optimizations with and without your debug library.

Those optimizations often make bugs visible, because variables no longer have the value you expect them to at the time you expect it, etc.

Add in threads, and the problem gets worse:

http://preshing.com/20120515/memory-reordering-caught-in-the...

Look at the behavior this has with and without the barrier. It's buggy without it. With it, it's fine.

This is exactly equivalent to:

Without the debugging library, the code is clearly buggy and doesn't work in user-visible ways.

With the debugging library, if i insert a breakpoint where the current asm barrier is, it now behaves correctly 100% of the time, even though it's broken.


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.


But it's not really material, because bar doesn't touch x (and if it did, this problem wouldn't exist to begin with).

In other words, it might be a bit strange and cause a slight detour in your quest to discover the cause of a bug, but it wouldn't actually change any behavior or cause any issues.


Your argument is essentially: The barriers you insert, even if they block optimization, will never block optimization in a way that changes behavior. This is demonstrably false, since you are, among other things, taking the address of a variable, which means escape analysis won't do things to it, etc.

You can argue "The behavior it changes doesn't matter". As i've shown, 1. it does in a threaded environment (like, you know, go) 2. It depends on whether your code is buggy or not.

IT's certainly true that it never, on it's own, causes bugs. But as i've shown, it can make bugs appear to come or go.

If you don't think that will ever happen, i don't know what to tell you, other than "It has happened in literally every compiler that has ever had barriers like this".

Without any evidence why Go should be different here, i don't see why go will be different here.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: