Skip to content

[Release 10.0] Support hardware with more than 1024 CPUs - #4

Open
anurag6569201 wants to merge 1 commit into
qa/agent-dotnet-runtime/pr-04-131740/basefrom
qa/agent-dotnet-runtime/pr-04-131740/head
Open

anurag6569201 wants to merge 1 commit into
qa/agent-dotnet-runtime/pr-04-131740/basefrom
qa/agent-dotnet-runtime/pr-04-131740/head

Conversation

@anurag6569201

Copy link
Copy Markdown

Backport of dotnet#126763 and dotnet#127572 to release/10.0

Customer Impact

.NET runtime fails to initialize on Linux on machines that have more than 1024 CPUs due to sched_getaffinity being passed the default instance of cpu_set_t that supports max 1024 CPUs and fails if there are more CPUs on the current machine.
This occurs also in case of containers limited to a small number of CPUs running on a host with more than 1024 CPUs. So it is impossible to use .NET on such machines.

Regression

  • Yes
  • No

Testing

Directed test on Azure VM with 1792 CPU cores, CI testing coreclr and libraries tests.

Risk

Low. The change has been in main since the beginning of April and no issues were discovered.

Source merge-base: 76ca66ef3bed7037ac2f7f708d48baf93953a8d6
Source head: 8bb9f3c49f7350fe8806d489c0476ac90a35e42f

@shipwright-agent

Copy link
Copy Markdown

⛔ Shipwright · Blocked

Recommendation: do not merge PR #4 · Tier T2
Checks: 0 total · 0 needing attention

Next step: resolve the blocking findings before merge.

Findings (28)

  • CRITICAL SetThreadAffinity allocates a cpu_set_t sized for g_configuredCpuCount but calls CPU_SET_S with procNo without validating procNo < g_configuredCpuCount. · src/coreclr/gc/unix/gcenv.unix.cpp:1120
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL SetThreadAffinity calls CPU_ALLOC(g_configuredCpuCount) without checking for nullptr before CPU_ZERO_S/CPU_SET_S. · src/coreclr/gc/unix/gcenv.unix.cpp:1117
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL AffinitySet::Initialize computes m_bitsetDataSize = (cpuCount + BitsPerBitsetEntry - 1) / BitsPerBitsetEntry without overflow protection. · src/coreclr/gc/env/gcenv.os.h:180
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL The assertion before proc_no_to_heap_no[proc_no] uses GetActiveProcessorCount(), but the array is sized by GetMaxProcessorCount(). · src/coreclr/gc/gc.cpp:19504
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL GetProcessorForHeap casts the uint32_t loop index to uint16_t when assigning procIndex. · src/coreclr/gc/windows/gcenv.windows.cpp:1205
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The assertion 'assert(proc_no < GCToOSInterface::GetActiveProcessorCount ());' is added before indexing 'proc_no_to_heap_no[proc_no]', but the array was allocated with 'GCToOSInter · src/coreclr/gc/gc.cpp:19504
    • Fix: Fix the review finding before release.
  • HIGH GetProcessorForHeap casts the loop index i (now uint32_t, up to GetTotalProcessorCount()) to uint16_t when assigning procIndex. · src/coreclr/gc/windows/gcenv.windows.cpp:1205
    • Fix: Fix the review finding before release.
  • HIGH SetThreadAffinity allocates a cpu_set_t sized for g_configuredCpuCount but then calls CPU_SET_S with procNo without validating that procNo is less than g_configuredCpuCount. · src/coreclr/gc/unix/gcenv.unix.cpp:1120
    • Fix: Fix the review finding before release.
  • …and 20 more findings in the check details.

Fireworks usage: 36,597 input · 3,431 output · 40,028 total tokens · $0.0103 · 27s · 0 fix iteration(s)

Open the Shipwright check for full evidence and the audit bundle. Use /shipwright rerun to verify again.


cpu_set_t* pCpuSet = CPU_ALLOC(g_configuredCpuCount);
size_t cpuSetSize = CPU_ALLOC_SIZE(g_configuredCpuCount);
CPU_ZERO_S(cpuSetSize, pCpuSet);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · CRITICAL

SetThreadAffinity allocates a cpu_set_t sized for g_configuredCpuCount but calls CPU_SET_S with procNo without validating procNo < g_configuredCpuCount.

Impact: SetThreadAffinity allocates a cpu_set_t sized for g_configuredCpuCount but calls CPU_SET_S with procNo without validating procNo < g_configuredCpuCount. A larger procNo causes an out-of-bounds write and memory corruption.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

cpu_set_t cpuSet;
CPU_ZERO(&cpuSet);
CPU_SET((int)procNo, &cpuSet);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · CRITICAL

SetThreadAffinity calls CPU_ALLOC(g_configuredCpuCount) without checking for nullptr before CPU_ZERO_S/CPU_SET_S.

Impact: SetThreadAffinity calls CPU_ALLOC(g_configuredCpuCount) without checking for nullptr before CPU_ZERO_S/CPU_SET_S. Allocation failure dereferences null and crashes.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

AffinitySet(AffinitySet&&) = delete;
AffinitySet& operator=(AffinitySet&&) = delete;

bool Initialize(int cpuCount)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · CRITICAL

AffinitySet::Initialize computes m_bitsetDataSize = (cpuCount + BitsPerBitsetEntry - 1) / BitsPerBitsetEntry without overflow protection.

Impact: AffinitySet::Initialize computes m_bitsetDataSize = (cpuCount + BitsPerBitsetEntry - 1) / BitsPerBitsetEntry without overflow protection. A large uint32_t cpuCount can overflow the addition, causing a small allocation and later out-of-bounds access.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Comment thread src/coreclr/gc/gc.cpp
last_proc_no = proc_no;
}

assert(proc_no < GCToOSInterface::GetActiveProcessorCount ());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · CRITICAL

The assertion before proc_no_to_heap_no[proc_no] uses GetActiveProcessorCount(), but the array is sized by GetMaxProcessorCount().

Impact: The assertion before proc_no_to_heap_no[proc_no] uses GetActiveProcessorCount(), but the array is sized by GetMaxProcessorCount(). If active count is less than max count, a valid processor index can fail the assertion in debug builds even though the access is safe.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

if (cnt == 0)
{
procIndex = i;
procIndex = (uint16_t)i;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · CRITICAL

GetProcessorForHeap casts the uint32_t loop index to uint16_t when assigning procIndex.

Impact: GetProcessorForHeap casts the uint32_t loop index to uint16_t when assigning procIndex. On systems with more than 65535 processors this truncates the processor number and can return an incorrect or duplicate processor for a heap.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Comment thread src/coreclr/gc/gc.cpp
last_proc_no = proc_no;
}

assert(proc_no < GCToOSInterface::GetActiveProcessorCount ());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

The assertion 'assert(proc_no < GCToOSInterface::GetActiveProcessorCount ());' is added before indexing 'proc_no_to_heap_no[proc_no]', but the array was allocated with 'GCToOSInter

Impact: The assertion 'assert(proc_no < GCToOSInterface::GetActiveProcessorCount ());' is added before indexing 'proc_no_to_heap_no[proc_no]', but the array was allocated with 'GCToOSInterface::GetMaxProcessorCount()' entries. If 'GetActiveProcessorCount()' can be less than 'GetMaxProcessorCount()' (e.g., due to CPU groups or affinity restrictions), a valid processor number may be >= active count but < max count, c…

Suggested fix: Fix the review finding before release.

if (cnt == 0)
{
procIndex = i;
procIndex = (uint16_t)i;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

GetProcessorForHeap casts the loop index i (now uint32_t, up to GetTotalProcessorCount()) to uint16_t when assigning procIndex.

Impact: GetProcessorForHeap casts the loop index i (now uint32_t, up to GetTotalProcessorCount()) to uint16_t when assigning procIndex. On systems with more than 65535 processors, this truncates the processor number and can return an incorrect processor for a heap, defeating the >1024 CPU support and potentially assigning duplicate/invalid processor indices.

Suggested fix: Fix the review finding before release.


cpu_set_t* pCpuSet = CPU_ALLOC(g_configuredCpuCount);
size_t cpuSetSize = CPU_ALLOC_SIZE(g_configuredCpuCount);
CPU_ZERO_S(cpuSetSize, pCpuSet);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

SetThreadAffinity allocates a cpu_set_t sized for g_configuredCpuCount but then calls CPU_SET_S with procNo without validating that procNo is less than g_configuredCpuCount.

Impact: SetThreadAffinity allocates a cpu_set_t sized for g_configuredCpuCount but then calls CPU_SET_S with procNo without validating that procNo is less than g_configuredCpuCount. If procNo exceeds the configured count, CPU_SET_S writes out of bounds, corrupting memory. The previous fixed-size cpu_set_t also had this issue for values >= CPU_SETSIZE, but the new dynamic allocation makes the bound explicit and the diff i…

Suggested fix: Fix the review finding before release.

AffinitySet(AffinitySet&&) = delete;
AffinitySet& operator=(AffinitySet&&) = delete;

bool Initialize(int cpuCount)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

'AffinitySet::Initialize' uses 'new (nothrow) uintptr_t[m_bitsetDataSize]' but does not check for integer overflow when computing 'm_bitsetDataSize = (cpuCount + BitsPerBitsetEntry

Impact: 'AffinitySet::Initialize' uses 'new (nothrow) uintptr_t[m_bitsetDataSize]' but does not check for integer overflow when computing 'm_bitsetDataSize = (cpuCount + BitsPerBitsetEntry - 1) / BitsPerBitsetEntry'. If 'cpuCount' is very large (e.g., 'UINT32_MAX'), the addition can overflow, leading to a small allocation and subsequent out-of-bounds access. The caller passes 'GetMaxProcessorCount()', which is a 'uint32_t',…

Suggested fix: Fix the review finding before release.

}

if ((start_index >= MAX_SUPPORTED_CPUS) || (end_index >= MAX_SUPPORTED_CPUS) || (end_index < start_index))
size_t maxCpuCount = GCToOSInterface::GetMaxProcessorCount();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

In ParseGCHeapAffinitizeRanges, maxCpuCount is obtained from GCToOSInterface::GetMaxProcessorCount(), which returns g_processAffinitySet.MaxCpuCount().

Impact: In ParseGCHeapAffinitizeRanges, maxCpuCount is obtained from GCToOSInterface::GetMaxProcessorCount(), which returns g_processAffinitySet.MaxCpuCount(). On Windows, g_processAffinitySet is initialized in GCToOSInterface::Initialize() before this parsing path, but the new GetMaxProcessorCount() implementation is only added in gcenv.windows.cpp. Other platforms implementing GCToOSInterface may not provide GetMaxProcess…

Suggested fix: Fix the review finding before release.

cpu_set_t cpuSet;
CPU_ZERO(&cpuSet);
CPU_SET((int)procNo, &cpuSet);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

SetThreadAffinity calls CPU_ALLOC(g_configuredCpuCount) without checking for nullptr before CPU_ZERO_S/CPU_SET_S.

Impact: SetThreadAffinity calls CPU_ALLOC(g_configuredCpuCount) without checking for nullptr before CPU_ZERO_S/CPU_SET_S. On allocation failure this dereferences null and crashes. The Initialize path checks CPU_ALLOC result, but this new allocation does not.

Suggested fix: Fix the review finding before release.

{
break;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

minipal_get_cpu_max_possible_count parses /sys/devices/system/cpu/possible with fscanf and fgetc.

Impact: minipal_get_cpu_max_possible_count parses /sys/devices/system/cpu/possible with fscanf and fgetc. If the sysfs list contains spaces around commas, parsing stops prematurely and misses later CPU ranges.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

AffinitySet(const AffinitySet&) = delete;
AffinitySet& operator=(const AffinitySet&) = delete;
AffinitySet(AffinitySet&&) = delete;
AffinitySet& operator=(AffinitySet&&) = delete;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

AffinitySet::Initialize asserts m_bitset == nullptr but has no release-build guard against double initialization.

Impact: AffinitySet::Initialize asserts m_bitset == nullptr but has no release-build guard against double initialization. A second call leaks the first allocation and overwrites the pointer.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

CPU_ZERO_S(cpuSetSize, pCpuSet);

int st = sched_getaffinity(gPID, cpuSetSize, pCpuSet);
if (st == 0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

PAL_GetLogicalCpuCountFromOS recomputes CPU_ALLOC_SIZE(configuredCpuCount) instead of using the already-computed cpuSetSize.

Impact: PAL_GetLogicalCpuCountFromOS recomputes CPU_ALLOC_SIZE(configuredCpuCount) instead of using the already-computed cpuSetSize. This is inconsistent and risks a size mismatch if the value changes between calls.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

AffinitySet(AffinitySet&&) = delete;
AffinitySet& operator=(AffinitySet&&) = delete;

bool Initialize(int cpuCount)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

AffinitySet::Initialize does not validate cpuCount > 0.

Impact: AffinitySet::Initialize does not validate cpuCount > 0. A zero cpuCount can produce a zero-sized allocation and later assertions or invalid access in Contains/Add/Remove.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

palError = ERROR_INTERNAL_ERROR;
goto fail;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · HIGH

CPalThread::ThreadEntry now treats sched_getaffinity failure as non-fatal and continues without restoring thread affinity.

Impact: CPalThread::ThreadEntry now treats sched_getaffinity failure as non-fatal and continues without restoring thread affinity. This silently skips the affinity restoration required for Snap sandboxing and may allow threads to run with incorrect affinity in constrained environments.

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

CPU_ZERO_S(cpuSetSize, pCpuSet);

int st = sched_getaffinity(gPID, cpuSetSize, pCpuSet);
if (st == 0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · MEDIUM

PAL_GetLogicalCpuCountFromOS calls CPU_COUNT_S(CPU_ALLOC_SIZE(configuredCpuCount), pCpuSet) instead of using the already-computed cpuSetSize variable.

Impact: PAL_GetLogicalCpuCountFromOS calls CPU_COUNT_S(CPU_ALLOC_SIZE(configuredCpuCount), pCpuSet) instead of using the already-computed cpuSetSize variable. This is functionally equivalent but recomputes the allocation size; more importantly, if CPU_ALLOC_SIZE is not idempotent or the configuredCpuCount changes between calls, the size could differ from the buffer allocated. The local cpuSetSize should be used for consiste…

Suggested fix: Fix the review finding before release.

return g_totalCpuCount;
}

uint32_t GCToOSInterface::GetMaxProcessorCount()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · MEDIUM

The new GetMaxProcessorCount returns g_processAffinitySet.MaxCpuCount(), which is the maximum possible CPU count, not the total processor count.

Impact: The new GetMaxProcessorCount returns g_processAffinitySet.MaxCpuCount(), which is the maximum possible CPU count, not the total processor count. If callers expect the number of processors available to the process, this can over-report CPUs on systems where the affinity set is sparse or configured CPU count exceeds online CPUs. The diff does not show callers, but the method name and existing GetTotalProcessorCount di…

Suggested fix: Fix the review finding before release.

AffinitySet(AffinitySet&&) = delete;
AffinitySet& operator=(AffinitySet&&) = delete;

bool Initialize(int cpuCount)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · MEDIUM

'AffinitySet::Initialize' does not handle the case where 'cpuCount' is zero.

Impact: 'AffinitySet::Initialize' does not handle the case where 'cpuCount' is zero. If 'cpuCount' is zero, 'm_bitsetDataSize' becomes zero, and 'new (nothrow) uintptr_t[0]' may return a non-null pointer or null depending on the implementation. If it returns non-null, 'memset' with size zero is fine, but subsequent 'Contains'/'Add'/'Remove' calls with any index will assert because 'GetBitsetEntryIndex(cpuIndex) < m_bitse…

Suggested fix: Fix the review finding before release.

palError = ERROR_INTERNAL_ERROR;
goto fail;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · MEDIUM

In CPalThread::ThreadEntry, when sched_getaffinity fails, the code now treats it as non-fatal and continues without setting the thread affinity.

Impact: In CPalThread::ThreadEntry, when sched_getaffinity fails, the code now treats it as non-fatal and continues without setting the thread affinity. The previous behavior returned ERROR_INTERNAL_ERROR and aborted thread creation. This change silently skips the affinity restoration that the surrounding comment says is required for Snap sandboxing, potentially allowing threads to run with incorrect affinity in constrained…

Suggested fix: Fix the review finding before release.

{
break;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · MEDIUM

'minipal_get_cpu_max_possible_count' uses 'fscanf' to parse the possible CPU list.

Impact: 'minipal_get_cpu_max_possible_count' uses 'fscanf' to parse the possible CPU list. The format '%d-%d' does not handle whitespace or newlines robustly. If the file contains a trailing newline after the last range, the loop will break after reading the last range and then 'fgetc' will return the newline, which is not '','', so the loop breaks. This is correct. However, if the file contains spaces around the comma (e.g…

Suggested fix: Fix the review finding before release.

AffinitySet(const AffinitySet&) = delete;
AffinitySet& operator=(const AffinitySet&) = delete;
AffinitySet(AffinitySet&&) = delete;
AffinitySet& operator=(AffinitySet&&) = delete;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · MEDIUM

'AffinitySet::Initialize' asserts 'm_bitset == nullptr' but does not prevent double initialization in release builds.

Impact: 'AffinitySet::Initialize' asserts 'm_bitset == nullptr' but does not prevent double initialization in release builds. If 'Initialize' is called twice, the second call will leak the first allocation and overwrite the pointer. The diff does not show any guard against this in release builds.

Suggested fix: Fix the review finding before release.

if (maxCpu != -1)
{
return maxCpu + 1;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · LOW

'minipal_get_cpu_max_possible_count' returns the maximum CPU index plus one, but the caller uses this value as the CPU count for 'CPU_ALLOC'.

Impact: 'minipal_get_cpu_max_possible_count' returns the maximum CPU index plus one, but the caller uses this value as the CPU count for 'CPU_ALLOC'. On Linux, 'CPU_ALLOC' expects the number of CPUs, so this is correct. However, the fallback 'sysconf(_SC_NPROCESSORS_CONF)' returns the number of configured processors, which is also a count. The issue is that the function name and documentation imply a count, but the parsing…

Suggested fix: Fix the review finding before release.

{
size_t count = 0;
for (size_t i = 0; i < MAX_SUPPORTED_CPUS; i++)
for (size_t i = 0; i < m_bitsetDataSize * BitsPerBitsetEntry; i++)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · LOW

'AffinitySet::Count' iterates up to 'm_bitsetDataSize * BitsPerBitsetEntry' and calls 'Contains(i)' for each index.

Impact: 'AffinitySet::Count' iterates up to 'm_bitsetDataSize * BitsPerBitsetEntry' and calls 'Contains(i)' for each index. 'Contains' asserts that 'GetBitsetEntryIndex(cpuIndex) < m_bitsetDataSize'. For the last valid index, 'GetBitsetEntryIndex' returns 'm_bitsetDataSize - 1', so the assert passes. However, if 'm_bitsetDataSize' is zero (e.g., 'Initialize' was never called or failed), the loop does not execute, so no a…

Suggested fix: Fix the review finding before release.

}

count = CPU_COUNT(&cpuSet);
if (count == 0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · LOW

In 'InitializeCurrentProcessCpuCount', the fallback to 'GCToOSInterface::GetTotalProcessorCount()' is used when 'count == 0'.

Impact: In 'InitializeCurrentProcessCpuCount', the fallback to 'GCToOSInterface::GetTotalProcessorCount()' is used when 'count == 0'. However, 'count' is initialized to 0 and only set if 'sched_getaffinity' succeeds. If 'sched_getaffinity' succeeds but returns 0 CPUs (which is possible if the process has no affinity to any CPU), the fallback is triggered, which may be intentional. This is not a defect.

Suggested fix: Fix the review finding before release.

@@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · LOW

The new file 'src/native/minipal/cpucount.c' includes '<stdio.h>' and '<unistd.h>' but the header 'cpucount.h' is not shown in the diff.

Impact: The new file 'src/native/minipal/cpucount.c' includes '<stdio.h>' and '<unistd.h>' but the header 'cpucount.h' is not shown in the diff. If the header does not declare 'minipal_get_cpu_max_possible_count' with the correct calling convention or visibility, this could cause a linker error. However, the diff does not show the header, so this cannot be confirmed.

Suggested fix: Fix the review finding before release.

#ifndef __GCENV_OS_H__
#define __GCENV_OS_H__

#include <new>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · LOW

'AffinitySet::Initialize' uses 'new (nothrow)' but does not include '<new>' in the file where it is used.

Impact: 'AffinitySet::Initialize' uses 'new (nothrow)' but does not include '<new>' in the file where it is used. The diff adds '#include <new>' at the top of 'gcenv.os.h', so this is not a defect.

Suggested fix: Fix the review finding before release.

~AffinitySet()
{
memset(m_bitset, 0, sizeof(m_bitset));
delete[] m_bitset;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shipwright · LOW

The 'AffinitySet' destructor calls 'delete[] m_bitset' without checking for null.

Impact: The 'AffinitySet' destructor calls 'delete[] m_bitset' without checking for null. 'delete[]' on a null pointer is safe, so this is not a defect.

Suggested fix: Fix the review finding before release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant