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

cmd/cgo: msvc created dll can be linked with cgo but executable fails with "The procedure entry point AddVectoredExceptionHandler could not be located" #43244

Open
philippseith opened this issue Dec 17, 2020 · 6 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Milestone

Comments

@philippseith
Copy link

philippseith commented Dec 17, 2020

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

$ go version
go version go1.15.6 linux/amd64

Does this issue reproduce with the latest release?

Yes

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

go env Output
$ go env

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/philipp/.cache/go-build"
GOENV="/home/philipp/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/philipp/go/pkg/mod"
GONOPROXY=""
GOOS="linux"
GOPATH="/home/philipp/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build125405181=/tmp/go-build -gno-record-gcc-switches"

What did you do?

  • I build a 64bit dll which exports C and C++ symbols using Visual Studio. Sources used: http://www.mingw.org/wiki/sampledll
  • I linked it with cgo into a go executable GOARCH=amd64 GOOS=windows CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go build -o cgotest.exe main.go with this trival main.go
package main

/*
#cgo LDFLAGS: -L. -lsample

#include "sample.h"
*/
import (
	"C"
)

func main() {
	world := C.CString("World")
	C.hello(world)
	C.Double(2)
}
  • I put cgotest.exe together with the sample.dll on a Windows box and run it.

What did you expect to see?

Hello World

What did you see instead?

A messagebox containing this text:

---------------------------
cgotest.exe - Entry Point Not Found
---------------------------
The procedure entry point AddVectoredExceptionHandler could not be located in the dynamic link library D:\tmp\cgotest.exe. 
---------------------------
OK   
---------------------------
@philippseith
Copy link
Author

philippseith commented Dec 18, 2020

The error occurs when both sample.dll and sample.lib during build time are placed in the directory used as library path (-L). This seems to cause an invalid import section in the generated PE file.

c:\>dumpbin /IMPORTS cgotest.exe
Microsoft (R) COFF/PE Dumper Version 14.28.29335.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file cgotest.exe

File Type: EXECUTABLE IMAGE

  Section contains the following imports:

    Sample.dll
                506310 Import Address Table
                506070 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           8 hello
                           7 Double
                          14 AddVectoredExceptionHandler
                          8D CloseHandle
                          C5 CreateEventA
                          FC CreateThread
                         11B DeleteCriticalSection
                         139 DuplicateHandle
                         13F EnterCriticalSection
                         16E ExitProcess
                         1BA FreeEnvironmentStringsW
                         20D GetConsoleMode
                         228 GetCurrentProcess
                         229 GetCurrentProcessId
                         22D GetCurrentThreadId
                         24B GetEnvironmentStringsW
                         276 GetLastError
                         2C6 GetProcAddress
                         2C7 GetProcessAffinityMask
                         2E2 GetQueuedCompletionStatus
                         2E7 GetStartupInfoA
                         2EA GetStdHandle
                         2F7 GetSystemDirectoryA
                         2FB GetSystemInfo
                         301 GetSystemTimeAsFileTime
                         31F GetTickCount
                         37C InitializeCriticalSection
                         3D8 LeaveCriticalSection
                         3DC LoadLibraryA
                         3DF LoadLibraryW
                         46B QueryPerformanceCounter
                         4C6 RtlAddFunctionTable
                         4C7 RtlCaptureContext
                         4CE RtlLookupFunctionEntry
                         4D5 RtlVirtualUnwind
                         4ED SetConsoleCtrlHandler
                         519 SetErrorMode
                         51A SetEvent
                         548 SetProcessPriorityBoost
                         572 SetUnhandledExceptionFilter
                         57B SetWaitableTimer
                         582 Sleep
                         58C SwitchToThread
                         591 TerminateProcess
                         5A5 TlsGetValue
                         5B3 UnhandledExceptionFilter
                         5CE VirtualAlloc
                         5D1 VirtualFree
                         5D4 VirtualProtect
                         5D6 VirtualQuery
                         5DD WaitForMultipleObjects
                         5DF WaitForSingleObject
                         621 WriteConsoleW
                         622 WriteFile
                         633 __C_specific_handler

    KERNEL32.dll
                506320 Import Address Table
                506080 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                          14 AddVectoredExceptionHandler
                          8D CloseHandle
                          C5 CreateEventA
                          FC CreateThread
                         11B DeleteCriticalSection
                         139 DuplicateHandle
                         13F EnterCriticalSection
                         16E ExitProcess
                         1BA FreeEnvironmentStringsW
                         20D GetConsoleMode
                         228 GetCurrentProcess
                         229 GetCurrentProcessId
                         22D GetCurrentThreadId
                         24B GetEnvironmentStringsW
                         276 GetLastError
                         2C6 GetProcAddress
                         2C7 GetProcessAffinityMask
                         2E2 GetQueuedCompletionStatus
                         2E7 GetStartupInfoA
                         2EA GetStdHandle
                         2F7 GetSystemDirectoryA
                         2FB GetSystemInfo
                         301 GetSystemTimeAsFileTime
                         31F GetTickCount
                         37C InitializeCriticalSection
                         3D8 LeaveCriticalSection
                         3DC LoadLibraryA
                         3DF LoadLibraryW
                         46B QueryPerformanceCounter
                         4C6 RtlAddFunctionTable
                         4C7 RtlCaptureContext
                         4CE RtlLookupFunctionEntry
                         4D5 RtlVirtualUnwind
                         4ED SetConsoleCtrlHandler
                         519 SetErrorMode
                         51A SetEvent
                         548 SetProcessPriorityBoost
                         572 SetUnhandledExceptionFilter
                         57B SetWaitableTimer
                         582 Sleep
                         58C SwitchToThread
                         591 TerminateProcess
                         5A5 TlsGetValue
                         5B3 UnhandledExceptionFilter
                         5CE VirtualAlloc
                         5D1 VirtualFree
                         5D4 VirtualProtect
                         5D6 VirtualQuery
                         5DD WaitForMultipleObjects
                         5DF WaitForSingleObject
                         621 WriteConsoleW
                         622 WriteFile
                         633 __C_specific_handler

    msvcrt.dll
                5064D0 Import Address Table
                506230 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                          52 __getmainargs
                          53 __initenv
                          54 __iob_func
                          5B __lconv_init
                          61 __set_app_type
                          63 __setusermatherr
                          72 _acmdln
                          79 _amsg_exit
                          86 _beginthread
                          8B _cexit
                          BE _errno
                          DD _fmode
                         11E _initterm
                         22A _onexit
                         386 abort
                         397 calloc
                         3A4 exit
                         3B7 fprintf
                         3BE free
                         3CA fwrite
                         3F8 malloc
                         400 memcpy
                         41E signal
                         433 strlen
                         436 strncmp
                         455 vfprintf

  Summary

        1000 .CRT
       22000 .bss
        3000 .data
        4000 .debug_abbrev
        1000 .debug_aranges
        D000 .debug_frame
        1000 .debug_gdb_scripts
       92000 .debug_info
       20000 .debug_line
       59000 .debug_loc
        3000 .debug_pubnames
        A000 .debug_pubtypes
       1B000 .debug_ranges
        1000 .debug_str
        1000 .idata
        1000 .pdata
       7C000 .rdata
       62000 .text
        1000 .tls
        1000 .xdata

As one can see, the symbols of kernel32 appear twice, and falsely in the import section of the sample.dll

@philippseith philippseith changed the title msvc created dll with c++ exports can be linked with cgo but executable fails with "The procedure entry point AddVectoredExceptionHandler could not be located" msvc created dll can be linked with cgo but executable fails with "The procedure entry point AddVectoredExceptionHandler could not be located" Dec 18, 2020
@cagedmantis cagedmantis changed the title msvc created dll can be linked with cgo but executable fails with "The procedure entry point AddVectoredExceptionHandler could not be located" cmd/cgo: msvc created dll can be linked with cgo but executable fails with "The procedure entry point AddVectoredExceptionHandler could not be located" Dec 22, 2020
@networkimprov
Copy link

Note that 1.13 is no longer supported.

cc @alexbrainman

@gopherbot add OS-Windows

@cagedmantis
Copy link
Contributor

@philippseith Can you reproduce this issue in a supported version of Go? Either 1.14 or 1.15?

@cagedmantis cagedmantis added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Dec 22, 2020
@philippseith
Copy link
Author

philippseith commented Dec 23, 2020

I reproduced it with go version go1.15.6 linux/amd64

@networkimprov
Copy link

@gopherbot remove WaitingForInfo

@gopherbot gopherbot removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Dec 23, 2020
@dmitshur dmitshur added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Dec 29, 2020
@dmitshur dmitshur added this to the Backlog milestone Dec 29, 2020
@triphocy
Copy link

Note that I ran into this issue as well, and have some addiitonal notes.

First, I do not see the issue with binutils 2.36.1. I can link against a DLL import library and the resulting binary has proper imports. I do see this issue cross compiling on an Ubuntu 20.04 system with MinGW binutils 2.34 when linking against a DLL import library.

Basically, if I have a third party library MyLibrary.DLL with an import library MyLibrary.LIB, then, if I link with #cgo -lMyLibrary, for some reason, the KERNEL32.DLL symbols get added to the "MyLibrary.DLL" imports.

However, ld on cygwin/mingw allows you to link directly against the DLL (for reference, see this link). If I replace the MyLibrary.LIB file in the library search path with MyLibrary.DLL, then linking with #cgo -lMyLibrary links directly against MyLibrary.DLL, and the resulting imports look correct.

This may not be a Go issue, since I have tried this on Go 1.13, Go 1.15, and now Go 1.19, with the same results.

For reference, here is a snippet from dumpbin when I link against an import library (mingw ld 2.34):

    dwf.dll
                B643B8 Import Address Table
                B64070 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                         10A FDwfDeviceOpen
                         106 FDwfDeviceClose
                          71 FDwfAnalogInFrequencySet
                          57 FDwfAnalogInBufferSizeSet
                          53 FDwfAnalogInAcquisitionModeSet
                          61 FDwfAnalogInChannelEnableSet
                          6C FDwfAnalogInChannelRangeSet
                          69 FDwfAnalogInChannelOffsetSet
                          64 FDwfAnalogInChannelFilterSet
                          77 FDwfAnalogInReset
                          6E FDwfAnalogInConfigure
                          7E FDwfAnalogInStatus
                          80 FDwfAnalogInStatusData
                          76 FDwfAnalogInRecordLengthSet
                          86 FDwfAnalogInStatusRecord
                          14 AddVectoredExceptionHandler
                          8D CloseHandle
                          C5 CreateEventA
                          CC CreateFileA
                          D9 CreateIoCompletionPort
                          FC CreateThread
                         10A CreateWaitableTimerExW
                         11B DeleteCriticalSection
                         139 DuplicateHandle
                         13F EnterCriticalSection
                         16E ExitProcess
                         1BA FreeEnvironmentStringsW
                         20D GetConsoleMode
                         228 GetCurrentProcess
                         229 GetCurrentProcessId
                         22D GetCurrentThreadId
                         24B GetEnvironmentStringsW
                         276 GetLastError
                         2C6 GetProcAddress
                         2C7 GetProcessAffinityMask
                         2E3 GetQueuedCompletionStatusEx
                         2E7 GetStartupInfoA
                         2EA GetStdHandle
                         2F7 GetSystemDirectoryA
                         2FB GetSystemInfo
                         301 GetSystemTimeAsFileTime
                         30F GetThreadContext
                         31F GetTickCount
                         37C InitializeCriticalSection
                         3D8 LeaveCriticalSection
                         3DC LoadLibraryA
                         3DF LoadLibraryW
                         441 PostQueuedCompletionStatus
                         46B QueryPerformanceCounter
                         4C5 ResumeThread
                         4C6 RtlAddFunctionTable
                         4C7 RtlCaptureContext
                         4CE RtlLookupFunctionEntry
                         4D5 RtlVirtualUnwind
                         4ED SetConsoleCtrlHandler
                         519 SetErrorMode
                         51A SetEvent
                         548 SetProcessPriorityBoost
                         558 SetThreadContext
                         572 SetUnhandledExceptionFilter
                         57B SetWaitableTimer
                         582 Sleep
                         58A SuspendThread
                         58C SwitchToThread
                         591 TerminateProcess
                         5A5 TlsGetValue
                         5B3 UnhandledExceptionFilter
                         5CE VirtualAlloc
                         5D1 VirtualFree
                         5D4 VirtualProtect
                         5D6 VirtualQuery
                         5DD WaitForMultipleObjects
                         5DF WaitForSingleObject
                         621 WriteConsoleW
                         622 WriteFile
                         633 __C_specific_handler

Notice all KERNEL32.DLL symbols like CreateWaitableTimerExW that are incorrectly associated with dwf.dll.

And this is what it looks like when I link directly against the DLL (mingw ld 2.34):

    dwf.dll
                B64660 Import Address Table
                B64318 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                          53 FDwfAnalogInAcquisitionModeSet
                          57 FDwfAnalogInBufferSizeSet
                          61 FDwfAnalogInChannelEnableSet
                          64 FDwfAnalogInChannelFilterSet
                          69 FDwfAnalogInChannelOffsetSet
                          6C FDwfAnalogInChannelRangeSet
                          6E FDwfAnalogInConfigure
                          71 FDwfAnalogInFrequencySet
                          76 FDwfAnalogInRecordLengthSet
                          77 FDwfAnalogInReset
                          7E FDwfAnalogInStatus
                          80 FDwfAnalogInStatusData
                          86 FDwfAnalogInStatusRecord
                         106 FDwfDeviceClose
                         10A FDwfDeviceOpen

Here is the equivalent dump when linked with the importlib on mingw ld 2.36.1:

    dwf.dll
             1407635B0 Import Address Table
             1407632C0 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                          53 FDwfAnalogInAcquisitionModeSet
                          57 FDwfAnalogInBufferSizeSet
                          61 FDwfAnalogInChannelEnableSet
                          64 FDwfAnalogInChannelFilterSet
                          69 FDwfAnalogInChannelOffsetSet
                          6C FDwfAnalogInChannelRangeSet
                          6E FDwfAnalogInConfigure
                          71 FDwfAnalogInFrequencySet
                          76 FDwfAnalogInRecordLengthSet
                          77 FDwfAnalogInReset
                          7E FDwfAnalogInStatus
                          80 FDwfAnalogInStatusData
                          86 FDwfAnalogInStatusRecord
                         106 FDwfDeviceClose
                         10A FDwfDeviceOpen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Windows
Projects
None yet
Development

No branches or pull requests

6 participants