Skip to content

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

Closed
@gopherbot

Description

@gopherbot

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)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions