1 /*-------------------------------------------------------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and/or associated documentation files (the
9 * "Materials"), to deal in the Materials without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Materials, and to
12 * permit persons to whom the Materials are furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice(s) and this permission notice shall be
16 * included in all copies or substantial portions of the Materials.
18 * The Materials are Confidential Information as defined by the
19 * Khronos Membership Agreement until designated non-confidential by
20 * Khronos, at which point this condition clause shall be removed.
22 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
32 * \brief Memory allocation callback utilities.
33 *//*--------------------------------------------------------------------*/
35 #include "vkAllocationCallbackUtil.hpp"
36 #include "tcuFormatUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "deSTLUtil.hpp"
46 // System default allocator
48 static VKAPI_ATTR void* VKAPI_CALL systemAllocate (void*, size_t size, size_t alignment, VkSystemAllocationScope)
51 return deAlignedMalloc(size, (deUint32)alignment);
56 static VKAPI_ATTR void VKAPI_CALL systemFree (void*, void* pMem)
61 static VKAPI_ATTR void* VKAPI_CALL systemReallocate (void*, void* pOriginal, size_t size, size_t alignment, VkSystemAllocationScope)
63 return deAlignedRealloc(pOriginal, size, alignment);
66 static VKAPI_ATTR void VKAPI_CALL systemInternalAllocationNotification (void*, size_t, VkInternalAllocationType, VkSystemAllocationScope)
70 static VKAPI_ATTR void VKAPI_CALL systemInternalFreeNotification (void*, size_t, VkInternalAllocationType, VkSystemAllocationScope)
74 static const VkAllocationCallbacks s_systemAllocator =
80 systemInternalAllocationNotification,
81 systemInternalFreeNotification,
84 const VkAllocationCallbacks* getSystemAllocator (void)
86 return &s_systemAllocator;
89 // AllocationCallbacks
91 static VKAPI_ATTR void* VKAPI_CALL allocationCallback (void* pUserData, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
93 return reinterpret_cast<AllocationCallbacks*>(pUserData)->allocate(size, alignment, allocationScope);
96 static VKAPI_ATTR void* VKAPI_CALL reallocationCallback (void* pUserData, void* pOriginal, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
98 return reinterpret_cast<AllocationCallbacks*>(pUserData)->reallocate(pOriginal, size, alignment, allocationScope);
101 static VKAPI_ATTR void VKAPI_CALL freeCallback (void* pUserData, void* pMem)
103 reinterpret_cast<AllocationCallbacks*>(pUserData)->free(pMem);
106 static VKAPI_ATTR void VKAPI_CALL internalAllocationNotificationCallback (void* pUserData, size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
108 reinterpret_cast<AllocationCallbacks*>(pUserData)->notifyInternalAllocation(size, allocationType, allocationScope);
111 static VKAPI_ATTR void VKAPI_CALL internalFreeNotificationCallback (void* pUserData, size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
113 reinterpret_cast<AllocationCallbacks*>(pUserData)->notifyInternalFree(size, allocationType, allocationScope);
116 static VkAllocationCallbacks makeCallbacks (AllocationCallbacks* object)
118 const VkAllocationCallbacks callbacks =
120 reinterpret_cast<void*>(object),
122 reallocationCallback,
124 internalAllocationNotificationCallback,
125 internalFreeNotificationCallback
130 AllocationCallbacks::AllocationCallbacks (void)
131 : m_callbacks(makeCallbacks(this))
135 AllocationCallbacks::~AllocationCallbacks (void)
139 // AllocationCallbackRecord
141 AllocationCallbackRecord AllocationCallbackRecord::allocation (size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr)
143 AllocationCallbackRecord record;
145 record.type = TYPE_ALLOCATION;
146 record.data.allocation.size = size;
147 record.data.allocation.alignment = alignment;
148 record.data.allocation.scope = scope;
149 record.data.allocation.returnedPtr = returnedPtr;
154 AllocationCallbackRecord AllocationCallbackRecord::reallocation (void* original, size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr)
156 AllocationCallbackRecord record;
158 record.type = TYPE_REALLOCATION;
159 record.data.reallocation.original = original;
160 record.data.reallocation.size = size;
161 record.data.reallocation.alignment = alignment;
162 record.data.reallocation.scope = scope;
163 record.data.reallocation.returnedPtr = returnedPtr;
168 AllocationCallbackRecord AllocationCallbackRecord::free (void* mem)
170 AllocationCallbackRecord record;
172 record.type = TYPE_FREE;
173 record.data.free.mem = mem;
178 AllocationCallbackRecord AllocationCallbackRecord::internalAllocation (size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope)
180 AllocationCallbackRecord record;
182 record.type = TYPE_INTERNAL_ALLOCATION;
183 record.data.internalAllocation.size = size;
184 record.data.internalAllocation.type = type;
185 record.data.internalAllocation.scope = scope;
190 AllocationCallbackRecord AllocationCallbackRecord::internalFree (size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope)
192 AllocationCallbackRecord record;
194 record.type = TYPE_INTERNAL_FREE;
195 record.data.internalAllocation.size = size;
196 record.data.internalAllocation.type = type;
197 record.data.internalAllocation.scope = scope;
204 ChainedAllocator::ChainedAllocator (const VkAllocationCallbacks* nextAllocator)
205 : m_nextAllocator(nextAllocator)
209 ChainedAllocator::~ChainedAllocator (void)
213 void* ChainedAllocator::allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
215 return m_nextAllocator->pfnAllocation(m_nextAllocator->pUserData, size, alignment, allocationScope);
218 void* ChainedAllocator::reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
220 return m_nextAllocator->pfnReallocation(m_nextAllocator->pUserData, original, size, alignment, allocationScope);
223 void ChainedAllocator::free (void* mem)
225 m_nextAllocator->pfnFree(m_nextAllocator->pUserData, mem);
228 void ChainedAllocator::notifyInternalAllocation (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
230 m_nextAllocator->pfnInternalAllocation(m_nextAllocator->pUserData, size, allocationType, allocationScope);
233 void ChainedAllocator::notifyInternalFree (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
235 m_nextAllocator->pfnInternalFree(m_nextAllocator->pUserData, size, allocationType, allocationScope);
238 // AllocationCallbackRecorder
240 AllocationCallbackRecorder::AllocationCallbackRecorder (const VkAllocationCallbacks* allocator, deUint32 callCountHint)
241 : ChainedAllocator (allocator)
242 , m_records (callCountHint)
246 AllocationCallbackRecorder::~AllocationCallbackRecorder (void)
250 void* AllocationCallbackRecorder::allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
252 void* const ptr = ChainedAllocator::allocate(size, alignment, allocationScope);
254 m_records.append(AllocationCallbackRecord::allocation(size, alignment, allocationScope, ptr));
259 void* AllocationCallbackRecorder::reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
261 void* const ptr = ChainedAllocator::reallocate(original, size, alignment, allocationScope);
263 m_records.append(AllocationCallbackRecord::reallocation(original, size, alignment, allocationScope, ptr));
268 void AllocationCallbackRecorder::free (void* mem)
270 ChainedAllocator::free(mem);
272 m_records.append(AllocationCallbackRecord::free(mem));
275 void AllocationCallbackRecorder::notifyInternalAllocation (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
277 ChainedAllocator::notifyInternalAllocation(size, allocationType, allocationScope);
279 m_records.append(AllocationCallbackRecord::internalAllocation(size, allocationType, allocationScope));
282 void AllocationCallbackRecorder::notifyInternalFree (size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope)
284 ChainedAllocator::notifyInternalFree(size, allocationType, allocationScope);
286 m_records.append(AllocationCallbackRecord::internalFree(size, allocationType, allocationScope));
289 // DeterministicFailAllocator
291 DeterministicFailAllocator::DeterministicFailAllocator (const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs)
292 : ChainedAllocator (allocator)
293 , m_numPassingAllocs(numPassingAllocs)
294 , m_allocationNdx (0)
298 DeterministicFailAllocator::~DeterministicFailAllocator (void)
302 void* DeterministicFailAllocator::allocate (size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
304 if (deAtomicIncrementUint32(&m_allocationNdx) <= m_numPassingAllocs)
305 return ChainedAllocator::allocate(size, alignment, allocationScope);
310 void* DeterministicFailAllocator::reallocate (void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope)
312 if (deAtomicIncrementUint32(&m_allocationNdx) <= m_numPassingAllocs)
313 return ChainedAllocator::reallocate(original, size, alignment, allocationScope);
320 AllocationCallbackValidationResults::AllocationCallbackValidationResults (void)
322 deMemset(internalAllocationTotal, 0, sizeof(internalAllocationTotal));
325 void AllocationCallbackValidationResults::clear (void)
327 liveAllocations.clear();
329 deMemset(internalAllocationTotal, 0, sizeof(internalAllocationTotal));
335 struct AllocationSlot
337 AllocationCallbackRecord record;
340 AllocationSlot (void)
344 AllocationSlot (const AllocationCallbackRecord& record_, bool isLive_)
350 size_t getAlignment (const AllocationCallbackRecord& record)
352 if (record.type == AllocationCallbackRecord::TYPE_ALLOCATION)
353 return record.data.allocation.alignment;
354 else if (record.type == AllocationCallbackRecord::TYPE_REALLOCATION)
355 return record.data.reallocation.alignment;
365 void validateAllocationCallbacks (const AllocationCallbackRecorder& recorder, AllocationCallbackValidationResults* results)
367 std::vector<AllocationSlot> allocations;
368 std::map<void*, size_t> ptrToSlotIndex;
370 DE_ASSERT(results->liveAllocations.empty() && results->violations.empty());
372 for (AllocationCallbackRecorder::RecordIterator callbackIter = recorder.getRecordsBegin();
373 callbackIter != recorder.getRecordsEnd();
376 const AllocationCallbackRecord& record = *callbackIter;
380 const VkSystemAllocationScope* const scopePtr = record.type == AllocationCallbackRecord::TYPE_ALLOCATION ? &record.data.allocation.scope
381 : record.type == AllocationCallbackRecord::TYPE_REALLOCATION ? &record.data.reallocation.scope
382 : record.type == AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION ? &record.data.internalAllocation.scope
383 : record.type == AllocationCallbackRecord::TYPE_INTERNAL_FREE ? &record.data.internalAllocation.scope
386 if (scopePtr && !de::inBounds(*scopePtr, (VkSystemAllocationScope)0, VK_SYSTEM_ALLOCATION_SCOPE_LAST))
387 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_INVALID_ALLOCATION_SCOPE));
390 // Validate alignment
391 if (record.type == AllocationCallbackRecord::TYPE_ALLOCATION ||
392 record.type == AllocationCallbackRecord::TYPE_REALLOCATION)
394 if (!deIsPowerOfTwoSize(getAlignment(record)))
395 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_INVALID_ALIGNMENT));
398 // Validate actual allocation behavior
401 case AllocationCallbackRecord::TYPE_ALLOCATION:
403 if (record.data.allocation.returnedPtr)
405 if (!de::contains(ptrToSlotIndex, record.data.allocation.returnedPtr))
407 ptrToSlotIndex[record.data.allocation.returnedPtr] = allocations.size();
408 allocations.push_back(AllocationSlot(record, true));
412 const size_t slotNdx = ptrToSlotIndex[record.data.allocation.returnedPtr];
413 if (!allocations[slotNdx].isLive)
415 allocations[slotNdx].isLive = true;
416 allocations[slotNdx].record = record;
420 // we should not have multiple live allocations with the same pointer
429 case AllocationCallbackRecord::TYPE_REALLOCATION:
431 if (de::contains(ptrToSlotIndex, record.data.reallocation.original))
433 const size_t origSlotNdx = ptrToSlotIndex[record.data.reallocation.original];
434 AllocationSlot& origSlot = allocations[origSlotNdx];
436 DE_ASSERT(record.data.reallocation.original != DE_NULL);
438 if (record.data.reallocation.size > 0)
440 if (getAlignment(origSlot.record) != record.data.reallocation.alignment)
441 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_REALLOC_DIFFERENT_ALIGNMENT));
443 if (record.data.reallocation.original == record.data.reallocation.returnedPtr)
445 if (!origSlot.isLive)
447 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_REALLOC_FREED_PTR));
448 origSlot.isLive = true; // Mark live to suppress further errors
451 // Just update slot record
452 allocations[origSlotNdx].record = record;
456 if (record.data.reallocation.returnedPtr)
458 allocations[origSlotNdx].isLive = false;
459 if (!de::contains(ptrToSlotIndex, record.data.reallocation.returnedPtr))
461 ptrToSlotIndex[record.data.reallocation.returnedPtr] = allocations.size();
462 allocations.push_back(AllocationSlot(record, true));
466 const size_t slotNdx = ptrToSlotIndex[record.data.reallocation.returnedPtr];
467 if (!allocations[slotNdx].isLive)
469 allocations[slotNdx].isLive = true;
470 allocations[slotNdx].record = record;
474 // we should not have multiple live allocations with the same pointer
479 // else original ptr remains valid and live
484 DE_ASSERT(!record.data.reallocation.returnedPtr);
486 origSlot.isLive = false;
491 if (record.data.reallocation.original)
492 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_REALLOC_NOT_ALLOCATED_PTR));
494 if (record.data.reallocation.returnedPtr)
496 DE_ASSERT(!de::contains(ptrToSlotIndex, record.data.reallocation.returnedPtr));
497 ptrToSlotIndex[record.data.reallocation.returnedPtr] = allocations.size();
498 allocations.push_back(AllocationSlot(record, true));
505 case AllocationCallbackRecord::TYPE_FREE:
507 if (record.data.free.mem != DE_NULL) // Freeing null pointer is valid and ignored
509 if (de::contains(ptrToSlotIndex, record.data.free.mem))
511 const size_t slotNdx = ptrToSlotIndex[record.data.free.mem];
513 if (allocations[slotNdx].isLive)
514 allocations[slotNdx].isLive = false;
516 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_DOUBLE_FREE));
519 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_FREE_NOT_ALLOCATED_PTR));
525 case AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION:
526 case AllocationCallbackRecord::TYPE_INTERNAL_FREE:
528 if (de::inBounds(record.data.internalAllocation.type, (VkInternalAllocationType)0, VK_INTERNAL_ALLOCATION_TYPE_LAST))
530 size_t* const totalAllocSizePtr = &results->internalAllocationTotal[record.data.internalAllocation.type][record.data.internalAllocation.scope];
531 const size_t size = record.data.internalAllocation.size;
533 if (record.type == AllocationCallbackRecord::TYPE_INTERNAL_FREE)
535 if (*totalAllocSizePtr < size)
537 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_NEGATIVE_INTERNAL_ALLOCATION_TOTAL));
538 *totalAllocSizePtr = 0; // Reset to 0 to suppress compound errors
541 *totalAllocSizePtr -= size;
544 *totalAllocSizePtr += size;
547 results->violations.push_back(AllocationCallbackViolation(record, AllocationCallbackViolation::REASON_INVALID_INTERNAL_ALLOCATION_TYPE));
557 DE_ASSERT(!de::contains(ptrToSlotIndex, DE_NULL));
559 // Collect live allocations
560 for (std::vector<AllocationSlot>::const_iterator slotIter = allocations.begin();
561 slotIter != allocations.end();
564 if (slotIter->isLive)
565 results->liveAllocations.push_back(slotIter->record);
569 bool checkAndLog (tcu::TestLog& log, const AllocationCallbackValidationResults& results, deUint32 allowedLiveAllocScopeBits)
575 if (!results.violations.empty())
577 for (size_t violationNdx = 0; violationNdx < results.violations.size(); ++violationNdx)
579 log << TestLog::Message << "VIOLATION " << (violationNdx+1)
580 << ": " << results.violations[violationNdx]
581 << " (" << results.violations[violationNdx].record << ")"
582 << TestLog::EndMessage;
585 log << TestLog::Message << "ERROR: Found " << results.violations.size() << " invalid allocation callbacks!" << TestLog::EndMessage;
588 // Verify live allocations
589 for (size_t liveNdx = 0; liveNdx < results.liveAllocations.size(); ++liveNdx)
591 const AllocationCallbackRecord& record = results.liveAllocations[liveNdx];
592 const VkSystemAllocationScope scope = record.type == AllocationCallbackRecord::TYPE_ALLOCATION ? record.data.allocation.scope
593 : record.type == AllocationCallbackRecord::TYPE_REALLOCATION ? record.data.reallocation.scope
594 : VK_SYSTEM_ALLOCATION_SCOPE_LAST;
596 DE_ASSERT(de::inBounds(scope, (VkSystemAllocationScope)0, VK_SYSTEM_ALLOCATION_SCOPE_LAST));
598 if ((allowedLiveAllocScopeBits & (1u << scope)) == 0)
600 log << TestLog::Message << "LEAK " << (numLeaks+1) << ": " << record << TestLog::EndMessage;
605 // Verify internal allocations
606 for (int internalAllocTypeNdx = 0; internalAllocTypeNdx < VK_INTERNAL_ALLOCATION_TYPE_LAST; ++internalAllocTypeNdx)
608 for (int scopeNdx = 0; scopeNdx < VK_SYSTEM_ALLOCATION_SCOPE_LAST; ++scopeNdx)
610 const VkInternalAllocationType type = (VkInternalAllocationType)internalAllocTypeNdx;
611 const VkSystemAllocationScope scope = (VkSystemAllocationScope)scopeNdx;
612 const size_t totalAllocated = results.internalAllocationTotal[type][scope];
614 if ((allowedLiveAllocScopeBits & (1u << scopeNdx)) == 0 &&
617 log << TestLog::Message << "LEAK " << (numLeaks+1) << ": " << totalAllocated
618 << " bytes of (" << type << ", " << scope << ") internal memory is still allocated"
619 << TestLog::EndMessage;
626 log << TestLog::Message << "ERROR: Found " << numLeaks << " memory leaks!" << TestLog::EndMessage;
628 return results.violations.empty() && numLeaks == 0;
631 bool validateAndLog (tcu::TestLog& log, const AllocationCallbackRecorder& recorder, deUint32 allowedLiveAllocScopeBits)
633 AllocationCallbackValidationResults validationResults;
635 validateAllocationCallbacks(recorder, &validationResults);
637 return checkAndLog(log, validationResults, allowedLiveAllocScopeBits);
640 std::ostream& operator<< (std::ostream& str, const AllocationCallbackRecord& record)
644 case AllocationCallbackRecord::TYPE_ALLOCATION:
645 str << "ALLOCATION: size=" << record.data.allocation.size
646 << ", alignment=" << record.data.allocation.alignment
647 << ", scope=" << record.data.allocation.scope
648 << ", returnedPtr=" << tcu::toHex(record.data.allocation.returnedPtr);
651 case AllocationCallbackRecord::TYPE_REALLOCATION:
652 str << "REALLOCATION: original=" << tcu::toHex(record.data.reallocation.original)
653 << ", size=" << record.data.reallocation.size
654 << ", alignment=" << record.data.reallocation.alignment
655 << ", scope=" << record.data.reallocation.scope
656 << ", returnedPtr=" << tcu::toHex(record.data.reallocation.returnedPtr);
659 case AllocationCallbackRecord::TYPE_FREE:
660 str << "FREE: mem=" << tcu::toHex(record.data.free.mem);
663 case AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION:
664 case AllocationCallbackRecord::TYPE_INTERNAL_FREE:
665 str << "INTERNAL_" << (record.type == AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION ? "ALLOCATION" : "FREE")
666 << ": size=" << record.data.internalAllocation.size
667 << ", type=" << record.data.internalAllocation.type
668 << ", scope=" << record.data.internalAllocation.scope;
678 std::ostream& operator<< (std::ostream& str, const AllocationCallbackViolation& violation)
680 switch (violation.reason)
682 case AllocationCallbackViolation::REASON_DOUBLE_FREE:
684 DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_FREE);
685 str << "Double free of " << tcu::toHex(violation.record.data.free.mem);
689 case AllocationCallbackViolation::REASON_FREE_NOT_ALLOCATED_PTR:
691 DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_FREE);
692 str << "Attempt to free " << tcu::toHex(violation.record.data.free.mem) << " which has not been allocated";
696 case AllocationCallbackViolation::REASON_REALLOC_NOT_ALLOCATED_PTR:
698 DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_REALLOCATION);
699 str << "Attempt to reallocate " << tcu::toHex(violation.record.data.reallocation.original) << " which has not been allocated";
703 case AllocationCallbackViolation::REASON_REALLOC_FREED_PTR:
705 DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_REALLOCATION);
706 str << "Attempt to reallocate " << tcu::toHex(violation.record.data.reallocation.original) << " which has been freed";
710 case AllocationCallbackViolation::REASON_NEGATIVE_INTERNAL_ALLOCATION_TOTAL:
712 DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_INTERNAL_FREE);
713 str << "Internal allocation total for (" << violation.record.data.internalAllocation.type << ", " << violation.record.data.internalAllocation.scope << ") is negative";
717 case AllocationCallbackViolation::REASON_INVALID_INTERNAL_ALLOCATION_TYPE:
719 DE_ASSERT(violation.record.type == AllocationCallbackRecord::TYPE_INTERNAL_ALLOCATION ||
720 violation.record.type == AllocationCallbackRecord::TYPE_INTERNAL_FREE);
721 str << "Invalid internal allocation type " << tcu::toHex(violation.record.data.internalAllocation.type);
725 case AllocationCallbackViolation::REASON_INVALID_ALLOCATION_SCOPE:
727 str << "Invalid allocation scope";
731 case AllocationCallbackViolation::REASON_INVALID_ALIGNMENT:
733 str << "Invalid alignment";
737 case AllocationCallbackViolation::REASON_REALLOC_DIFFERENT_ALIGNMENT:
739 str << "Reallocation with different alignment";