узнать по куче (созданной через HeapCreate) ее размер

Тема в разделе "WASM.WIN32", создана пользователем PorosenokPedro, 19 окт 2017.

  1. PorosenokPedro

    PorosenokPedro New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2017
    Сообщения:
    7
    как можно узнать по адресу кучи ее размер ?
    HANDLE HeapAdr =
    HANDLE WINAPI HeapCreate(
    _In_ DWORD flOptions,
    _In_ SIZE_T dwInitialSize,
    _In_ SIZE_T dwMaximumSize
    );

    на входе только HeapAdr, нужно узнать dwInitialSize.
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Перебрать через HeapWalk() все блоки кучи и просуммировать их размер.
     
  3. PorosenokPedro

    PorosenokPedro New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2017
    Сообщения:
    7
    не вариант, сама куча может иметь размер 10 mb для примера , а мы выделили только 2 блока по 20 байт - вернет 40 байт
     
  4. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    HeapWalk() сообщает и о свободных блоках.
     
    PorosenokPedro нравится это.
  5. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Код (Text):
    1. RtlCreateHeap (
    2.     IN ULONG Flags,
    3.     IN PVOID HeapBase OPTIONAL,
    4.     IN SIZE_T ReserveSize OPTIONAL,
    5.     IN SIZE_T CommitSize OPTIONAL,
    6.     IN PVOID Lock OPTIONAL,
    7.     IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL
    8.     )
    Код (Text):
    1.         CommitSize = ROUND_UP_TO_POWER2(CommitSize, PAGE_SIZE);
    2.  
    3.         if (!ARGUMENT_PRESENT( ReserveSize )) {
    4.  
    5.             ReserveSize = ROUND_UP_TO_POWER2( CommitSize, 16 * PAGE_SIZE );
    6.  
    7.         } else {
    8.  
    9.             ReserveSize = ROUND_UP_TO_POWER2( ReserveSize, PAGE_SIZE );
    10.         }
    Тоесть какой вам параметр нужен и зачем ?

    Есть множество апи для получения инфы про хип. RtlSizeHeap() не годится ?
     
  6. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    она возвращает размер указанного блока на куче, а не размер начальный размер кучи...
     
  7. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Rel,

    go back #5
     
  8. PorosenokPedro

    PorosenokPedro New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2017
    Сообщения:
    7
    rmn был прав, недооценил я HeapWalk
    Код (C++):
    1.  
    2. unsigned long GetHeapInitializedSize(HANDLE heap)
    3. {
    4.    unsigned long sz = 0;
    5.    HeapLock(heap);
    6.    PROCESS_HEAP_ENTRY entry;
    7.    memset(&entry, '\0', sizeof entry);
    8.    while (HeapWalk(heap, &entry))
    9.    {
    10.        if (entry.wFlags != PROCESS_HEAP_UNCOMMITTED_RANGE)
    11.        {
    12.             sz += entry.cbData;
    13.        }
    14.    }
    15.    HeapUnlock(heap);
    16.    return sz;
    17. }
    18.  
    19.  
    но вернет оно значение без размера служебной таблицы хипы, результат нужно округлить до размера страницы
     
  9. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    875
    Можно еще посмотреть в DEBUG_HEAP_INFORMATION информацию о куче:
    Код (C++):
    1.  
    2. PDEBUG_BUFFER buffer;
    3. NTSTATUS ntStatus;
    4.  
    5. buffer = RtlCreateQueryDebugBuffer(0,FALSE);
    6.  
    7. ntStatus = RtlQueryProcessDebugInformation(GetCurrentProcessId(),
    8. PDI_HEAPS|PDI_HEAP_BLOCKS,
    9. buffer);
    10.  
    11. PDEBUG_HEAP_INFORMATION heapInfo = PDEBUG_HEAP_INFORMATION(PULONG(buffer->HeapInformation) + 1);
    12.  
    13. std::cout << "Base: " << heapInfo->Base
    14.           << "\nAllocated: " << heapInfo->Allocated
    15.           << "\nCommited: " << heapInfo->Committed
    16.           << "\nBlockCount: " << heapInfo->BlockCount;
    17.  
    18. RtlDestroyQueryDebugBuffer(buffer);
    19.  
    Перебирать списки DEBUG_HEAP_INFORMATION пока не найдешь свой.
     
    PorosenokPedro нравится это.
  10. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Размер блока со служебными таблицами равен entry.cbData + entry.cbOverhead.
     
    PorosenokPedro нравится это.
  11. PorosenokPedro

    PorosenokPedro New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2017
    Сообщения:
    7
    верно, остается еще служебная таблица хипы, не знаю насколько будет корректным округлить результирующее значение на величину страницы

    Код (C++):
    1.  
    2.  
    3. unsigned long GetHeapInitializedSize(HANDLE heap)
    4. {
    5.    unsigned long sz = 0;
    6.    HeapLock(heap);
    7.    PROCESS_HEAP_ENTRY entry;
    8.    memset(&entry, '\0', sizeof entry);
    9.    while (HeapWalk(heap, &entry))
    10.    {
    11.        if (entry.wFlags != PROCESS_HEAP_UNCOMMITTED_RANGE)
    12.        {
    13.             sz += entry.cbData + entry.cbOverhead;
    14.        }
    15.    }
    16.    HeapUnlock(heap);
    17.    return sz;
    18. }
    19.  
    20.  
     
  12. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    875
    DEBUG_HEAP_INFORMATION.Allocated
     
  13. PorosenokPedro

    PorosenokPedro New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2017
    Сообщения:
    7
    а это вообще идеально выдает
    Код (C++):
    1.  
    2. ULONG GetHeapInitializedSize2(HANDLE heap)
    3. {
    4.  
    5. ULONG res = 0;
    6. PDEBUG_BUFFER db = (PDEBUG_BUFFER)RtlCreateQueryDebugBuffer(0, FALSE);
    7. RtlQueryProcessDebugInformation(GetCurrentProcessId(), PDI_HEAPS | PDI_HEAP_BLOCKS, db);
    8. ULONG heapNodeCount = db->HeapInformation ? *PULONG(db->HeapInformation) : 0;
    9. PDEBUG_HEAP_INFORMATION heapInfo = PDEBUG_HEAP_INFORMATION(PULONG(db->HeapInformation) + 1);
    10. for (unsigned int i = 0; i < heapNodeCount; i++)
    11. {
    12. if (heapInfo[i].Base == (ULONG)heap)
    13. {
    14. res = heapInfo[i].Committed;
    15. break;
    16. }
    17. }
    18. RtlDestroyQueryDebugBuffer(db);
    19. return res;
    20. }
    21.