Skip to content

Incorrect generation of cgo_export.h file for CGo on 64-bit machines #5646

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

Closed
gopherbot opened this issue Jun 6, 2013 · 2 comments
Closed

Comments

@gopherbot
Copy link
Contributor

by TheBrokenToaster:

One of the changes from Go 1.0 to Go 1.1 was that the size of an "int" was now
dependent on the native architecture of the CPU. In Go 1.0, the size of the
"len" and "cap" fields in a GoSlice was always 32-bits. However, in
Go 1.1, those fields could be 32-bits or 64-bits depending on architecture.

Similarly, when using the GoSlice struct with CGo, the size of "len" and
"cap" fields should be architecture dependent. Currently, it uses the
"int" type, in which C language gives no guarantee that it is architecture
dependent.

The _cgo_export.h header is currently (INCORRECT):
    typedef struct { char *p; int n; } GoString;
    typedef struct { void *data; int len; int cap; } GoSlice;

Instead it should be (CORRECT):
    typedef struct { char *p; GoInt n; } GoString;
    typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;

Note: The GoString struct happens to work due to data structure alignment, but will
still suffer from a integer overflow if the string length was greater than 2^32.

----

What steps will reproduce the problem?
    1.) Download the attachment.
    2.) Compile and run demo.go on a 64-bit machine


What is the expected output?
    sizeof(GoSlice): 16
      sizeof(GoSlice.data): 8
      sizeof(GoSlice.len): 4
      sizeof(GoSlice.cap): 4
    sizeof(GoString): 16
      sizeof(GoString.p): 8
      sizeof(GoString.n): 4

    Print length of each GoSlice element
      Index 0: len=0, cap=0
      Index 1: len=417792, cap=194
      Hexdump: 00400500c2000000 0000000000000000 2823000000000000 00600600c2000000

    Print length of each GoString element
      Index 0: len=10
      Index 1: len=16
      Index 2: len=18
      Hexdump: 9050430000000000 0a00000000000000 105a430000000000 1000000000000000 d052430000000000 1200000000000000


What do you see instead?
    sizeof(GoSlice): 24
      sizeof(GoSlice.data): 8
      sizeof(GoSlice.len): 8
      sizeof(GoSlice.cap): 8
    sizeof(GoString): 16
      sizeof(GoString.p): 8
      sizeof(GoString.n): 8

    Print length of each GoSlice element
      Index 0: len=0, cap=9000
      Index 1: len=123, cap=456
      Hexdump: 00400500c2000000 0000000000000000 2823000000000000 00600600c2000000 7b00000000000000 c801000000000000

    Print length of each GoString element
      Index 0: len=10
      Index 1: len=16
      Index 2: len=18
      Hexdump: 9050430000000000 0a00000000000000 105a430000000000 1000000000000000 d052430000000000 1200000000000000


Which compiler are you using?
    6g


Which operating system are you using?
    Linux Mint 14 Nadia


Which version are you using?
    go version go1.1 linux/amd64

Attachments:

  1. cgo_bug.tar.gz (1253 bytes)
@gopherbot
Copy link
Contributor Author

Comment 1 by TheBrokenToaster:

Sorry, I switched the "what is the expected output" and "what do you see instead" fields
on accident.

@ianlancetaylor
Copy link
Contributor

Comment 2:

Status changed to Duplicate.

Merged into issue #5548.

@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
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

2 participants