Commit 560d2dc4 authored by Brad King's avatar Brad King Committed by Kitware Robot
Browse files

Merge topic 'SystemInformation-windows-backtrace'

43c6e2fd

 SystemInformation: Implement backtrace support on Windows
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !140
parents c42b92f0 43c6e2fd
......@@ -894,6 +894,11 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
IF(KWSYS_USE_SystemInformation)
IF(WIN32)
TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32)
# link in dbghelp.dll for symbol lookup if MSVC 1800 or later
# Note that the dbghelp runtime is part of MS Windows OS
IF(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)
TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} dbghelp)
ENDIF()
IF(KWSYS_SYS_HAS_PSAPI)
TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
Psapi)
......
......@@ -2,6 +2,9 @@
file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
#if defined(_WIN32)
# define NOMINMAX // use our min,max
# if !defined(_WIN32_WINNT) && defined(_MSC_VER) && _MSC_VER >= 1800
# define _WIN32_WINNT 0x0600 // vista
# endif
# if !defined(_WIN32_WINNT) && !(defined(_MSC_VER) && _MSC_VER < 1300)
# define _WIN32_WINNT 0x0501
# endif
......@@ -3879,6 +3882,20 @@ SystemInformation::LongLong SystemInformationImplementation::GetProcessId()
#endif
}
/**
* Used in GetProgramStack(...) below
*/
#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 && defined(_MSC_VER) && \
_MSC_VER >= 1800
# define KWSYS_SYSTEMINFORMATION_HAS_DBGHELP
# define TRACE_MAX_STACK_FRAMES 1024
# define TRACE_MAX_FUNCTION_NAME_LENGTH 1024
# pragma warning(push)
# pragma warning(disable : 4091) /* 'typedef ': ignored on left of '' */
# include "dbghelp.h"
# pragma warning(pop)
#endif
/**
return current program stack in a string
demangle cxx symbols if possible.
......@@ -3886,28 +3903,58 @@ demangle cxx symbols if possible.
std::string SystemInformationImplementation::GetProgramStack(int firstFrame,
int wholePath)
{
std::string programStack = ""
#if !defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
"WARNING: The stack could not be examined "
"because backtrace is not supported.\n"
#elif !defined(KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD)
"WARNING: The stack trace will not use advanced "
"capabilities because this is a release build.\n"
std::ostringstream oss;
std::string programStack = "";
#ifdef KWSYS_SYSTEMINFORMATION_HAS_DBGHELP
(void)wholePath;
void* stack[TRACE_MAX_STACK_FRAMES];
HANDLE process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
WORD numberOfFrames =
CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, NULL);
SYMBOL_INFO* symbol = static_cast<SYMBOL_INFO*>(
malloc(sizeof(SYMBOL_INFO) +
(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)));
symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
DWORD displacement;
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
for (int i = 0; i < numberOfFrames; i++) {
DWORD64 address = reinterpret_cast<DWORD64>(stack[i]);
SymFromAddr(process, address, NULL, symbol);
if (SymGetLineFromAddr64(process, address, &displacement, &line)) {
oss << " at " << symbol->Name << " in " << line.FileName << " line "
<< line.LineNumber << std::endl;
} else {
oss << " at " << symbol->Name << std::endl;
}
}
free(symbol);
#else
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
"WARNING: Function names will not be demangled "
"because "
"dladdr is not available.\n"
# endif
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
"WARNING: Function names will not be demangled "
"because cxxabi is not available.\n"
programStack += ""
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
"WARNING: The stack could not be examined "
"because backtrace is not supported.\n"
# elif !defined(KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD)
"WARNING: The stack trace will not use advanced "
"capabilities because this is a release build.\n"
# else
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP)
"WARNING: Function names will not be demangled "
"because dladdr is not available.\n"
# endif
# if !defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
"WARNING: Function names will not be demangled "
"because cxxabi is not available.\n"
# endif
# endif
#endif
;
std::ostringstream oss;
#if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
# if defined(KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE)
void* stackSymbols[256];
int nFrames = backtrace(stackSymbols, 256);
for (int i = firstFrame; i < nFrames; ++i) {
......@@ -3916,10 +3963,12 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame,
symProps.Initialize(stackSymbols[i]);
oss << symProps << std::endl;
}
#else
# else
(void)firstFrame;
(void)wholePath;
# endif
#endif
programStack += oss.str();
return programStack;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment