This came up during a routinely scheduled meeting between the Delve team and folks from the Go team and it was suggested by @heschik to open an issue about this to ensure it stays on folks minds.
Delve leverages the debug.asyncpreemptoff in order to disable the functionality on Windows  (where it won't play well with debuggers) and may use it on other platforms as well to disable the functionality when run under Delve  .
This issue is mostly to get feedback and assurance that we can rely on this feature for the foreseeable future.
The text was updated successfully, but these errors were encountered:
Thanks for bringing this up. I don't think there's any particular reason why this would go away in the future. There are a lot of benefits to cooperative preemption (mostly it's much cheaper when it works), so that's not going away, and the two systems are relatively orthogonal, so it's quite easy to turn off the async part.
One thing we may have to watch out for is doing optimizations that assume async preemption works. For example, it would be nice to more aggressively eliminate function prologues where we can prove the stack check isn't necessary, but that creates more situations where cooperative preemption isn't sufficient. Maybe we still can't do optimizations like that because of their impact on debuggers.
There's an idea I've been kicking around for a while... What if the runtime provided more of a debugger agent? I think you would still break in to a process using ptrace/whatever, and use DWARF for symbolization of data and source code. But the runtime could provide a debug API to the scheduler in particular, which seems to be where most of the friction is. For example, the debugger would probably still inject INT3s for breakpoints, but may handle them by immediately reflecting them back to the runtime: ask the scheduler to suspend that goroutine (or all user goroutines) and immediately resume the OS process, even though the user is still sitting at a debug prompt.
For example, the debugger would probably still inject INT3s for breakpoints, but may handle them by immediately reflecting them back to the runtime: ask the scheduler to suspend that goroutine (or all user goroutines) and immediately resume the OS process, even though the user is still sitting at a debug prompt.
I don't think this helps with the current issues we are having. For macOS the problem is that we are receiving signals at all, bouncing everything back to the process wouldn't make this faster it would just make breakpoints twice as slow. For linux we don't have any problems (that we know of) and this would just make breakpoints twice as slow. In theory it could help with the windows problem, however the debugger knows where the breakpoints are, while the runtime doesn't.
I'm not sure I understand why this would make breakpoints twice as slow. It seems like the same total work. Admittedly, this is only a rough sketch of an idea; there could well be important details I'm overlooking.
In terms of context switches between the debugger and the process we are currently doing one when we get the breakpoint signal if we make the process do some of the work it would be two context switches.
On macOS the biggest source of latency is communication between debugserver and delve and we have to do it every time we have to route a signal so that would at minimum make it twice as slow, possibly N time slower (N = number of threads) if the runtime has to send a signal to stop each thread.