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: wrong value of exported variables in a DLL #4339

Closed
gopherbot opened this issue Nov 4, 2012 · 16 comments

Comments

@gopherbot
Copy link

commented Nov 4, 2012

by hwang.dev:

What steps will reproduce the problem?
1. Create a DLL with an exported variable(which has been properly initialized within the
DLL).e.g. (the code is in the attachment)
In "adll.h"
    typedef struct {
        char *name;
        void (*bar)();
    } T;
   __declspec(dllexport) const T exported_var;

In "adll.c"
const T exported_var = {"var", &bar_impl};

2. Write a go program to access the variable:
   fmt.Println(C.exported_var, C.GoString(C.exported_var.name))
   C.foo(&C.exported_var) // foo calls exported_var.bar


What is the expected output?
1. The correct value of C.exported_var can be obtained.
2. C.foo(&C.exported_var) calls exported_var.bar without a problem.

Or

An error message that the use case cannot be supported.

What do you see instead?
1. It just compiles without an error message.
2. During run, wrong values got.
3. C.foo(&C.exported_var) causes panic with message "runtime error: invalid
memory address or nil pointer dereference".

Which compiler are you using (5g, 6g, 8g, gccgo)?
6g

Which operating system are you using?
Windows 7 64 bit

Which version are you using?  (run 'go version')
go1.0.3
C compiler: Mingw-w64/MSYS/gcc 4.7.1

Please provide any additional information below.
I've found a workaround that a wrapper written in C will be able to get the correct
variable value. e.g.

/*
const T* getVar() {
    return &exported_var;
}
*/
import "C"

and then:
    fmt.Println(C.getVar(), C.GoString(C.getVar().name))

Attachments:

  1. dllvar.zip (1326 bytes)
@alexbrainman

This comment has been minimized.

Copy link
Member

commented Nov 5, 2012

Comment 1:

Tried to build as per your instructions, and it does not build:
C:\go\path\src\dllvar>BuildAll.bat
C:\go\path\src\dllvar>gcc -c adll.c -DEXPORT_DLL
C:\go\path\src\dllvar>gcc -shared -o adll.dll adll.o -Wl,--export-all-symbols
C:\go\path\src\dllvar>go build goapp.go
# command-line-arguments
goapp.go:21[C:\DOCUME~1\aa\LOCALS~1\Temp\go-build288956491\command-line-arguments\_obj\goapp.cgo1.go:21]:
cannot use &(*_Cvar_exported_var) (type *_Ctype_struct___0) as type *_Ctype_T in
function argument
My go version is:
hg id a9b2f3280559
What I see is different. Would you like to tell me how I can reproduce your error?
On the other hand, you have come up with solution to your problem. I would just use that
if I could.
Thank you.
Alex

Status changed to WaitingForReply.

@gopherbot

This comment has been minimized.

Copy link
Author

commented Nov 5, 2012

Comment 2 by hwang.dev:

I guess the compilation error you've encountered is due to different Go or gcc version
(and it might be another bug or misconfiguration), my env information is:
Windows 7 64 bit
Go version is 1.0.3 (64bit).
MinGW-w64, gcc 4.7.1 with C compiler only (installed with TDM-GCC web installer 
http://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%20Installer/tdm-gcc-webdl.exe/download).
No C++ compiler is installed.
The error occurs at this line (goapp.go):
C.foo(&C.exported_var)
I think by just commenting out this line, the line above it is able to illustrate this
issue too:
    fmt.Println(C.exported_var, C.GoString(C.exported_var.name))
    // C.foo(&C.exported_var)
Because fmt.Println(C.exported_var, C.GoString(C.exported_var.name)) will fail to print
any values.
@alexbrainman

This comment has been minimized.

Copy link
Member

commented Nov 7, 2012

Comment 3:

I have no time to look at it now. Hopefully soon. I hope, you can avoid this issue for
the time.
Alex

Labels changed: added os-windows.

Status changed to New.

@davecheney

This comment has been minimized.

Copy link
Contributor

commented Nov 18, 2012

Comment 4:

Labels changed: added priority-later, removed priority-triage.

Status changed to Accepted.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Dec 10, 2012

Comment 5:

Labels changed: added size-l.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Mar 12, 2013

Comment 6:

Labels changed: added go1.1maybe, removed go1.1.

@robpike

This comment has been minimized.

Copy link
Contributor

commented May 18, 2013

Comment 7:

Labels changed: added go1.2maybe, removed go1.1maybe.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Sep 10, 2013

Comment 8:

I can't reproduce this using ordinary "everything linked together" C.
So it looks like it has something to do with the DLL. 
I will submit CL 13653043 which adds a test of the non-DLL case.
I don't know what's wrong in the DLL case, though.
I don't believe this will make it into Go 1.2.

Labels changed: added go1.3maybe, removed go1.2maybe.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Sep 11, 2013

Comment 9:

This issue was updated by revision 71ed6eb.

R=golang-dev, minux.ma
CC=golang-dev
https://golang.org/cl/13653043
@rsc

This comment has been minimized.

Copy link
Contributor

commented Dec 4, 2013

Comment 10:

Labels changed: added release-none, removed go1.3maybe.

@rsc

This comment has been minimized.

Copy link
Contributor

commented Dec 4, 2013

Comment 11:

Labels changed: added repo-main.

@varialus

This comment has been minimized.

Copy link
Contributor

commented Apr 6, 2015

I think this is fixed in the current development branch. I was encountering this bug on Windows XP with Go 1.4.2 and my own DLL, but I built the master branch of Go today and I'm no longer getting the error. My build environment may be slightly different than the official Go build machines, so it's probably advisable to retest it yourself.

@minux

This comment has been minimized.

Copy link
Member

commented Apr 6, 2015

@alexbrainman

This comment has been minimized.

Copy link
Member

commented Apr 7, 2015

This is now works (most likely fixed by #4069). Here https://go-review.googlesource.com/8523 is the test for it.

Alex

alexbrainman added a commit that referenced this issue Apr 7, 2015
misc/cgo/testso: add test for fixed issue 4339
Update #4339.

Change-Id: Ic1a7535562b8b824ba166777725f7ba5b9623d77
Reviewed-on: https://go-review.googlesource.com/8523
Run-TryBot: Minux Ma <minux@golang.org>
Reviewed-by: Minux Ma <minux@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@mikioh

This comment has been minimized.

Copy link
Contributor

commented Apr 8, 2015

@mikioh mikioh reopened this Apr 8, 2015

@alexbrainman

This comment has been minimized.

Copy link
Member

commented Apr 9, 2015

https://go-review.googlesource.com/#/c/8523/ contained test for issue #4339, not the fix. Issue #4339 was fixed by a series of CLs that fix issue #4069. We also have issue #10360 to keep track of progress fixing broken test https://go-review.googlesource.com/#/c/8523/ on darwin and netbsd. So I think this issue is resolved.

Alex

@mikioh mikioh added this to the Go1.5 milestone Apr 9, 2015

@golang golang locked and limited conversation to collaborators Jun 24, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
8 participants
You can’t perform that action at this time.