Exemplo n.º 1
0
CallStack* CallStack::Create()
{
    CallStack* result = NULL;
    if (g_vld.GetOptions() & VLD_OPT_SAFE_STACK_WALK) {
        result = new SafeCallStack();
    }
    else {
        result = new FastCallStack();
    }
    return result;
}
Exemplo n.º 2
0
__declspec(dllexport) UINT VLDReportLeaks ()
{
    return (UINT)g_vld.ReportLeaks();
}
Exemplo n.º 3
0
__declspec(dllexport) void VLDGlobalEnable ()
{
    g_vld.GlobalEnableLeakDetection();
}
Exemplo n.º 4
0
__declspec(dllexport) void VLDRestore ()
{
    g_vld.RestoreLeakDetectionState();
}
Exemplo n.º 5
0
__declspec(dllexport) void VLDDisable ()
{
    g_vld.DisableLeakDetection();
}
Exemplo n.º 6
0
__declspec(dllexport) UINT VLDGetThreadLeaksCount (UINT threadId)
{
    return (UINT)g_vld.GetThreadLeaksCount(threadId);
}
Exemplo n.º 7
0
__declspec(dllexport) UINT VLDGetOptions()
{
    return g_vld.GetOptions();
}
Exemplo n.º 8
0
__declspec(dllexport) void VLDRefreshModules()
{
    g_vld.RefreshModules();
}
Exemplo n.º 9
0
__declspec(dllexport) void VLDSetModulesList(CONST WCHAR *modules, BOOL includeModules)
{
    g_vld.SetModulesList(modules, includeModules);
}
Exemplo n.º 10
0
__declspec(dllexport) int VLDSetReportHook(int mode,  VLD_REPORT_HOOK pfnNewHook)
{
    return g_vld.SetReportHook(mode, pfnNewHook);
}
Exemplo n.º 11
0
__declspec(dllexport) void VLDSetOptions(UINT option_mask, SIZE_T maxDataDump, UINT maxTraceFrames)
{
    g_vld.SetOptions(option_mask, maxDataDump, maxTraceFrames);
}
Exemplo n.º 12
0
// Resolve - Creates a nicely formatted rendition of the CallStack, including
//   symbolic information (function names and line numbers) if available. and
//   saves it for later retrieval. This is almost identical to Callstack::dump above.
//
//   Note: The symbol handler must be initialized prior to calling this
//     function.
//
//  - showInternalFrames (IN): If true, then all frames in the CallStack will be
//      dumped. Otherwise, frames internal to the heap will not be dumped.
//
//  Return Value:
//
//    None.
//
int CallStack::resolve(BOOL showInternalFrames)
{
    if (m_resolved)
    {
        // already resolved, no need to do it again
        // resolving twice may report an incorrect module for the stack frames
        // if the memory was leaked in a dynamic library that was already unloaded.
        return 0;
    }

    if (m_status & CALLSTACK_STATUS_STARTUPCRT) {
        // there is no need to resolve a leak that will not be reported
        return 0;
    }

    if (m_status & CALLSTACK_STATUS_INCOMPLETE) {
        // This call stack appears to be incomplete. Using StackWalk64 may be
        // more reliable.
        Report(L"    HINT: The following call stack may be incomplete. Setting \"StackWalkMethod\"\n"
            L"      in the vld.ini file to \"safe\" instead of \"fast\" may result in a more\n"
            L"      complete stack trace.\n");
    }

    int unresolvedFunctionsCount = 0;
    IMAGEHLP_LINE64  sourceInfo = { 0 };
    sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

    bool skipStartupLeaks = !!(g_vld.GetOptions() & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);

    // Use static here to increase performance, and avoid heap allocs.
    // It's thread safe because of g_heapMapLock lock.
    static WCHAR stack_line[MAXREPORTLENGTH + 1] = L"";
    bool isPrevFrameInternal = false;
    bool isDynamicInitializer = false;
    DWORD NumChars = 0;
    CriticalSectionLocker<DbgHelp> locker(g_DbgHelp);

    const size_t max_line_length = MAXREPORTLENGTH + 1;
    m_resolvedCapacity = m_size * max_line_length;
    const size_t allocedBytes = m_resolvedCapacity * sizeof(WCHAR);
    m_resolved = new WCHAR[m_resolvedCapacity];
    if (m_resolved) {
        ZeroMemory(m_resolved, allocedBytes);
    }

    // Iterate through each frame in the call stack.
    for (UINT32 frame = 0; frame < m_size; frame++)
    {
        // Try to get the source file and line number associated with
        // this program counter address.
        SIZE_T programCounter = (*this)[frame];
        DWORD            displacement = 0;

        // It turns out that calls to SymGetLineFromAddrW64 may free the very memory we are scrutinizing here
        // in this method. If this is the case, m_Resolved will be null after SymGetLineFromAddrW64 returns.
        // When that happens there is nothing we can do except crash.
        DbgTrace(L"dbghelp32.dll %i: SymGetLineFromAddrW64\n", GetCurrentThreadId());
        BOOL foundline = g_DbgHelp.SymGetLineFromAddrW64(g_currentProcess, programCounter, &displacement, &sourceInfo, locker);

        if (skipStartupLeaks && foundline && !isDynamicInitializer &&
            !(m_status & CALLSTACK_STATUS_NOTSTARTUPCRT) && isCrtStartupModule(sourceInfo.FileName)) {
            m_status |= CALLSTACK_STATUS_STARTUPCRT;
            delete[] m_resolved;
            m_resolved = NULL;
            m_resolvedCapacity = 0;
            m_resolvedLength = 0;
            return 0;
        }

        bool isFrameInternal = false;
        if (foundline && !showInternalFrames) {
            if (isInternalModule(sourceInfo.FileName)) {
                // Don't show frames in files internal to the heap.
                isFrameInternal = true;
            }
        }

        // show one allocation function for context
        if (NumChars > 0 && !isFrameInternal && isPrevFrameInternal) {
            m_resolvedLength += NumChars;
            if (m_resolved) {
                wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars);
            }
        }
        isPrevFrameInternal = isFrameInternal;

        DWORD64 displacement64;
        BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_SYMBOL_NAME_SIZE];
        LPCWSTR functionName = getFunctionName(programCounter, displacement64, (SYMBOL_INFO*)&symbolBuffer, locker);

        if (skipStartupLeaks && foundline && beginWith(functionName, wcslen(functionName), L"`dynamic initializer for '")) {
            isDynamicInitializer = true;
        }

        if (!foundline)
            displacement = (DWORD)displacement64;
        NumChars = resolveFunction( programCounter, foundline ? &sourceInfo : NULL,
            displacement, functionName, stack_line, _countof( stack_line ));

        if (NumChars > 0 && !isFrameInternal) {
            m_resolvedLength += NumChars;
            if (m_resolved) {
                wcsncat_s(m_resolved, m_resolvedCapacity, stack_line, NumChars);
            }
        }
    } // end for loop

    m_status |= CALLSTACK_STATUS_NOTSTARTUPCRT;
    return unresolvedFunctionsCount;
}
Exemplo n.º 13
0
__declspec(dllexport) void VLDMarkThreadLeaksAsReported (UINT threadId)
{
    g_vld.MarkThreadLeaksAsReported(threadId);
}
Exemplo n.º 14
0
__declspec(dllexport) UINT VLDGetLeaksCount ()
{
    return (UINT)g_vld.GetLeaksCount();
}
Exemplo n.º 15
0
__declspec(dllexport) BOOL VLDGetModulesList(WCHAR *modules, UINT size)
{
    return g_vld.GetModulesList(modules, size);
}
Exemplo n.º 16
0
__declspec(dllexport) void VLDMarkAllLeaksAsReported ()
{
    g_vld.MarkAllLeaksAsReported();
}
Exemplo n.º 17
0
__declspec(dllexport) void VLDSetReportOptions(UINT option_mask, CONST WCHAR *filename)
{
    g_vld.SetReportOptions(option_mask,filename);
}
Exemplo n.º 18
0
__declspec(dllexport) void VLDDisableModule(HMODULE module)
{
    g_vld.DisableModule(module);
}
Exemplo n.º 19
0
__declspec(dllexport) void VLDResolveCallstacks()
{
    g_vld.ResolveCallstacks();
}
Exemplo n.º 20
0
__declspec(dllexport) void VLDGetReportFilename(WCHAR *filename)
{
    g_vld.GetReportFilename(filename);
}
Exemplo n.º 21
0
__declspec(dllexport) UINT VLDReportThreadLeaks (UINT threadId)
{
    return (UINT)g_vld.ReportThreadLeaks(threadId);
}