A cross-platform library for simple callstack tracing with C89 and C++03 public APIs.
Requires a C++11 compiler to build.
License: Apache 2.0
- Fancy assertion or logging macros
- Automatic tracing for bug database submission (JIRA, Sentry.IO, etc.)
- Stack traces for leaked allocations or refcounting
Tested OS | Compiler | SDK | Unwind Impl | Symbols Impl |
---|---|---|---|---|
Windows 7 | VS2015 u1 | DbgHelp | DbgHelp | |
Android 5.0 | GCC 4.9 | nVidia Codeworks 1R4 | libunwind | Custom elf/dwarf parser |
Android 5.0 | Clang 3.6 | Microsoft's Android SDK | __builtin_return_address | Custom elf/dwarf parser |
Ubuntu 16.10 | Clang 3.8.1 | None (noop/fallback) | None | |
Ubuntu 16.10 | GCC 6.2.0 | None (noop/fallback) | None |
Other C++11 capable platforms/compilers should at least be able to use the Fallback implementation, feel free to file an issue if they don't!
#include <mmk/debug/stack.h> // mmkDebugStackCurrentThread etc.
#include <stdio.h> // printf
#include <string.h>
#define NO_INLINE ZMMK_DEBUG_STACK_NO_INLINE // Note: ZMMK_* isn't part of the public API
const char* nameOnly(const char* filename) {
if (const char* bs = strrchr(filename, '\\')) return bs+1;
if (const char* fs = strrchr(filename, '/')) return fs+1;
return filename;
}
#define TRACE() (void)(printf("Trace:\n"), mmk::debug::stackCurrentThread(mmkDebugStackResolveAll, 0, 25, \
[](const mmk::debug::stackFunction& f) { \
printf(" %s(%d): %s @ %p\n", nameOnly(f.file), f.line, f.name, f.address); \
return true; /* continue trace */ \
}, MMK_DEBUG_STACK_HINT()), printf("\n\n\n"), 0)
NO_INLINE void test_trace() { TRACE(); }
template < size_t N > struct recursive { NO_INLINE static void test_trace() { recursive<N-1>::test_trace(); } };
template <> struct recursive<0> { NO_INLINE static void test_trace() { ::test_trace(); } };
int main()
{
recursive<10>::test_trace();
}
Resulting Debug|x86
Console:
Trace:
main.cpp(19): test_trace @ 013B2C76
main.cpp(21): recursive<0>::test_trace @ 013B2C03
main.cpp(20): recursive<1>::test_trace @ 013B28E3
main.cpp(20): recursive<2>::test_trace @ 013B2933
main.cpp(20): recursive<3>::test_trace @ 013B2983
main.cpp(20): recursive<4>::test_trace @ 013B29D3
main.cpp(20): recursive<5>::test_trace @ 013B2A23
main.cpp(20): recursive<6>::test_trace @ 013B2A73
main.cpp(20): recursive<7>::test_trace @ 013B2AC3
main.cpp(20): recursive<8>::test_trace @ 013B2B13
main.cpp(20): recursive<9>::test_trace @ 013B2B63
main.cpp(20): recursive<10>::test_trace @ 013B2BB3
main.cpp(26): main @ 013B2DB3
exe_common.inl(74): invoke_main @ 013B6B4E
exe_common.inl(264): __scrt_common_main_seh @ 013B699A
exe_common.inl(309): __scrt_common_main @ 013B682D
exe_main.cpp(17): mainCRTStartup @ 013B6B68
<unknown>(0): BaseThreadInitThunk @ 76F3336A
<unknown>(0): RtlInitializeExceptionChain @ 77C39902
<unknown>(0): RtlInitializeExceptionChain @ 77C398D5
More examples:
Add libMmkDebugStack to your project via nuget. Done!
- Clone the repository
- Use
libMmkDebugStack.sln
to buildlibMmkDebugStack.lib
in the configurations/platforms of your choice. - Add
HAS_MMK_DEBUG_STACK
to your preprocessor definitions. - Add
libMmkDebugStack\include\
to your #include paths. - Targeting Windows:
- Add
build\native\lib\$(PlatformTarget)\$(PlatformToolset)\$(Configuration)\
to your library paths - Add
libMmkDebugStack.lib
andDbgHelp.lib
to your additional dependencies list.
- Add
- Targeting Android via the nVidia Codeworks for Android 1R4 SDK:
- Add
build\native\lib\$(ArchAbi)\$(ToolchainIdentifier)\$(Configuration)\
to your library paths - Add
MmkDebugStack
to your additional dependencies list.
- Add
- Targeting Android via the Microsoft Android SDK:
- Add
build\native\lib\$(Platform)\$(PlatformToolset)\$(Configuration)\
to your library paths - Add
-lMmkDebugStack
to your additional dependencies list.
- Add
- Clone the repository
- Run make
- Add
-DHAS_MMK_DEBUG_STACK
to yourCCFLAGS
- Add
-Lbin/$(compiler)-$(arch)-$(build)-$(language)/
to yourLDFLAGS
- Add
-lMmkDebugStack
to yourLDFLAGS
- Add
bin/$(compiler)-$(arch)-$(build)-$(language)/
to yourLD_LIBRARY_PATH
- Add option to use separate debugger process for stability / collecting stacks of foreign threads
- Backport to C++03 for wider compatability
- Properly port to Linux, OS X, iOS
- Port to Consoles, Handhelds, etc. (Blocker: Devkit access)
- Add Windows CDB backend for possible stability improvements, multi-thread stacks, crash dump analysis, etc.