in src/logging_stacktrace.c [50:145]
void getStackAsString(char* destination, size_t destinationSize)
{
/*lazily call once SymInitialize*/
LONG state;
while ((state = InterlockedCompareExchange(&doSymInit, 1, 0)) != 2)
{
if (state == 0)
{
(void)SymInitialize(GetCurrentProcess(), NULL, TRUE);
(void)InterlockedExchange(&doSymInit, 2);
}
}
size_t copied;
/*all following function calls are protected by the same SRW*/
AcquireSRWLockExclusive(&lockOverSymCalls);
uint16_t numberOfFrames = CaptureStackBackTrace(1, TRACE_MAX_STACK_FRAMES, stack, NULL);
if (numberOfFrames == 0)
{
(void)snprintf(destination, destinationSize, "!CaptureStackBackTrace returned 0 frames");
}
else
{
HANDLE process = GetCurrentProcess();
SYMBOL_INFO_EXTENDED symbolExtended;
SYMBOL_INFO* symbol = &symbolExtended.symbol;
symbol->MaxNameLen = TRACE_MAX_SYMBOL_SIZE;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
for (uint16_t j = 0; j < numberOfFrames; j++)
{
DWORD64 address = (DWORD64)(stack[j]);
DWORD displacement = 0;
if (!SymFromAddr(process, address, NULL, symbol))
{
copied = memcat(destination, destinationSize, SymFromAddrFailed, sizeof(SymFromAddrFailed) - 1);
destination += copied;
destinationSize -= copied;
}
else
{
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
char resultLine[TRACE_MAX_STACK_LINE_AS_STRING_SIZE];
if (SymGetLineFromAddr64(process, address, &displacement, &line))
{
int snprintfResult = snprintf(resultLine, sizeof(resultLine), "!%s %s:%" PRIu32 "%s", symbol->Name, line.FileName, (uint32_t)line.LineNumber, (j < numberOfFrames - 1) ? "\n" : "");
if (!(
(snprintfResult >= 0) && /*the returned value is nonnegative [...]*/
(snprintfResult < (int)sizeof(resultLine)) /*[...] and less than n.*/
))
{
copied = memcat(destination, destinationSize, snprintfFailed, sizeof(snprintfFailed) - 1);
destination += copied;
destinationSize -= copied;
}
else
{
copied = memcat(destination, destinationSize, resultLine, snprintfResult);
destination += copied;
destinationSize -= copied;
}
}
else
{
int snprintfResult = snprintf(resultLine, sizeof(resultLine), "!%s Address 0x%" PRIX64 "%s", symbol->Name, line.Address, (j < numberOfFrames - 1) ? "\n" : "");
if (!(
(snprintfResult >= 0) && /*the returned value is nonnegative [...]*/
(snprintfResult < (int)sizeof(resultLine)) /*[...] and less than n.*/
))
{
copied = memcat(destination, destinationSize, snprintfFailed, sizeof(snprintfFailed) - 1);
destination += copied;
destinationSize -= copied;
}
else
{
copied = memcat(destination, destinationSize, resultLine, snprintfResult);
destination += copied;
destinationSize -= copied;
}
}
}
}
destination[-1] = '\0';
}
ReleaseSRWLockExclusive(&lockOverSymCalls);
}