-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: 'packed' does not mean packed in some gcc #6149
Labels
Milestone
Comments
It works fine here on windows-386. I use C:\>gcc --version gcc (tdm-1) 4.5.2 Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Perhaps there is a confusion between Go and gcc about the size of C.int. I am not cgo expert, but I would use "go -x -work ..." command to examine intermediate files to see where the problem is. I would look for C Test function prototype generated by Go to decide if it is right or wrong. Alex |
Here is a more glfw3 like presentation: foolib.c ======== #include "_cgo_export.h" void cFoobar() { goFoobar(1,2,3); } foolib.go ========= package foolib //#cgo CFLAGS: -malign-double //void cFoobar(); import "C" import "fmt" //export goFoobar func goFoobar(val C.int, val2 C.double, val3 C.double) { fmt.Println(float64(val), float64(val2), float64(val3)) } func Foobar() { C.cFoobar() } runme.go ======== package main import "foolib" func main() { foolib.Foobar() } Command for running =================== go run path\to\runme.go Output ====== 1 9.80967354e-315 5.304989477e-315 |
I have attached all the source/build/log files, what is your gcc version? Attachments:
|
Thank you for attaching that file full of intermediate objects. Here is the C Test function: void Test(int p0, double p1, double p2) { struct { int p0; double p1; double p2; } __attribute__((packed)) a; a.p0 = p0; a.p1 = p1; a.p2 = p2; crosscall2(_cgoexp_aff9d600cead_Test, &a, 20); } and here is its disassembly: 0x00002060 <Test+0>: sub $0x3c,%esp 0x00002063 <Test+3>: mov 0x40(%esp),%eax 0x00002067 <Test+7>: mov %eax,0x18(%esp) 0x0000206b <Test+11>: fldl 0x44(%esp) 0x0000206f <Test+15>: fstpl 0x20(%esp) 0x00002073 <Test+19>: fldl 0x4c(%esp) 0x00002077 <Test+23>: fstpl 0x28(%esp) 0x0000207b <Test+27>: movl $0x14,0x8(%esp) 0x00002083 <Test+35>: lea 0x18(%esp),%eax 0x00002087 <Test+39>: mov %eax,0x4(%esp) 0x0000208b <Test+43>: movl $0x0,(%esp) 0x00002092 <Test+50>: call 0x2097 <Test+55> 0x00002097 <Test+55>: add $0x3c,%esp 0x0000209a <Test+58>: ret 0x0000209b <Test+59>: ret The "__attribute__((packed))" is supposed to mean there is no padding between struct field elements, no matter what, and yet the code is storing the 4-byte int at 0x18(%esp) but the first double at 0x20(%esp). The 4-byte gap at 0x1c(%esp) is not supposed to be there, yet it is. This is why Go cannot read the arguments correctly. The best solution would be to get a better, less buggy copy of gcc. But that might be difficult, since we don't know which versions have the problem or even if it is an admitted problem. Another solution might be to change cgo to stop using packed structs. It could instead declare a struct with the arguments as scratch space and a buffer of the right size and then memmove from the scratch space into the buffer. Still Go1.2Maybe, but not sure it will happen. |
Looks like another instance of issue #5603, which is fixed on tip. We should have put the patch into 1.1.2, but we missed it. Sorry about that. Status changed to Duplicate. Merged into issue #5603. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
by Vova616:
The text was updated successfully, but these errors were encountered: