Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breakpoints in plugins are not working if set before plugin is loaded #1653

Closed
akamensky opened this issue Aug 8, 2019 · 20 comments · Fixed by #3154
Closed

Breakpoints in plugins are not working if set before plugin is loaded #1653

akamensky opened this issue Aug 8, 2019 · 20 comments · Fixed by #3154

Comments

@akamensky
Copy link

Please answer the following before submitting your issue:

  1. Version: 1.2.0 Build: dd4fd5dc9cf5d45092f97f2ba376f3e69d7a5a8e
  2. What version of Go are you using? go version go1.12.7 linux/amd64
  3. What operating system and processor architecture are you using? linux x86_64
  4. What did you do?

Attempt to debug plugin from Goland. Using i.e. https://github.com/vladimirvivien/go-plugin-example.git (compile all plugins with -gcflags='all=-N -l'). Place breakpoints inside functions of plugin and inside main application functions.

  1. What did you expect to see?

Breakpoints of main application work. Breakpoints inside plugins work.

  1. What did you see instead?

Breakpoints of main application work. Plugin breakpoints are ignored.

@derekparker
Copy link
Member

Is there an error or any odd output when you put a breakpoint in the plugin code?

@akamensky
Copy link
Author

Is there an error or any odd output when you put a breakpoint in the plugin code?

No errors, the breakpoints are just skipped as if non-existent

Screenshot from 2019-08-13 12-25-22

@aarzilli
Copy link
Member

I'd like to see output of --log --log-output=rpc. I'm guessing you are setting all breakpoints before starting the program, the ones on plugins fail (because the plugins aren't loaded when the program starts) and goland isn't telling you. We should have delayed breakpoints, but we don't.

@akamensky
Copy link
Author

@aarzilli you are right I am setting breakpoints before starting the application.

Are the arguments you mention for dlv?

@aarzilli
Copy link
Member

Yes. IIRC there's an option to get those logs from GoLand, I think maybe somewhere under the help menu?

@akamensky
Copy link
Author

I will get the log later (did not find it this option anywhere in GoLand btw). Meanwhile, it appears that even after the module loaded I am unable to set breakpoints via IDE, I've set a breakpoint right before call to Greet() and when I hit it, navigate to the source file and set breakpoint there, this normally works with non-plugin code, but here it appears as disabled/inactive breakpoint:

Screen Shot 2019-08-13 at 10 32 23 PM

BTW, the second screenshot is from Mac, so not sure if plugin debugging is even supposed to work there, I can only try again on Linux later, where I can also try to get logs from debugger.

@akamensky
Copy link
Author

akamensky commented Aug 13, 2019

To get this log from IDE I had to make a wrapped bash in place of dlv binary that calls actual dlv binary with extra arguments :heavy_sigh:

Found that in both cases whether I try to create breakpoint before starting application or wait until plugin is loaded it shows same exact error:

2019-08-13T22:49:35+08:00 debug layer=rpc <- RPCServer.CreateBreakpoint(rpc2.CreateBreakpointIn{"Breakpoint":{"id":0,"name":"","addr":0,"file":"/Users/alexey.kamenskiy/GolandProjects/go-plugin-example/eng/greeter.go","line":8,"Cond":"","continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":null,"LoadLocals":null,"hitCount":null,"totalHitCount":0}})
2019-08-13T22:49:35+08:00 debug layer=rpc -> *rpc2.CreateBreakpointOut{"Breakpoint":{"id":0,"name":"","addr":0,"file":"","line":0,"Cond":"","continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":null,"LoadLocals":null,"hitCount":null,"totalHitCount":0}} error: "could not find file /Users/alexey.kamenskiy/GolandProjects/go-plugin-example/eng/greeter.go"

However the file is most definitely there:

$ ls -la /Users/alexey.kamenskiy/GolandProjects/go-plugin-example/eng/greeter.go
-rw-r--r--  1 alexey.kamenskiy  staff  145 Aug 13 22:26 /Users/alexey.kamenskiy/GolandProjects/go-plugin-example/eng/greeter.go
$

Also on Darwin, when i create breakpoint before running application, it automagically pops an Assembly file in editor "paused" on a RET instruction (same does not happen on Linux):

Screen Shot 2019-08-13 at 10 59 21 PM

@aarzilli
Copy link
Member

@akamensky
Copy link
Author

@aarzilli fair enough, I’ve sorted of expected this on Mac since it seems support for it lagging on all fronts.

I’ll re-test tomorrow with logging on Linux and follow up here.

@akamensky
Copy link
Author

Tested on Linux and it appears that if I set breakpoints before start application, then it skips them with same error: could not find file /path/to/file.go. If I, however, create a breakpoint before calling plugin method and once it hits that breakpoint set one inside plugin -- this new breakpoint works as expected.

There is one major issue with this though -- if I restart process the breakpoint inside plugin is no longer working.

Now sure if this is possible to detect from delve, but I would imagine "re-evaluating" breakpoints when detecting plugins being loaded should fix this issue? (re-evaluating here means check if all attempted breakpoints were successfully set, if not all, then check if any of unsuccessful are referring to loaded plugin, if they are -- set them at this point of time)

@akamensky
Copy link
Author

Also I think this is independent from #1628 which refers to specifically Darwin platform where debugging does not work at all.

@akamensky akamensky changed the title Breakpoints in plugins are not working Breakpoints in plugins are not working if set before plugin is loaded Aug 14, 2019
@nd
Copy link
Contributor

nd commented Aug 19, 2019

Filed an issue for GoLand: https://youtrack.jetbrains.com/issue/GO-7957. Maybe we can fix it without changes in Delve. E.g. to set a invisible breakpoint inside the plugin.Open and re-sent breakpoints for which Delve din't find files.

@akamensky
Copy link
Author

@nd I don't think this has anything to do with GoLand itself. From how Delve sets breakpoints the logic GoLand follows looks fine. GoLand would not know about those details, it passes breakpoint information to Delve, which in turn should be able to handle it. Also GoLand is not the only IDE, but Delve is basically only debugger that works for Go.

@FloThinksPi
Copy link

Hmm would it generally be possible for delve to "remember" breakpoints it has no reference to (executable does not contain debug information for file /somefile.go) and re-evaluates these breakpoints if/after a plugin load has occurred ?

@aarzilli
Copy link
Member

Yes but there is no existing code for either: (a) deferring a breakpoint creation, (b) catching a plugin load as soon as it happens

@pepjo
Copy link

pepjo commented Jan 19, 2021

I also hit this issue when trying to debug a plugin, but in my case, it happened in vs code.

@aarzilli I would be interested in implementing the needed features if there is an agreed path.

@aarzilli
Copy link
Member

It would probably have to be something like this:

  • figure out where to put a breakpoint so that it gets hit after a plugin has been loaded (it needs to work on all supported os/arch combinations)
  • add a callback function to proc.Breakpoint and call it when the breakpoint is detected in Continue
  • change service/debugger.Debugger to use these two mechanisms to implement deferred breakpoints
  • add an option to the CreateBreakpoint API argument to create a deferred breakpoint
  • change the break command to ask if the user wants to create a deferred breakpoint when normal breakpoint creation doesn't work

@pepjo
Copy link

pepjo commented Apr 13, 2021

Thanks for outlining the tasks. However, It has become apparent that I will not have much time to work on this the following months, hopefully someone else can give it a try.

@YIDWang
Copy link

YIDWang commented Nov 12, 2021

is there any documentation available or tips you can provide for debugging plugin code in mac?
plugin still can't debug on mac。

@FloThinksPi
Copy link

FloThinksPi commented Nov 12, 2021

@YIDWang

is there any documentation available or tips you can provide for debugging plugin code in mac? plugin still can't debug on mac。

See golang/go#25841, not possible on mac atm afaik.

aarzilli added a commit to aarzilli/delve that referenced this issue Jan 24, 2022
Adds a LogicalBreakpoint type to represent logical breakpoints
explicitly. Until now logical breakpoints were constructed implicitly
by grouping physical breakpoints together by their LogicalID.

Having logical breakpoints represented explicitly allows for a simpler
implementation of disabled breakpoints, as well as allowing a simple
implementation of delayed breakpoints (go-delve#1653, go-delve#2551) and in general of
breakpoints spanning multiple processes if we implement debugging
process trees (go-delve#2551).

Updates go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Feb 18, 2022
Adds a LogicalBreakpoint type to represent logical breakpoints
explicitly. Until now logical breakpoints were constructed implicitly
by grouping physical breakpoints together by their LogicalID.

Having logical breakpoints represented explicitly allows for a simpler
implementation of disabled breakpoints, as well as allowing a simple
implementation of delayed breakpoints (go-delve#1653, go-delve#2551) and in general of
breakpoints spanning multiple processes if we implement debugging
process trees (go-delve#2551).

Updates go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Feb 18, 2022
Saves information on how the breakpoint was originally set so that it can be used when the breakpoint is restored, either after a restart or when a breakpoint is re-enabled after being disabled.

This will also allow implementing delayed breakpoints for plugins or multi-process debugging.

Updates go-delve#1653, go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue May 20, 2022
Adds a LogicalBreakpoint type to represent logical breakpoints
explicitly. Until now logical breakpoints were constructed implicitly
by grouping physical breakpoints together by their LogicalID.

Having logical breakpoints represented explicitly allows for a simpler
implementation of disabled breakpoints, as well as allowing a simple
implementation of delayed breakpoints (go-delve#1653, go-delve#2551) and in general of
breakpoints spanning multiple processes if we implement debugging
process trees (go-delve#2551).

Updates go-delve#1653
Updates go-delve#2551
derekparker pushed a commit that referenced this issue May 25, 2022
Adds a LogicalBreakpoint type to represent logical breakpoints
explicitly. Until now logical breakpoints were constructed implicitly
by grouping physical breakpoints together by their LogicalID.

Having logical breakpoints represented explicitly allows for a simpler
implementation of disabled breakpoints, as well as allowing a simple
implementation of delayed breakpoints (#1653, #2551) and in general of
breakpoints spanning multiple processes if we implement debugging
process trees (#2551).

Updates #1653
Updates #2551
aarzilli added a commit to aarzilli/delve that referenced this issue Jun 2, 2022
Saves information on how the breakpoint was originally set so that it can be used when the breakpoint is restored, either after a restart or when a breakpoint is re-enabled after being disabled.

This will also allow implementing delayed breakpoints for plugins or multi-process debugging.

Updates go-delve#1653, go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Jun 2, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Jun 9, 2022
Saves information on how the breakpoint was originally set so that it can be used when the breakpoint is restored, either after a restart or when a breakpoint is re-enabled after being disabled.

This will also allow implementing delayed breakpoints for plugins or multi-process debugging.

Updates go-delve#1653, go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Jun 9, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Jun 12, 2022
Saves information on how the breakpoint was originally set so that it can be used when the breakpoint is restored, either after a restart or when a breakpoint is re-enabled after being disabled.

This will also allow implementing delayed breakpoints for plugins or multi-process debugging.

Updates go-delve#1653, go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Jun 12, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Jul 16, 2022
Saves information on how the breakpoint was originally set so that it can be used when the breakpoint is restored, either after a restart or when a breakpoint is re-enabled after being disabled.

This will also allow implementing delayed breakpoints for plugins or multi-process debugging.

Updates go-delve#1653, go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Jul 16, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Aug 4, 2022
Saves information on how the breakpoint was originally set so that it can be used when the breakpoint is restored, either after a restart or when a breakpoint is re-enabled after being disabled.

This will also allow implementing delayed breakpoints for plugins or multi-process debugging.

Updates go-delve#1653, go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Aug 4, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Aug 12, 2022
Changes FindLocation to support multiple targets and adds an AddrPid
member to api.Breakpoint so that clients can set breakpoints by address
when multiple targets are connected (but at them moment this field is
ignored).

Updates go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Aug 12, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Aug 17, 2022
Changes FindLocation to support multiple targets and adds an AddrPid
member to api.Breakpoint so that clients can set breakpoints by address
when multiple targets are connected (but at them moment this field is
ignored).

Updates go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Aug 17, 2022
Changes FindLocation to support multiple targets and adds an AddrPid
member to api.Breakpoint so that clients can set breakpoints by address
when multiple targets are connected (but at them moment this field is
ignored).

Updates go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Sep 21, 2022
Changes FindLocation to support multiple targets and adds an AddrPid
member to api.Breakpoint so that clients can set breakpoints by address
when multiple targets are connected (but at them moment this field is
ignored).

Updates go-delve#1653
Updates go-delve#2551
derekparker pushed a commit that referenced this issue Sep 26, 2022
Changes FindLocation to support multiple targets and adds an AddrPid
member to api.Breakpoint so that clients can set breakpoints by address
when multiple targets are connected (but at them moment this field is
ignored).

Updates #1653
Updates #2551
aarzilli added a commit to aarzilli/delve that referenced this issue Sep 27, 2022
Adds field to breakpoint struct to track how a breakpoint was
originally set, moves the logic for disabling and enabling a breakpoint
to proc.
This will allow creating suspended breakpoints that are automatically
enabled when a plugin is loaded. When follow exec mode is implemented
it will also be possible to automatically enable breakpoints (whether
or not they were suspended) on new child processes, as they are
spawned.

It also improves breakpoint restore after a restart, before this after
a restart breakpoints would be re-enabled using their file:line
position, for breakpoints set using a function name or a location
expression this could be the wrong location after a recompile.

Updates go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Sep 27, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
aarzilli added a commit to aarzilli/delve that referenced this issue Sep 27, 2022
Adds field to breakpoint struct to track how a breakpoint was
originally set, moves the logic for disabling and enabling a breakpoint
to proc.
This will allow creating suspended breakpoints that are automatically
enabled when a plugin is loaded. When follow exec mode is implemented
it will also be possible to automatically enable breakpoints (whether
or not they were suspended) on new child processes, as they are
spawned.

It also improves breakpoint restore after a restart, before this after
a restart breakpoints would be re-enabled using their file:line
position, for breakpoints set using a function name or a location
expression this could be the wrong location after a recompile.

Updates go-delve#1653
Updates go-delve#2551
derekparker pushed a commit that referenced this issue Sep 28, 2022
Adds field to breakpoint struct to track how a breakpoint was
originally set, moves the logic for disabling and enabling a breakpoint
to proc.
This will allow creating suspended breakpoints that are automatically
enabled when a plugin is loaded. When follow exec mode is implemented
it will also be possible to automatically enable breakpoints (whether
or not they were suspended) on new child processes, as they are
spawned.

It also improves breakpoint restore after a restart, before this after
a restart breakpoints would be re-enabled using their file:line
position, for breakpoints set using a function name or a location
expression this could be the wrong location after a recompile.

Updates #1653
Updates #2551
aarzilli added a commit to aarzilli/delve that referenced this issue Oct 1, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
derekparker pushed a commit that referenced this issue Oct 4, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes #1653
Updates #2551
gfszr pushed a commit to gfszr/delve that referenced this issue Oct 23, 2022
Allows setting suspended breakpoints and try to enable them
automatically after every time a plugin is loaded.

Fixes go-delve#1653
Updates go-delve#2551
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants