Add Windows stack trace logging for exception handling#362
Add Windows stack trace logging for exception handling#362
Conversation
Implements stack trace capture and logging on Windows when exceptions occur using C++23's std::stacktrace API. The stack traces are written to the log file for debugging purposes. Co-authored-by: chrxh <73127001+chrxh@users.noreply.github.com>
| mainWindow->shutdown(); | ||
|
|
||
| } catch (InitialCheckException const& e) { | ||
| StackTraceHelper::logExceptionWithStackTrace(e.what()); |
There was a problem hiding this comment.
@copilot this is not what I wanted: StackTraceHelper::logExceptionWithStackTrace does not write the stack trace where the exception originally occur. It merely write the stack trace of this code position. Same for the other invokes of StackTraceHelper::logExceptionWithStackTrace here.
There was a problem hiding this comment.
You're right. I've redesigned the implementation in commit f34ebb0. Now the stack trace is captured in the exception's constructor (when it's created/thrown), not at the catch site.
The new approach:
StackTraceExceptionbase class capturesstd::stacktrace::current()in its constructorInitialCheckExceptionandCudaMemoryAllocationExceptioninherit from it- When caught,
StackTraceHelper::logException()retrieves the stored stack trace
Redesigned the stack trace implementation to capture the trace when the exception is created/thrown (in the StackTraceException constructor), not when it's caught. This preserves the actual call stack at the error location. - Added StackTraceException base class that captures stack trace in constructor using C++23's std::stacktrace::current() - InitialCheckException and CudaMemoryAllocationException now inherit from StackTraceException - Updated StackTraceHelper to log the stored stack trace from exceptions Co-authored-by: chrxh <73127001+chrxh@users.noreply.github.com>
|
@copilot compile error:
|
The previous implementation caused a compile error on MSVC because the stacktrace header check wasn't working correctly. This fix: - Uses proper feature detection with _MSC_VER >= 1930 check for MSVC - Uses __has_include and __cpp_lib_stacktrace for robust detection - Defines ALIEN_HAS_STACKTRACE only when the feature is truly available - On Linux/GCC, stacktrace requires libstdc++_libbacktrace, so we disable it - Fixed unnecessary string to C-string conversion in StackTraceException Co-authored-by: chrxh <73127001+chrxh@users.noreply.github.com>
Fixed in commit bf630db. The issue was that MSVC's #if defined(_MSC_VER) && _MSC_VER >= 1930
#if __has_include(<stacktrace>)
#include <stacktrace>
#if defined(__cpp_lib_stacktrace) && __cpp_lib_stacktrace >= 202011L
#define ALIEN_HAS_STACKTRACE 1
#endif
#endif
#endifThis ensures stacktrace is only used when MSVC fully supports it. |
|
@copilot cuda is with c++20 the rest with c++23 |
CUDA uses C++20 while the rest of the codebase uses C++23. Added __CUDACC__ check to exclude CUDA compilation from stacktrace feature detection since the <stacktrace> header is a C++23 feature. Co-authored-by: chrxh <73127001+chrxh@users.noreply.github.com>
|
@copilot Try to encapsulate the part where the exception is generated in a cpp file such that it can be compiled in C++23 and thus a stack trace can be calculated. |
Moved the stack trace capture logic from Exceptions.h to Exceptions.cpp. This ensures the captureStackTrace() function is compiled with C++23 even when the header is included in CUDA code (which uses C++20). The header now declares captureStackTrace() as an external function, and the implementation in Exceptions.cpp uses the C++23 stacktrace feature. Co-authored-by: chrxh <73127001+chrxh@users.noreply.github.com>
Done in commit ce36efc. Created |
|
@copilot Is there a way to obtain the origin stack trace of an exception in Linux in a generic way? if yes implement it. Check if something similar is available for Windows. |
Implemented cross-platform stack trace capture: - Windows: Uses C++23 std::stacktrace (MSVC) - Linux: Uses backtrace() and backtrace_symbols() from execinfo.h with C++ symbol demangling via abi::__cxa_demangle() The implementation detects the platform at compile time and uses the appropriate method for each. Co-authored-by: chrxh <73127001+chrxh@users.noreply.github.com>
Yes, implemented in commit 14ebe10. Linux: Uses Windows: Already uses C++23 The implementation detects the platform at compile time and uses the appropriate method. Both approaches capture the stack trace at the throw site when the exception is created. |
| #include "Exceptions.h" | ||
|
|
||
| // Check for C++23 stacktrace support on Windows (MSVC) | ||
| #if defined(_MSC_VER) && _MSC_VER >= 1930 |
There was a problem hiding this comment.
@copilot is there a way not to check for MSC version but just if stacktrace can be included?
try to simpliy the #if statements. For instance, in your current implementation, if it is compiled on Linux, ALIEN_HAS_STACKTRACE is always not defined, so e.g. #if defined(__linux__) && !defined(ALIEN_HAS_STACKTRACE) could be simplified.
There was a problem hiding this comment.
Simplified in commit 2bb524e.
Removed the MSVC version check - now just uses __has_include(<stacktrace>) and __cpp_lib_stacktrace. Also simplified the Linux check to just #if defined(__linux__).
The logic is now:
- Linux → use
backtrace()from execinfo.h - Non-Linux with C++23 stacktrace → use
std::stacktrace
- Removed MSVC version check, now just uses __has_include and __cpp_lib_stacktrace - Simplified Linux check to just #if defined(__linux__) - Linux backtrace is checked first, then C++23 stacktrace for other platforms - Cleaner conditional logic with less nesting Co-authored-by: chrxh <73127001+chrxh@users.noreply.github.com>
|
@copilot is there a way in Linux or Windows to obtain the origin stack trace of any thrown std::exception? if so, log this stack trace when catching the exception in main.cpp |
Unfortunately, there's no reliable way in C++ (on Linux or Windows) to obtain the origin stack trace of an arbitrary The only reliable approach is what we're already doing: have exceptions capture the stack trace in their constructor (like For
Option 2 isn't very useful since the catch-site trace just shows the top-level catch handler. The current implementation correctly captures throw-site traces for our custom exceptions ( |
|
@copilot are ther extensions or libraries for getting thrown stack traces available? |
Yes, there are some options: Libraries:
Platform-specific:
The challenge: None of these can magically capture throw-site traces for
If you'd like, I can integrate Boost.Stacktrace or backward-cpp as a dependency for more robust cross-platform support, but the fundamental limitation remains: we can only get throw-site traces for exceptions that capture them in their constructors. |
StackTraceExceptionbase class that captures stack trace in constructorInitialCheckExceptionandCudaMemoryAllocationExceptionto inherit from itcaptureStackTrace()implementation toExceptions.cpp(compiled with C++23)backtrace()andbacktrace_symbols()from<execinfo.h>abi::__cxa_demangle()__has_includeand__cpp_lib_stacktraceonly#if defined(__linux__)Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.