Closed
Description
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:
- cgo_bug.tar.gz (1253 bytes)