Repository: dotnet/runtime
File: src/coreclr/debug/daccess/enummem.cpp (C++)

Code before:
    }

    PTR_ContractDescriptor pContractDescriptor = dac_cast<PTR_ContractDescriptor>((TADDR)contractDescriptorAddr);
    // Enumerate the ContractDescriptor structure
    ReportMem(dac_cast<TADDR>(pContractDescriptor), sizeof(ContractDescriptor));
    // Report the pointer data array
    ReportMem((TADDR)pContractDescriptor->pointer_data, pContractDescriptor->pointer_data_count * sizeof(void*));
    // Report the JSON blob
    ReportMem((TADDR)pContractDescriptor->descriptor, pContractDescriptor->descriptor_size);

    // Assume that subdescriptors will be the n last pointers in the pointer_data array
    // Must be updated if further subdescriptors are added
    // This could be improved by iterating all of the pointer data recursively and identifying subdescriptors by
    // the magic field in ContractDescriptor, but given it will eventually move to the cDAC, this is good enough for now.
    int cSubDescriptors = 1;
    for (int i = 0; i < cSubDescriptors; i++)
    {
        int subDescriptorIndex = (pContractDescriptor->pointer_data_count - 1) - i;

        TADDR pSubDescriptorAddr;
        ULONG32 bytesRead;
        if (FAILED(m_pTarget->ReadVirtual(
            (TADDR)pContractDescriptor->pointer_data + subDescriptorIndex * sizeof(void*),
            (PBYTE)&pSubDescriptorAddr, sizeof(TADDR), &bytesRead))
            || bytesRead != sizeof(TADDR)
            || pSubDescriptorAddr == NULL)
        {
            continue;
        }

        TADDR subDescriptorAddr;
        if (FAILED(m_pTarget->ReadVirtual(
            pSubDescriptorAddr,
            (PBYTE)&subDescriptorAddr, sizeof(TADDR), &bytesRead))
            || bytesRead != sizeof(TADDR)
            || subDescriptorAddr == NULL)
        {
            continue;
        }

        PTR_ContractDescriptor pSubDescriptor = dac_cast<PTR_ContractDescriptor>(subDescriptorAddr);
        // Enumerate the ContractDescriptor structure
        ReportMem(dac_cast<TADDR>(pSubDescriptor), sizeof(ContractDescriptor));
        // Report the pointer data array
        ReportMem((TADDR)pSubDescriptor->pointer_data, pSubDescriptor->pointer_data_count * sizeof(void*));
        // Report the JSON blob
        ReportMem((TADDR)pSubDescriptor->descriptor, pSubDescriptor->descriptor_size);
    }

    return status;
}

Review comment (suggestion):
Use `is null` instead of `== NULL` according to project coding guidelines. This should be `|| pSubDescriptorAddr is null)`.

Code after:
    // Assume that subdescriptors will be the n last pointers in the pointer_data array
    // Must be updated if further subdescriptors are added
    // This could be improved by iterating all of the pointer data recursively and identifying subdescriptors by
    // the magic field in ContractDescriptor. Given the low number of subdescriptors, this is not necessary right now.
    int cSubDescriptors = 1;
    PTR_ContractDescriptor pContractDescriptor = dac_cast<PTR_ContractDescriptor>((TADDR)contractDescriptorAddr);
    for (int i = 0; i < cSubDescriptors; i++)
    {
        int subDescriptorIndex = (pContractDescriptor->pointer_data_count - 1) - i;

        TADDR pSubDescriptorAddr;
        ULONG32 bytesRead;
        if (FAILED(m_pTarget->ReadVirtual(
            (TADDR)pContractDescriptor->pointer_data + subDescriptorIndex * sizeof(void*),
            (PBYTE)&pSubDescriptorAddr, sizeof(TADDR), &bytesRead))
            || bytesRead != sizeof(TADDR)
            || pSubDescriptorAddr == 0)
        {
            continue;
        }

        TADDR subDescriptorAddr;
        if (FAILED(m_pTarget->ReadVirtual(
            pSubDescriptorAddr,
            (PBYTE)&subDescriptorAddr, sizeof(TADDR), &bytesRead))
            || bytesRead != sizeof(TADDR)
            || subDescriptorAddr == 0)
        {
            continue;
        }

        // Save the subdescriptor
        EnumDataDescriptorHelper(subDescriptorAddr);
    }

    return S_OK;
}

void ClrDataAccess::EnumDataDescriptorHelper(TADDR dataDescriptorAddr)
{
    PTR_ContractDescriptor pDataDescriptor = dac_cast<PTR_ContractDescriptor>(dataDescriptorAddr);

    EX_TRY
    {
        // Enumerate the ContractDescriptor structure
        ReportMem(dac_cast<TADDR>(pDataDescriptor), sizeof(ContractDescriptor));
        // Report the pointer data array
        ReportMem((TADDR)pDataDescriptor->pointer_data, pDataDescriptor->pointer_data_count * sizeof(void*));
        // Report the JSON blob
        ReportMem((TADDR)pDataDescriptor->descriptor, pDataDescriptor->descriptor_size);
    }