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
x/sys/windows: wrong Sizeof result on struct windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION on ARCH 386 #41001
Comments
@gopherbot add OS-Windows |
My first guess would be an alignment difference. Can you print the C |
@ianlancetaylor You are right. It seems to be a size difference in Offset and sizes of
Offset and sizes of
Code
package main
// #include <windows.h>
//
// int SizeOfJob() {
// JOBOBJECT_EXTENDED_LIMIT_INFORMATION test;
// return sizeof(test);
// }
// int SizeOfBasicJob() {
// JOBOBJECT_EXTENDED_LIMIT_INFORMATION test;
// return sizeof(test.BasicLimitInformation);
// }
// int SizeOfBasicStructJob() {
// JOBOBJECT_BASIC_LIMIT_INFORMATION test;
// return sizeof(test);
// }
// int SizeOfBasicLimitInformation() { JOBOBJECT_EXTENDED_LIMIT_INFORMATION test; return sizeof(test.BasicLimitInformation); };
// int SizeOfIoInfo() { JOBOBJECT_EXTENDED_LIMIT_INFORMATION test; return sizeof(test.IoInfo); };
// int SizeOfProcessMemoryLimit() { JOBOBJECT_EXTENDED_LIMIT_INFORMATION test; return sizeof(test.ProcessMemoryLimit); };
// int SizeOfJobMemoryLimit() { JOBOBJECT_EXTENDED_LIMIT_INFORMATION test; return sizeof(test.JobMemoryLimit); };
// int SizeOfPeakProcessMemoryUsed() { JOBOBJECT_EXTENDED_LIMIT_INFORMATION test; return sizeof(test.PeakProcessMemoryUsed); };
// int SizeOfPeakJobMemoryUsed() { JOBOBJECT_EXTENDED_LIMIT_INFORMATION test; return sizeof(test.PeakJobMemoryUsed); };
//
// int OffsetOfBasicLimitInformation() { return offsetof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION, BasicLimitInformation); };
// int OffsetOfIoInfo() { return offsetof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION, IoInfo); };
// int OffsetOfProcessMemoryLimit() { return offsetof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION, ProcessMemoryLimit); };
// int OffsetOfJobMemoryLimit() { return offsetof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION, JobMemoryLimit); };
// int OffsetOfPeakProcessMemoryUsed() { return offsetof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION, PeakProcessMemoryUsed); };
// int OffsetOfPeakJobMemoryUsed() { return offsetof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION, PeakJobMemoryUsed); };
//
// int SizeOfPerProcessUserTimeLimit() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.PerProcessUserTimeLimit); }
// int SizeOfPerJobUserTimeLimit() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.PerJobUserTimeLimit); }
// int SizeOfLimitFlags() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.LimitFlags); }
// int SizeOfMinimumWorkingSetSize() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.MinimumWorkingSetSize); }
// int SizeOfMaximumWorkingSetSize() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.MaximumWorkingSetSize); }
// int SizeOfActiveProcessLimit() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.ActiveProcessLimit); }
// int SizeOfAffinity() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.Affinity); }
// int SizeOfPriorityClass() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.PriorityClass); }
// int SizeOfSchedulingClass() { JOBOBJECT_BASIC_LIMIT_INFORMATION test; return sizeof(test.SchedulingClass); }
//
// int OffsetOfPerProcessUserTimeLimit() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, PerProcessUserTimeLimit); }
// int OffsetOfPerJobUserTimeLimit() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, PerJobUserTimeLimit); }
// int OffsetOfLimitFlags() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, LimitFlags); }
// int OffsetOfMinimumWorkingSetSize() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, MinimumWorkingSetSize); }
// int OffsetOfMaximumWorkingSetSize() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, MaximumWorkingSetSize); }
// int OffsetOfActiveProcessLimit() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, ActiveProcessLimit); }
// int OffsetOfAffinity() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, Affinity); }
// int OffsetOfPriorityClass() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, PriorityClass); }
// int OffsetOfSchedulingClass() { return offsetof(JOBOBJECT_BASIC_LIMIT_INFORMATION, SchedulingClass); }
import "C"
import (
"fmt"
"unsafe"
"golang.org/x/sys/windows"
)
func main() {
info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{}
fmt.Printf("|Field | GO Offset | C Offset | GO Size | C Size|\n|-|-|-|-|-|\n")
fmt.Printf("|BasicLimitInformation | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation), C.OffsetOfBasicLimitInformation(), unsafe.Sizeof(info.BasicLimitInformation), C.SizeOfBasicLimitInformation())
fmt.Printf("|IoInfo | %d | %d | %d | %d|\n", unsafe.Offsetof(info.IoInfo), C.OffsetOfIoInfo(), unsafe.Sizeof(info.IoInfo), C.SizeOfIoInfo())
fmt.Printf("|ProcessMemoryLimit | %d | %d | %d | %d|\n", unsafe.Offsetof(info.ProcessMemoryLimit), C.OffsetOfProcessMemoryLimit(), unsafe.Sizeof(info.ProcessMemoryLimit), C.SizeOfProcessMemoryLimit())
fmt.Printf("|JobMemoryLimit | %d | %d | %d | %d|\n", unsafe.Offsetof(info.JobMemoryLimit), C.OffsetOfJobMemoryLimit(), unsafe.Sizeof(info.JobMemoryLimit), C.SizeOfJobMemoryLimit())
fmt.Printf("|PeakProcessMemoryUsed | %d | %d | %d | %d|\n", unsafe.Offsetof(info.PeakProcessMemoryUsed), C.OffsetOfPeakProcessMemoryUsed(), unsafe.Sizeof(info.PeakProcessMemoryUsed), C.SizeOfPeakProcessMemoryUsed())
fmt.Printf("|PeakJobMemoryUsed | %d | %d | %d | %d|\n", unsafe.Offsetof(info.PeakJobMemoryUsed), C.OffsetOfPeakJobMemoryUsed(), unsafe.Sizeof(info.PeakJobMemoryUsed), C.SizeOfPeakJobMemoryUsed())
fmt.Printf("\n")
fmt.Printf("|Field | GO Offset | C Offset | GO Size | C Size|\n|-|-|-|-|-|\n")
fmt.Printf("|PerProcessUserTimeLimit | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.PerProcessUserTimeLimit), C.OffsetOfPerProcessUserTimeLimit(), unsafe.Sizeof(info.BasicLimitInformation.PerProcessUserTimeLimit), C.SizeOfPerProcessUserTimeLimit())
fmt.Printf("|PerJobUserTimeLimit | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.PerJobUserTimeLimit), C.OffsetOfPerJobUserTimeLimit(), unsafe.Sizeof(info.BasicLimitInformation.PerJobUserTimeLimit), C.SizeOfPerJobUserTimeLimit())
fmt.Printf("|LimitFlags | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.LimitFlags), C.OffsetOfLimitFlags(), unsafe.Sizeof(info.BasicLimitInformation.LimitFlags), C.SizeOfLimitFlags())
fmt.Printf("|MinimumWorkingSetSize | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.MinimumWorkingSetSize), C.OffsetOfMinimumWorkingSetSize(), unsafe.Sizeof(info.BasicLimitInformation.MinimumWorkingSetSize), C.SizeOfMinimumWorkingSetSize())
fmt.Printf("|MaximumWorkingSetSize | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.MaximumWorkingSetSize), C.OffsetOfMaximumWorkingSetSize(), unsafe.Sizeof(info.BasicLimitInformation.MaximumWorkingSetSize), C.SizeOfMaximumWorkingSetSize())
fmt.Printf("|ActiveProcessLimit | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.ActiveProcessLimit), C.OffsetOfActiveProcessLimit(), unsafe.Sizeof(info.BasicLimitInformation.ActiveProcessLimit), C.SizeOfActiveProcessLimit())
fmt.Printf("|Affinity | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.Affinity), C.OffsetOfAffinity(), unsafe.Sizeof(info.BasicLimitInformation.Affinity), C.SizeOfAffinity())
fmt.Printf("|PriorityClass | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.PriorityClass), C.OffsetOfPriorityClass(), unsafe.Sizeof(info.BasicLimitInformation.PriorityClass), C.SizeOfPriorityClass())
fmt.Printf("|SchedulingClass | %d | %d | %d | %d|\n", unsafe.Offsetof(info.BasicLimitInformation.SchedulingClass), C.OffsetOfSchedulingClass(), unsafe.Sizeof(info.BasicLimitInformation.SchedulingClass), C.SizeOfSchedulingClass())
fmt.Printf("\n")
} |
Change https://golang.org/cl/251197 mentions this issue: |
@dbellavista Thanks! Looks like for Windows the alignment of Can you see whether https://golang.org/cl/251197 fixes the problem? Thanks. |
@ianlancetaylor thanks! The sizes are now equal |
Change https://golang.org/cl/253097 mentions this issue: |
Add test for CL 251197. Updates golang/go#41001 Change-Id: I6317678057eb8b18a1f7564842a92682c0c9930f Reviewed-on: https://go-review.googlesource.com/c/sys/+/253097 Run-TryBot: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Hi! I'm trying to call the
windows.SetInformationJobObject
function which requires the size of the input structure of typewindows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION
. To my understanding I can useunsafe.Sizeof
to achieve the same result of the Csizeof
operator.When compiling on amd64 arch, the sizeof is correct, but on 386 there is a 4 bytes difference.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
What did you expect to see?
Compiled on windows with environment
GOARCH=386
Compiled on windows with environment
GOARCH="amd64"
What did you see instead?
Compiled on windows with environment
GOARCH=386
The text was updated successfully, but these errors were encountered: