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

plugin: Incorrect Symbol Table generation #19748

Closed
slightnerd opened this issue Mar 28, 2017 · 4 comments
Closed

plugin: Incorrect Symbol Table generation #19748

slightnerd opened this issue Mar 28, 2017 · 4 comments

Comments

@slightnerd
Copy link

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.8 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/export/home/sll2/go"
GORACE=""
GOROOT="/usr/local/sll2/go18src/go"
GOTOOLDIR="/usr/local/sll2/go18src/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build859461664=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.

When using a 10 different functions in a plugin the plugin_open process confuses dot notated names after trying to delete entry in symbol table build in plugin_dlopen.go

    for symName, sym := range syms {
            fmt.Println("symName : ", string(symName))
            isFunc := symName[0] == '.'
            if isFunc {

error --> delete(syms, symName) <- error deleting from list while processing list
symName = symName[1:]
}

            cname := C.CString(pluginpath + "." + symName)
            p := C.pluginLookup(h, cname, &cErr)
            C.free(unsafe.Pointer(cname))
            if p == nil {
                    return nil, errors.New("plugin.Open: could not find symbol " + symName + ": " + C.GoString(cErr))
            }
            valp := (*[2]unsafe.Pointer)(unsafe.Pointer(&sym))
            if isFunc {
                    (*valp)[1] = unsafe.Pointer(&p)
            } else {
                    (*valp)[1] = p
            }             
           syms[symName] = sym
    }

What did you expect to see?

syms : map[.AX_Init: .AX_Print: .AX_Init.func1: .AX_Apply.func1: .AX_Apply.func2: .AX_Release: .AX_Apply: .AX_Message: .AX_ClearMessage: .AX_Trace: AZ_ITEM:]
symslen : 11 But looped 13 times. because delete in loop changed loop.
symName : AZ_ITEM
symName : .AX_Apply
symName : .AX_Message
symName : .AX_ClearMessage
symName : .AX_Trace
symName : .AX_Apply.func2
symName : AX_ClearMessage
symName : AX_Trace
symName : .AX_Release
symName : .AX_Init
symName : .AX_Print
symName : .AX_Init.func1
symName : .AX_Apply.func1

** Notice bad addresses in AX_INIT, and AX_PRINT because they were double processed and thought to be data the second time. Can cause a panic sometimes.

map[AX_Init:0x640029af090d8b48 AX_Print:0x640029aae90d8b48 AX_Message:0x7efcb073d7c0 AX_ClearMessage:0x7efcb073d820 AX_Trace:0x7efcb073d8a0 AX_Apply.func1:0x7efcb073d960 AX_Init.func1:0x7efcb073d8e0 AX_Apply.func2:0x7efcb073d9e0 AZ_ITEM:0x7efcb09dd920 AX_Release:0x7efcb073d050 AX_Apply:0x7efcb073d500]

What did you see instead?

syms : map[.AX_Init: .AX_Print: .AX_Init.func1: .AX_Apply.func1: .AX_Apply.func2: .AX_Release: .AX_Apply: .AX_Message: .AX_ClearMessage: .AX_Trace: AZ_ITEM:]
symslen : 11
symName : AZ_ITEM
symName : .AX_Apply
symName : .AX_Message
symName : .AX_ClearMessage
symName : .AX_Trace
symName : .AX_Apply.func2
symName : .AX_Release
symName : .AX_Init
symName : .AX_Print
symName : .AX_Init.func1
symName : .AX_Apply.func1

@slightnerd
Copy link
Author

Map delete and map add both cause processing problems with newly created symbol map

@slightnerd
Copy link
Author

Here is a simple fix I use until it can be refactored by development team.

symshold := make(map[string]interface{}, len(syms))

// Fill out the value of each plugin symbol.
for symName, sym := range syms {
	isFunc := symName[0] == '.'
	if isFunc {
		delete(syms, symName)
		symName = symName[1:]
	}  

	cname := C.CString(pluginpath + "." + symName)
	p := C.pluginLookup(h, cname, &cErr)
	C.free(unsafe.Pointer(cname))
	if p == nil {
		return nil, errors.New("plugin.Open: could not find symbol " + symName + ": " + C.GoString(cErr))
	}
	valp := (*[2]unsafe.Pointer)(unsafe.Pointer(&sym))
	if isFunc {
		(*valp)[1] = unsafe.Pointer(&p)
	} else {
		(*valp)[1] = p
	}
	symshold[symName] = sym
}
for symName, sym := range symshold {
	syms[symName] = sym
}

@tzneal
Copy link
Member

tzneal commented Apr 11, 2017

Dupe of #19269

@tzneal
Copy link
Member

tzneal commented Apr 17, 2017

Dupe, verified fixed in tip.

@tzneal tzneal closed this as completed Apr 17, 2017
@golang golang locked and limited conversation to collaborators Apr 17, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants