Conversation
WalkthroughThe update refactors CPU information retrieval on Windows by removing platform-specific Go implementations and introducing a unified C-based helper ( Changes
Sequence Diagram(s)sequenceDiagram
participant GoCode as Go CPU Info Collector
participant CHelper as C Helper (cpu_windows.c)
participant WinAPI as Windows API
participant Registry as Windows Registry
GoCode->>CHelper: computeCoresAndProcessors(&CPU_INFO)
CHelper->>WinAPI: GetLogicalProcessorInformationEx
CHelper-->>GoCode: CPU_INFO struct (cores, caches, etc.)
GoCode->>Registry: Query CPU MHz, Model, Vendor, Family
Registry-->>GoCode: Registry values
GoCode->>WinAPI: GetSystemInfo
WinAPI-->>GoCode: System info (model, stepping)
GoCode-->>GoCode: Assemble Info struct
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (1.64.8)Error: build linters: plugin(pkgconfigusage): plugin "pkgconfigusage" not found ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (5)
pkg/gohai/cpu/cpu_windows.h (1)
8-20: Consider adding documentation and checking data types.The
CPU_INFOstruct definition looks correct, but consider these improvements:
- Add brief documentation comments for each field to clarify their purpose
- Verify that
unsigned long longis appropriate for cache sizes - while it can handle large values, consider ifDWORD64orSIZE_Twould be more appropriate for Windows API consistency// CPU_INFO mirrors the Go struct typedef struct { + int corecount; // Number of physical CPU cores + int logicalcount; // Number of logical processors (including hyperthreading) + int pkgcount; // Number of physical CPU packages/sockets + int numaNodeCount; // Number of NUMA nodes + int relationGroups; // Number of processor groups + int maxProcsInGroups; // Maximum processors across all groups + int activeProcsInGroups; // Active processors across all groups + unsigned long long l1CacheSize; // Total L1 cache size in bytes + unsigned long long l2CacheSize; // Total L2 cache size in bytes + unsigned long long l3CacheSize; // Total L3 cache size in bytes } CPU_INFO;pkg/gohai/cpu/cpu_test.go (2)
13-13: Consider using testing.T.Log instead of log.Infof.Using
log.Infofin tests may not be the best approach as it depends on the global logger configuration and may not appear in test output.Consider using
t.Logffor test-specific logging:- "github.com/DataDog/datadog-agent/pkg/util/log"And replace the log statements with
t.Logfcalls.
69-84: Improve test logging approach.While the logging provides useful debugging information, consider these improvements:
- Use
t.Logfinstead oflog.Infoffor better integration with test output- Consider consolidating the logging or making it conditional (e.g., only when a verbose flag is set)
- // output CPUCores, CPULogicalProcessors, Family, Mhz, Model, ModelName, Stepping, VendorID, CacheSizeKB, CacheSizeL1Bytes, CacheSizeL2Bytes, CacheSizeL3Bytes, CPUNumaNodes, CPUPkgs - log.Infof("CPUCores: %s", decodedCPU.CPUCores) - log.Infof("CPULogicalProcessors: %s", decodedCPU.CPULogicalProcessors) - log.Infof("Family: %s", decodedCPU.Family) - log.Infof("Mhz: %s", decodedCPU.Mhz) - log.Infof("Model: %s", decodedCPU.Model) - log.Infof("ModelName: %s", decodedCPU.ModelName) - log.Infof("Stepping: %s", decodedCPU.Stepping) - log.Infof("VendorID: %s", decodedCPU.VendorID) - log.Infof("CacheSizeKB: %s", decodedCPU.CacheSizeKB) - log.Infof("CacheSizeL1Bytes: %s", decodedCPU.CacheSizeL1Bytes) - log.Infof("CacheSizeL2Bytes: %s", decodedCPU.CacheSizeL2Bytes) - log.Infof("CacheSizeL3Bytes: %s", decodedCPU.CacheSizeL3Bytes) - log.Infof("CPUNumaNodes: %s", decodedCPU.CPUNumaNodes) - log.Infof("CPUPkgs: %s", decodedCPU.CPUPkgs) + // Log CPU info for debugging + t.Logf("CPU Info - Cores: %s, LogicalProcs: %s, Family: %s, MHz: %s, Model: %s, ModelName: %s, Stepping: %s, VendorID: %s", + decodedCPU.CPUCores, decodedCPU.CPULogicalProcessors, decodedCPU.Family, decodedCPU.Mhz, + decodedCPU.Model, decodedCPU.ModelName, decodedCPU.Stepping, decodedCPU.VendorID) + t.Logf("Cache Info - KB: %s, L1: %s, L2: %s, L3: %s, NUMA: %s, Pkgs: %s", + decodedCPU.CacheSizeKB, decodedCPU.CacheSizeL1Bytes, decodedCPU.CacheSizeL2Bytes, + decodedCPU.CacheSizeL3Bytes, decodedCPU.CPUNumaNodes, decodedCPU.CPUPkgs)pkg/gohai/cpu/cpu_windows.go (2)
49-67: Consider consistent field naming in the cpuInfo struct.The struct has a mix of exported (uppercase) and unexported (lowercase) fields. Since all fields appear to be used internally within the package, consider making the naming convention consistent by either exporting all fields or keeping them all unexported.
69-76: Improve the regex pattern for more robust extraction.The current regex pattern has a few limitations:
- Uses
[0-9]*which matches zero or more digits (should be[0-9]+for one or more)- Requires a trailing space which might not always be present
- Could match anywhere in the string without anchoring
Consider this improved implementation:
func extract(caption, field string) string { - re := regexp.MustCompile(fmt.Sprintf("%s [0-9]* ", field)) + re := regexp.MustCompile(fmt.Sprintf(`\b%s\s+([0-9]+)\b`, field)) matches := re.FindStringSubmatch(caption) - if len(matches) > 0 { - return strings.Split(matches[0], " ")[1] + if len(matches) > 1 { + return matches[1] } return "" }This uses word boundaries (
\b), captures the numeric value directly, and ensures at least one digit is present.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
pkg/gohai/cpu/cpu_test.go(2 hunks)pkg/gohai/cpu/cpu_windows.c(1 hunks)pkg/gohai/cpu/cpu_windows.go(2 hunks)pkg/gohai/cpu/cpu_windows.h(1 hunks)pkg/gohai/cpu/cpu_windows_386.go(0 hunks)pkg/gohai/cpu/cpu_windows_amd64.go(0 hunks)releasenotes/notes/windows-agent-cpu-info-18e54faf1ffbd15a.yaml(1 hunks)
💤 Files with no reviewable changes (2)
- pkg/gohai/cpu/cpu_windows_386.go
- pkg/gohai/cpu/cpu_windows_amd64.go
🧰 Additional context used
🧬 Code Graph Analysis (2)
pkg/gohai/cpu/cpu_test.go (1)
pkg/util/log/log.go (1)
Infof(844-846)
pkg/gohai/cpu/cpu_windows.c (1)
pkg/gohai/cpu/cpu_windows.h (1)
computeCoresAndProcessors(23-23)
🔇 Additional comments (9)
pkg/gohai/cpu/cpu_windows.h (1)
22-23: Function signature looks correct.The function declaration is appropriate for its intended use - taking a pointer to the struct to populate it and returning an int for error codes.
releasenotes/notes/windows-agent-cpu-info-18e54faf1ffbd15a.yaml (1)
9-12: Release note accurately describes the fix.The release note correctly identifies the issue being fixed (inaccurate cpu_cores reporting by gohai) and references the appropriate JIRA ticket. The format follows the expected reStructuredText structure.
pkg/gohai/cpu/cpu_windows.c (7)
5-8: Include statements look appropriate.The necessary headers are included for Windows API functions and standard C library functions.
17-18: Good practice: Zero-initialize the struct.Using
memsetto zero-initialize the struct ensures clean data accumulation and prevents undefined behavior from uninitialized fields.
20-24: Correct API usage for buffer size determination.The two-step approach (first call to get buffer size, then allocate and call again) follows the standard Windows API pattern for variable-length data structures.
61-73: Cache size accumulation logic is correct.The switch statement correctly handles different cache levels and accumulates their sizes. This approach properly sums cache sizes across all processor cores.
31-34: Good error handling and cleanup.The function properly cleans up allocated memory on API failure and returns the appropriate error code.
91-92: Proper cleanup and success return.Memory is freed and the function returns 0 to indicate success, following good C programming practices.
42-55:Details
✅ Verification successful
Verify logical processor counting logic.
The bit manipulation logic for counting logical processors appears correct, but there's a potential issue with the GROUP_AFFINITY structure access pattern.
Let me verify the Windows API documentation for the correct way to iterate through processor groups and count logical processors:
🌐 Web query:
Windows API GetLogicalProcessorInformationEx SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX RelationProcessorCore structure layout and GROUP_AFFINITY usage💡 Result:
The GetLogicalProcessorInformationEx function is a Windows API that retrieves detailed information about logical processors and their relationships in a system. When used with RelationProcessorCore, it provides specific information about processor cores, including their efficiency classes on hybrid CPU architectures.
Function Overview
GetLogicalProcessorInformationEx has the following syntax:
BOOL GetLogicalProcessorInformationEx( [in] LOGICAL_PROCESSOR_RELATIONSHIP RelationshipType, [out, optional] PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX Buffer, [in, out] PDWORD ReturnedLength );The function returns TRUE if successful and writes at least one SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX structure to the output buffer[1]. This function is particularly useful for systems with more than 64 logical processors, as it's group-aware, unlike its predecessor GetLogicalProcessorInformation[2].
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX Structure
When RelationProcessorCore is specified as the RelationshipType parameter, the function returns information about processor cores. The structure is defined as:
typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX { LOGICAL_PROCESSOR_RELATIONSHIP Relationship; DWORD Size; union { PROCESSOR_RELATIONSHIP Processor; NUMA_NODE_RELATIONSHIP NumaNode; CACHE_RELATIONSHIP Cache; GROUP_RELATIONSHIP Group; } DUMMYUNIONNAME; } SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX;For RelationProcessorCore, the Processor field in the union contains valid data[10]. This PROCESSOR_RELATIONSHIP structure includes important information such as:
- The efficiency class of the processor core (on hybrid CPUs)
- Group affinity information
PROCESSOR_RELATIONSHIP and Efficiency Class
On hybrid CPU architectures (like Intel's performance hybrid architecture), the PROCESSOR_RELATIONSHIP structure includes an EfficiencyClass field that indicates the power-to-performance ratio of a logical processor[6].
- Higher EfficiencyClass values indicate higher performance but lower power efficiency
- Lower EfficiencyClass values indicate lower performance but higher power efficiency
This value is particularly useful for task scheduling based on performance or power requirements. For example, you might assign background tasks to cores with a lower efficiency class value and foreground tasks to cores with a higher efficiency class value[6].
GROUP_AFFINITY Usage
The GROUP_AFFINITY structure is a critical component when working with the GetLogicalProcessorInformationEx function, especially for systems with more than 64 logical processors. It contains:
typedef struct _GROUP_AFFINITY { KAFFINITY Mask; WORD Group; WORD Reserved[3]; } GROUP_AFFINITY, *PGROUP_AFFINITY;The structure has the following important members:
- Mask: A KAFFINITY value that serves as a 64-bit bitmask identifying processors within a group[7].
- Group: Specifies the processor group number[7].
- Reserved: Three WORD values reserved for future use (must be set to zero)[7].
When the RelationProcessorCore is specified, the PROCESSOR_RELATIONSHIP structure contains a groupMask array of GROUP_AFFINITY structures[6][8]. For processor cores, the groupCount is typically 1, meaning there's usually just one GROUP_AFFINITY structure per processor core[8].
Example Usage
In practical usage, you would typically:
- First call the function with a NULL buffer to get the required size
- Allocate memory for the buffer
- Call the function again to retrieve the information
- Process the returned structures based on their Relationship type
For example, when processing RelationProcessorCore relationships:
// For cores if (info.relationship == LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore) { PROCESSOR_RELATIONSHIP core = ((PROCESSOR_RELATIONSHIP) info); // For Core, groupCount is always 1 GROUP_AFFINITY groupAffinity = core.groupMask[0]; // On Windows 10 or later, you can access efficiency class int efficiencyClass = core.EfficiencyClass; }This pattern is demonstrated in various implementations, such as in the OSHI library[8] and the sysinfo Rust crate[9], which use this function to gather processor information.
Citations:
- 1: https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformationex
- 2: https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation
- 3: https://github.com/DataDog/gohai/blob/master/cpu/cpu_windows.go
- 4: https://mails.dpdk.org/archives/dev/2020-June/169480.html
- 5: https://cdrdv2-public.intel.com/685865/211112_Hybrid_WP_2_Developing_v1.2.pdf
- 6: https://www.intel.com/content/www/us/en/developer/articles/guide/12th-gen-intel-core-processor-gamedev-guide.html
- 7: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/minitape/ns-minitape-_group_affinity
- 8: https://www.oshi.ooo/xref/oshi/driver/windows/LogicalProcessorInformation.html
- 9: https://docs.rs/sysinfo/latest/i686-pc-windows-msvc/src/sysinfo/windows/cpu.rs.html
- 10: https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-system_logical_processor_information_ex
No issues found in logical processor counting logic
The implementation correctly iterates over
Processor.GroupCountand uses eachGROUP_AFFINITY.Maskto count set bits, matching the Windows API’sSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EXsemantics. Handling multiple groups ensures support for systems with over 64 logical processors, while on most machinesGroupCountwill be 1.
| // This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
| // Copyright 2014-present Datadog, Inc. | ||
|
|
||
| //go:build test |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Reconsider the build constraint.
The //go:build test constraint restricts this test file to only compile when the test build tag is specified. This is unusual for test files, which typically compile during normal go test execution without special build tags.
Unless there's a specific reason for this constraint, remove it to allow normal test execution:
-//go:build test
-📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| //go:build test |
🤖 Prompt for AI Agents
In pkg/gohai/cpu/cpu_test.go at line 5, the build constraint `//go:build test`
limits the test file to compile only with the `test` build tag, which is not
standard for Go test files. Remove this build constraint line entirely to allow
the test file to compile and run normally with the standard `go test` command.
| buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(buflen); | ||
| if (buffer == NULL) { | ||
| return ERROR_OUTOFMEMORY; | ||
| } |
There was a problem hiding this comment.
Add missing memory allocation header.
The code uses malloc but doesn't include <stdlib.h>. This could cause compilation warnings or errors.
#include "cpu_windows.h"
#include <windows.h>
#include <stdio.h>
+#include <stdlib.h>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(buflen); | |
| if (buffer == NULL) { | |
| return ERROR_OUTOFMEMORY; | |
| } | |
| #include "cpu_windows.h" | |
| #include <windows.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> |
🤖 Prompt for AI Agents
In pkg/gohai/cpu/cpu_windows.c around lines 26 to 29, the code uses malloc for
memory allocation but does not include the <stdlib.h> header, which is required
for malloc declaration. Add #include <stdlib.h> at the top of the file to ensure
proper declaration and avoid compilation warnings or errors.
| case RelationGroup: | ||
| cpuInfo->relationGroups = ptr->Group.MaximumGroupCount; | ||
| for (WORD i = 0; i < ptr->Group.ActiveGroupCount; i++) { | ||
| cpuInfo->maxProcsInGroups += ptr->Group.GroupInfo[i].MaximumProcessorCount; | ||
| cpuInfo->activeProcsInGroups += ptr->Group.GroupInfo[i].ActiveProcessorCount; | ||
| } | ||
| break; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Potential issue with group information handling.
The logic assumes there's only one RelationGroup entry, but the loop overwrites relationGroups and continues accumulating maxProcsInGroups and activeProcsInGroups. This could lead to incorrect values if multiple group entries exist.
case RelationGroup:
- cpuInfo->relationGroups = ptr->Group.MaximumGroupCount;
+ cpuInfo->relationGroups += ptr->Group.MaximumGroupCount;
for (WORD i = 0; i < ptr->Group.ActiveGroupCount; i++) {
cpuInfo->maxProcsInGroups += ptr->Group.GroupInfo[i].MaximumProcessorCount;
cpuInfo->activeProcsInGroups += ptr->Group.GroupInfo[i].ActiveProcessorCount;
}
break;Or consider whether relationGroups should store the total count or just the maximum group count from the last entry, based on the intended semantics.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| case RelationGroup: | |
| cpuInfo->relationGroups = ptr->Group.MaximumGroupCount; | |
| for (WORD i = 0; i < ptr->Group.ActiveGroupCount; i++) { | |
| cpuInfo->maxProcsInGroups += ptr->Group.GroupInfo[i].MaximumProcessorCount; | |
| cpuInfo->activeProcsInGroups += ptr->Group.GroupInfo[i].ActiveProcessorCount; | |
| } | |
| break; | |
| case RelationGroup: | |
| cpuInfo->relationGroups += ptr->Group.MaximumGroupCount; | |
| for (WORD i = 0; i < ptr->Group.ActiveGroupCount; i++) { | |
| cpuInfo->maxProcsInGroups += ptr->Group.GroupInfo[i].MaximumProcessorCount; | |
| cpuInfo->activeProcsInGroups += ptr->Group.GroupInfo[i].ActiveProcessorCount; | |
| } | |
| break; |
🤖 Prompt for AI Agents
In pkg/gohai/cpu/cpu_windows.c around lines 79 to 85, the code assumes a single
RelationGroup entry but may process multiple, causing relationGroups to be
overwritten and maxProcsInGroups and activeProcsInGroups to accumulate
incorrectly. Modify the code to either accumulate relationGroups across all
RelationGroup entries or clarify if it should only store the maximum group count
from the last entry, ensuring consistent and correct aggregation of group
information.
| // Get additional CPU information from Windows registry | ||
| k, err := registry.OpenKey(registry.LOCAL_MACHINE, | ||
| registryHive, | ||
| registry.QUERY_VALUE) | ||
| if err == nil { | ||
| defer k.Close() | ||
|
|
||
| dw, _, err := k.GetIntegerValue("~MHz") | ||
| cpuInfo.Mhz = utils.NewValueFrom(float64(dw), err) | ||
|
|
||
| s, _, err := k.GetStringValue("ProcessorNameString") | ||
| cpuInfo.ModelName = utils.NewValueFrom(s, err) | ||
|
|
||
| s, _, err = k.GetStringValue("VendorIdentifier") | ||
| cpuInfo.VendorID = utils.NewValueFrom(s, err) | ||
|
|
||
| s, _, err = k.GetStringValue("Identifier") | ||
| if err == nil { | ||
| cpuInfo.Family = utils.NewValue(extract(s, "Family")) | ||
| } else { | ||
| cpuInfo.Family = utils.NewErrorValue[string](err) | ||
| } | ||
| } else { | ||
| cpuInfo.Mhz = utils.NewErrorValue[float64](err) | ||
| cpuInfo.ModelName = utils.NewErrorValue[string](err) | ||
| cpuInfo.VendorID = utils.NewErrorValue[string](err) | ||
| cpuInfo.Family = utils.NewErrorValue[string](err) | ||
| if err != nil { | ||
| log.Errorf("failed to open registry key: %v", err) | ||
| return &Info{} | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Preserve CPU data from C function when registry access fails.
The current implementation returns an empty Info{} struct when the registry key cannot be opened, discarding potentially valid CPU topology data already retrieved from the C function (cores, logical processors, cache sizes, etc.).
Consider continuing with the data collection even if the registry access fails:
// Get additional CPU information from Windows registry
k, err := registry.OpenKey(registry.LOCAL_MACHINE,
registryHive,
registry.QUERY_VALUE)
if err != nil {
log.Errorf("failed to open registry key: %v", err)
- return &Info{}
+ // Continue with partial data from C function
+ } else {
+ defer k.Close()
+
+ if mhz, _, err := k.GetIntegerValue("~MHz"); err == nil {
+ cInfo.Mhz = float64(mhz)
+ }
+ // ... rest of registry reads ...
}
- defer k.Close()This ensures that CPU topology information is still available even if registry-based details (MHz, vendor ID, etc.) cannot be retrieved.
🤖 Prompt for AI Agents
In pkg/gohai/cpu/cpu_windows.go around lines 100 to 107, the code returns an
empty Info struct when failing to open the registry key, discarding CPU data
obtained from the C function. Modify the error handling to log the error but
continue execution, returning the partially populated Info struct with the data
collected so far instead of an empty one. This preserves CPU topology
information even if registry access fails.
| GetLogicalProcessorInformationEx(RelationAll, NULL, &buflen); | ||
| if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | ||
| return GetLastError(); | ||
| } | ||
|
|
||
| buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(buflen); |
There was a problem hiding this comment.
🐕 Corgea found a CWE-190: Integer Overflow or Wraparound vulnerability that is rated as 🔴 High.
View in Corgea.
🎟️Issue Explanation: The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.
More issue details
The code risks integer overflow by assuming a calculated buffer size will stay positive, which could lead to resource mismanagement or improper execution control.-"buflen" could exceed its maximum value during calculation, converting it into a negative.
-Overflow can trick "malloc(buflen)" into allocating insufficient memory.
-If exploited, this can disrupt tasks or expose sensitive data like processor info.
Fix Details
The fix prevents integer overflow and zero-size allocations by checking if "buflen" is within valid limits before allocating memory. This ensures safe resource management and guards against potential overflow and wraparound vulnerabilities.- An overflow check is added: "if (buflen == 0 || buflen > SIZE_MAX)" to ensure safe memory allocation.
- Returns "ERROR_INVALID_PARAMETER" if conditions are met, preventing further execution with invalid buffer sizes.
- Typecasting "buflen" to "(size_t)" during allocation ensures correct memory size handling.
| GetLogicalProcessorInformationEx(RelationAll, NULL, &buflen); | |
| if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | |
| return GetLastError(); | |
| } | |
| buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(buflen); | |
| GetLogicalProcessorInformationEx(RelationAll, NULL, &buflen); | |
| if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | |
| return GetLastError(); | |
| } | |
| // Prevent integer overflow and zero-size allocation |
What does this PR do?
Motivation
Describe how you validated your changes
Possible Drawbacks / Trade-offs
Additional Notes
Summary by CodeRabbit