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

Support plugins #865

Closed
cpg1111 opened this issue Jun 8, 2017 · 7 comments
Closed

Support plugins #865

cpg1111 opened this issue Jun 8, 2017 · 7 comments

Comments

@cpg1111
Copy link

cpg1111 commented Jun 8, 2017

Please answer the following before submitting your issue:

Note: Please include any substantial examples (debug session output,
stacktraces, etc) as linked gists.

  1. What version of Delve are you using (dlv version)? 0.12.2

  2. What version of Go are you using? (go version)? 1.8.1

  3. What operating system and processor architecture are you using? Linux Ubuntu amd64

  4. What did you do?

    dlv exec on an executable that loads a plugin and try to step into the plugin's code.
    The plugin is built with go build -buildmode=plugin --o plug.so and the exec is built with the standard go build -o exec main.go. The code executes fine normally, however I am tracking down a SIGSEGV in the plugin code when it hits an edge case, that is when I try to step into the code and dlv panics.

  5. What did you expect to see?

The child callframe in the plugin

  1. What did you see instead?

This panic stack trace:

Command failed: Internal debugger error: runtime error: invalid memory address or nil pointer dereference
runtime.call32 (0x454328)
        /usr/local/go/src/runtime/asm_amd64.s:514
runtime.gopanic (0x42a07f)
        /usr/local/go/src/runtime/panic.go:489
/runtime.panicmem (0x428f2e)
        /usr/local/go/src/runtime/panic.go:63
runtime.sigpanic (0x43f3ef)
        /usr/local/go/src/runtime/signal_unix.go:290
github.com/derekparker/delve/pkg/proc.next (0x67afd0)
        /home/cgrabowski/go/src/github.com/derekparker/delve/pkg/proc/threads.go:109
github.com/derekparker/delve/pkg/proc.Step (0x67367d)
        /home/cgrabowski/go/src/github.com/derekparker/delve/pkg/proc/proc.go:225
github.com/derekparker/delve/service/debugger.(*Debugger).Command (0x6e09cc)
        /home/cgrabowski/go/src/github.com/derekparker/delve/service/debugger/debugger.go:506
github.com/derekparker/delve/service/rpc2.(*RPCServer).Command (0x8967c1)
        /home/cgrabowski/go/src/github.com/derekparker/delve/service/rpc2/server.go:101
 runtime.call64 (0x4543a8)
        /usr/local/go/src/runtime/asm_amd64.s:515
reflect.Value.call (0x4ae0cf)
        /usr/local/go/src/reflect/value.go:434
reflect.Value.Call (0x4ad694)
        /usr/local/go/src/reflect/value.go:302
github.com/derekparker/delve/service/rpccommon.(*ServerImpl).serveJSONCodec.func2 (0x89f6a2)        
       /home/cgrabowski/go/src/github.com/derekparker/delve/service/rpccommon/server.go:319
runtime.goexit (0x456ac1)
        /usr/local/go/src/runtime/asm_amd64.s:2197
@aarzilli aarzilli changed the title Unable to view or step into code compiled into a plugin Support plugins Jun 8, 2017
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 15, 2018
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 16, 2018
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 16, 2018
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 16, 2018
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 16, 2018
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 21, 2018
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 21, 2018
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 22, 2018
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 22, 2018
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 23, 2018
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Nov 23, 2018
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Dec 4, 2018
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Dec 4, 2018
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Jan 5, 2019
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Jan 5, 2019
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Jan 15, 2019
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
@webern
Copy link

webern commented Feb 4, 2019

I'm surprised there aren't more 'me too' folks on this issue. I guess Go plugins are not so popular. I need to use Go plugins in my project so I will be watching this issue. Thank you.

aarzilli added a commit to aarzilli/delve that referenced this issue Feb 26, 2019
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Feb 27, 2019
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Mar 20, 2019
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
derekparker pushed a commit that referenced this issue Mar 20, 2019
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates #865
aarzilli added a commit to aarzilli/delve that referenced this issue Mar 20, 2019
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Mar 29, 2019
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue Mar 29, 2019
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
@MaxFedotov
Copy link

MaxFedotov commented Apr 7, 2019

Hello @aarzilli, sorry for bothering, got one question regarding plugins and debugging.
Currently on go version go1.12.2 darwin/amd64 when you try to build simple plugin and load it you've got error plugin was built with a different version of package math/bits during debugging (for example consider simple plugins from https://github.com/vladimirvivien/go-plugin-example as example). But when you build app and start it, everything is OK. Is it also related to this issue?

@aarzilli
Copy link
Member

aarzilli commented Apr 8, 2019

Delve builds everything with -gcflags='all=-N -l' the plugins need to be compiled like that too (or you debug the optimized executable with exec).

@MaxFedotov
Copy link

@aarzilli Thanks a lot! This helped

aarzilli added a commit to aarzilli/delve that referenced this issue May 3, 2019
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
aarzilli added a commit to aarzilli/delve that referenced this issue May 8, 2019
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
derekparker pushed a commit that referenced this issue May 8, 2019
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates #865
@derekparker
Copy link
Member

Closing as this is now supported.

@juhwany
Copy link

juhwany commented Jul 22, 2019

@derekparker

Do you have a plan to support debugging plugin in Mac?

cgxxv pushed a commit to cgxxv/delve that referenced this issue Mar 25, 2022
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
cgxxv pushed a commit to cgxxv/delve that referenced this issue Mar 25, 2022
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

Updates go-delve#865
@sh0umik
Copy link

sh0umik commented Nov 12, 2023

@juhwany did you find any way to debug the plugin in macOS? I am running Sonoma 14 with Goland

abner-chenc pushed a commit to loongson/delve that referenced this issue Mar 1, 2024
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).

It does not actually implement support for debugging plugins on linux.

Updates go-delve#865
abner-chenc pushed a commit to loongson/delve that referenced this issue Mar 1, 2024
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).

Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.

Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.

This approach has a few shortcomings:

1. Multiple shared libraries can define functions or globals with the
   same name and we have no way to disambiguate between them.

2. We don't have a way to handle library unloading.

Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.

There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
  break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.

For this reason I consider this approach an acceptable and sustainable
stopgap.

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

No branches or pull requests

7 participants