This project has moved. For the latest updates, please go here.

How about dump Block id Descending just as _crtDumpMemoryLeaks

Sep 6, 2011 at 4:36 PM
Edited Sep 6, 2011 at 4:42 PM

Hi! 

We know a top Block id memory leak may cause a lot of sub Block leaks, so when use _crtDumpMemoryLeaks we always move to the bottom of output window, fixed the top Block id, and test again. but VLD dump memory leak not Descending so it is hard find the top one. 

Sep 7, 2011 at 8:01 AM
Edited Sep 7, 2011 at 8:03 AM

It can be  geted by few modify, wish the author can take it.


bool pred_blockmapit(const BlockMap::Iterator& it1,const BlockMap::Iterator& it2)
{
	blockinfo_t* info1 = (*it1).second;
	blockinfo_t* info2 = (*it2).second;
	return info1->serialNumber > info2->serialNumber;
}

SIZE_T VisualLeakDetector::reportLeaks (heapinfo_t* heapinfo, Set<blockinfo_t*> &aggregatedLeaks)
{
    BlockMap* blockmap   = &heapinfo->blockMap;
    SIZE_T leaksFound = 0;
    bool firstLeak = true;

    const int MAX_BLOCKS = 256;
    int blockNum = 0;
    BlockMap::Iterator its[MAX_BLOCKS];

    for (BlockMap::Iterator blockit = blockmap->begin(); blockit != blockmap->end(); ++blockit)
    {
        // Found a block which is still in the BlockMap. We've identified a
        // potential memory leak.
        LPCVOID block = (*blockit).first;
        blockinfo_t* info = (*blockit).second;
        if (info->reported)
            continue;

        Set<blockinfo_t*>::Iterator it = aggregatedLeaks.find(info);
        if (it != aggregatedLeaks.end())
            continue;

	its[blockNum++] = blockit;
	if (blockNum == MAX_BLOCKS)
	    break;
    }

    std::sort(its,its+blockNum,pred_blockmapit);
    for (int i=0; i<blockNum; i++)
    {
 	BlockMap::Iterator blockit = its[i];
	LPCVOID block = (*blockit).first;
	blockinfo_t* info = (*blockit).second;

        LPCVOID address = block;
        SIZE_T size = info->size;

        if (heapinfo->flags & VLD_HEAP_CRT_DBG) {
            // This block is allocated to a CRT heap, so the block has a CRT
            // memory block header pretended to it.
            crtdbgblockheader_t* crtheader = (crtdbgblockheader_t*)block;
            if (CRT_USE_TYPE(crtheader->use) == CRT_USE_IGNORE ||
                CRT_USE_TYPE(crtheader->use) == CRT_USE_FREE ||
                CRT_USE_TYPE(crtheader->use) == CRT_USE_INTERNAL)
            {
                // This block is marked as being used internally by the CRT.
                // The CRT will free the block after VLD is destroyed.
                continue;
            }
            // The CRT header is more or less transparent to the user, so
            // the information about the contained block will probably be
            // more useful to the user. Accordingly, that's the information
            // we'll include in the report.
            address = CRTDBGBLOCKDATA(block);
            size = crtheader->size;
        }

        // It looks like a real memory leak.
        if (firstLeak) { // A confusing way to only display this message once
            Report(L"WARNING: Visual Leak Detector detected memory leaks %d!\n", blockNum);
            firstLeak = false;
        }
        leaksFound++;
        Report(L"---------- Block %ld at " ADDRESSFORMAT L": %u bytes ----------\n", info->serialNumber, address, size);
        assert(info->callStack);
        if (m_options & VLD_OPT_AGGREGATE_DUPLICATES) {
            // Aggregate all other leaks which are duplicates of this one
            // under this same heading, to cut down on clutter.
            SIZE_T erased = eraseDuplicates(blockit, aggregatedLeaks);

            // add only the number that were erased, since the 'one left over'
            // is already recorded as a leak
            leaksFound += erased;

            DWORD callstackCRC = 0;
            if (info->callStack)
                callstackCRC = CalculateCRC32(info->size, info->callStack->getHashValue());
            Report(L"Leak Hash: 0x%08X Count: %Iu\n", callstackCRC, erased + 1);
        }
        // Dump the call stack.
        Report(L"  Call Stack:\n");
        if (info->callStack)
            info->callStack->dump(m_options & VLD_OPT_TRACE_INTERNAL_FRAMES);

        // Dump the data in the user data section of the memory block.
        if (m_maxDataDump != 0) {
            Report(L"  Data:\n");
            if (m_options & VLD_OPT_UNICODE_REPORT) {
                DumpMemoryW(address, (m_maxDataDump < size) ? m_maxDataDump : size);
            }
            else {
                DumpMemoryA(address, (m_maxDataDump < size) ? m_maxDataDump : size);
            }
        }
        Report(L"\n\n");
    }

    return leaksFound;
}

Sep 11, 2011 at 5:38 AM

there is bug prev post.

bool pred_blockmapit(const BlockMap::Iterator& it1,const BlockMap::Iterator& it2)
{
	blockinfo_t* info1 = (*it1).second;
	blockinfo_t* info2 = (*it2).second;
	return info1->serialNumber > info2->serialNumber;
}

SIZE_T VisualLeakDetector::reportLeaks (heapinfo_t* heapinfo, Set<blockinfo_t*> &aggregatedLeaks)
{
	BlockMap* blockmap   = &heapinfo->blockMap;
	SIZE_T leaksFound = 0;
	bool firstLeak = true;

	const int MAX_BLOCKS = 256*256;
	BlockMap::Iterator its[MAX_BLOCKS];
	int blockNum = 0;

	for (BlockMap::Iterator blockit = blockmap->begin(); blockit != blockmap->end(); ++blockit)
	{
		// Found a block which is still in the BlockMap. We've identified a
		// potential memory leak.
		LPCVOID block = (*blockit).first;
		blockinfo_t* info = (*blockit).second;

		its[blockNum++] = blockit;
		if (blockNum == MAX_BLOCKS)
			break;
	}

	std::sort(its,its+blockNum,pred_blockmapit);
	for (int i=0; i<blockNum; i++)
	{
		BlockMap::Iterator blockit = its[i];
		LPCVOID block = (*blockit).first;
		blockinfo_t* info = (*blockit).second;

		if (info->reported)
			continue;

		Set<blockinfo_t*>::Iterator it = aggregatedLeaks.find(info);
		if (it != aggregatedLeaks.end())
			continue;
...