Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes and enhancements around logfile usage #27

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/callstack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ CallStack::~CallStack ()
m_resolvedLength = 0;
}

CallStack* CallStack::Create()
CallStack* CallStack::Create(BOOL safe_stack_walk)
{
CallStack* result = NULL;
if (g_vld.GetOptions() & VLD_OPT_SAFE_STACK_WALK) {
if (safe_stack_walk) {
result = new SafeCallStack();
}
else {
Expand Down Expand Up @@ -330,10 +330,10 @@ bool CallStack::isCrtStartupAlloc()
//
// None.
//
void CallStack::dump(BOOL showInternalFrames)
void CallStack::dump(BOOL showInternalFrames, BOOL skipStartupLeaks)
{
if (!m_resolved) {
resolve(showInternalFrames);
resolve(showInternalFrames, skipStartupLeaks);
}

// The stack was reoslved already
Expand All @@ -356,7 +356,7 @@ void CallStack::dump(BOOL showInternalFrames)
//
// None.
//
int CallStack::resolve(BOOL showInternalFrames)
int CallStack::resolve(BOOL showInternalFrames, BOOL skipStartupLeaks)
{
if (m_resolved)
{
Expand All @@ -383,7 +383,7 @@ int CallStack::resolve(BOOL showInternalFrames)
IMAGEHLP_LINE64 sourceInfo = { 0 };
sourceInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

bool skipStartupLeaks = !!(g_vld.GetOptions() & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);
//bool skipStartupLeaks = !!(g_vld.GetOptions() & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);
rglarix marked this conversation as resolved.
Show resolved Hide resolved

// Use static here to increase performance, and avoid heap allocs.
// It's thread safe because of g_heapMapLock lock.
Expand Down Expand Up @@ -467,9 +467,9 @@ int CallStack::resolve(BOOL showInternalFrames)
return unresolvedFunctionsCount;
}

const WCHAR* CallStack::getResolvedCallstack( BOOL showinternalframes )
const WCHAR* CallStack::getResolvedCallstack( BOOL showinternalframes, BOOL skipStartupLeaks)
{
resolve(showinternalframes);
resolve(showinternalframes, skipStartupLeaks);
return m_resolved;
}

Expand Down
8 changes: 4 additions & 4 deletions src/callstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ class CallStack
public:
CallStack ();
virtual ~CallStack ();
static CallStack* Create();
static CallStack* Create(BOOL safe_stack_walk);
// Public APIs - see each function definition for details.
VOID clear ();
// Prints the call stack to one of either / or the debug output window and or
// a log file.
VOID dump (BOOL showinternalframes);
VOID dump (BOOL showinternalframes, BOOL skipStartupLeaks);
// Formats the stack frame into a human readable format, and saves it for later retrieval.
int resolve(BOOL showinternalframes);
int resolve(BOOL showinternalframes, BOOL skipStartupLeaks);
// Formats the stack frame into a human readable format, and saves it for later retrieval.
CONST WCHAR* getResolvedCallstack(BOOL showinternalframes);
CONST WCHAR* getResolvedCallstack(BOOL showinternalframes, BOOL skipStartupLeaks);
virtual DWORD getHashValue() const = 0;
virtual VOID getStackTrace (UINT32 maxdepth, const context_t& context) = 0;
bool isCrtStartupAlloc();
Expand Down
42 changes: 18 additions & 24 deletions src/vld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ VisualLeakDetector::VisualLeakDetector ()
m_reportFile = NULL;
wcsncpy_s(m_reportFilePath, MAX_PATH, VLD_DEFAULT_REPORT_FILE_NAME, _TRUNCATE);
m_status = 0x0;
m_optionsLock.Initialize();

HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
if (ntdll)
Expand Down Expand Up @@ -420,7 +421,6 @@ VisualLeakDetector::VisualLeakDetector ()
m_curAlloc = 0;
m_maxAlloc = 0;
m_loadedModules = new ModuleSet();
m_optionsLock.Initialize();
m_modulesLock.Initialize();
m_selfTestFile = __FILE__;
m_selfTestLine = 0;
Expand Down Expand Up @@ -1346,8 +1346,6 @@ tls_t* VisualLeakDetector::getTls ()
//
VOID VisualLeakDetector::mapBlock (HANDLE heap, LPCVOID mem, SIZE_T size, bool debugcrtalloc, bool ucrt, DWORD threadId, blockinfo_t* &pblockInfo)
{
CriticalSectionLocker<> cs(g_heapMapLock);

// Record the block's information.
blockinfo_t* blockinfo = new blockinfo_t();
blockinfo->callStack = NULL;
Expand Down Expand Up @@ -1472,15 +1470,15 @@ VOID VisualLeakDetector::unmapBlock (HANDLE heap, LPCVOID mem, const context_t &
Report(L"---------- Block %Iu at " ADDRESSFORMAT L": %Iu bytes ----------\n", alloc_block->serialNumber, mem, alloc_block->size);
Report(L" TID: %u\n", alloc_block->threadId);
Report(L" Call Stack:\n");
alloc_block->callStack->dump(m_options & VLD_OPT_TRACE_INTERNAL_FRAMES);
alloc_block->callStack->dump(m_options & VLD_OPT_TRACE_INTERNAL_FRAMES, m_options & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);

// Now we need a way to print the current callstack at this point:
CallStack* stack_here = CallStack::Create();
CallStack* stack_here = CallStack::Create(m_options & VLD_OPT_SAFE_STACK_WALK);
stack_here->getStackTrace(m_maxTraceFrames, context);
Report(L"Deallocation Call stack.\n");
Report(L"---------- Block %Iu at " ADDRESSFORMAT L": %Iu bytes ----------\n", alloc_block->serialNumber, mem, alloc_block->size);
Report(L" Call Stack:\n");
stack_here->dump(FALSE);
stack_here->dump(FALSE, m_options & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);
// Now it should be safe to delete our temporary callstack
delete stack_here;
stack_here = NULL;
Expand Down Expand Up @@ -1562,8 +1560,6 @@ VOID VisualLeakDetector::unmapHeap (HANDLE heap)
VOID VisualLeakDetector::remapBlock (HANDLE heap, LPCVOID mem, LPCVOID newmem, SIZE_T size,
bool debugcrtalloc, bool ucrt, DWORD threadId, blockinfo_t* &pblockInfo, const context_t &context)
{
CriticalSectionLocker<> cs(g_heapMapLock);

if (newmem != mem) {
// The block was not reallocated in-place. Instead the old block was
// freed and a new block allocated to satisfy the new size.
Expand Down Expand Up @@ -1913,7 +1909,7 @@ SIZE_T VisualLeakDetector::reportLeaks (heapinfo_t* heapinfo, bool &firstLeak, S
else
Report(L" Call Stack:\n");
if (info->callStack)
info->callStack->dump(m_options & VLD_OPT_TRACE_INTERNAL_FRAMES);
info->callStack->dump(m_options & VLD_OPT_TRACE_INTERNAL_FRAMES, m_options & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);

// Dump the data in the user data section of the memory block.
if (m_maxDataDump != 0) {
Expand Down Expand Up @@ -2709,6 +2705,7 @@ void VisualLeakDetector::SetReportOptions(UINT32 option_mask, CONST WCHAR *filen
else if ( m_reportFile ) { //Close the previous report file if needed.
fclose(m_reportFile);
m_reportFile = NULL;
SetReportFile(m_reportFile, m_options & VLD_OPT_REPORT_TO_DEBUGGER, m_options & VLD_OPT_REPORT_TO_STDOUT);
}
}

Expand Down Expand Up @@ -2747,22 +2744,16 @@ void VisualLeakDetector::setupReporting()
// Unicode data encoding has been enabled. Write the byte-order
// mark before anything else gets written to the file. Open the
// file for binary writing.
if (_wfopen_s(&m_reportFile, m_reportFilePath, L"wb") == EINVAL) {
// Couldn't open the file.
m_reportFile = NULL;
}
else if (m_reportFile) {
m_reportFile = _wfsopen(m_reportFilePath, L"wb", _SH_DENYWR);
if (m_reportFile) {
fwrite(&bom, sizeof(WCHAR), 1, m_reportFile);
SetReportEncoding(unicode);
}
}
else {
// Open the file in text mode for ASCII output.
if (_wfopen_s(&m_reportFile, m_reportFilePath, L"w") == EINVAL) {
// Couldn't open the file.
m_reportFile = NULL;
}
else if (m_reportFile) {
m_reportFile = _wfsopen(m_reportFilePath, L"w", _SH_DENYWR);
if (m_reportFile) {
SetReportEncoding(ascii);
}
}
Expand Down Expand Up @@ -2818,9 +2809,9 @@ const wchar_t* VisualLeakDetector::GetAllocationResolveResults(void* alloc, BOOL
blockinfo_t* info = getAllocationBlockInfo(alloc);
if (info != NULL)
{
int unresolvedFunctionsCount = info->callStack->resolve(showInternalFrames);
int unresolvedFunctionsCount = info->callStack->resolve(showInternalFrames, m_options & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);
_ASSERT(unresolvedFunctionsCount == 0);
return info->callStack->getResolvedCallstack(showInternalFrames);
return info->callStack->getResolvedCallstack(showInternalFrames, m_options & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);
}
return NULL;
}
Expand Down Expand Up @@ -2870,7 +2861,7 @@ int VisualLeakDetector::resolveStacks(heapinfo_t* heapinfo)
// Dump the call stack.
if (info->callStack)
{
unresolvedFunctionsCount += info->callStack->resolve(m_options & VLD_OPT_TRACE_INTERNAL_FRAMES);
unresolvedFunctionsCount += info->callStack->resolve(m_options & VLD_OPT_TRACE_INTERNAL_FRAMES, m_options & VLD_OPT_SKIP_CRTSTARTUP_LEAKS);
if ((m_options & VLD_OPT_SKIP_CRTSTARTUP_LEAKS) && info->callStack->isCrtStartupAlloc()) {
info->reported = true;
continue;
Expand Down Expand Up @@ -2925,6 +2916,11 @@ CaptureContext::~CaptureContext() {
return;

if ((m_tls->blockWithoutGuard) && (!IsExcludedModule())) {
CallStack* callstack = CallStack::Create(g_vld.m_options & VLD_OPT_SAFE_STACK_WALK);
callstack->getStackTrace(g_vld.m_maxTraceFrames, m_tls->context);

CriticalSectionLocker<> cs(g_heapMapLock);

blockinfo_t* pblockInfo = NULL;
if (m_tls->newBlockWithoutGuard == NULL) {
g_vld.mapBlock(m_tls->heap,
Expand All @@ -2946,8 +2942,6 @@ CaptureContext::~CaptureContext() {
pblockInfo, m_tls->context);
}

CallStack* callstack = CallStack::Create();
callstack->getStackTrace(g_vld.m_maxTraceFrames, m_tls->context);
pblockInfo->callStack.reset(callstack);
}

Expand Down