/****************************************************************************** * Copyright (c) Intel Corporation - All rights reserved. * * This file is part of the LIBXSMM library. * * * * For information on the license, see the LICENSE file. * * Further information: https://github.com/hfp/libxsmm/ * * SPDX-License-Identifier: BSD-3-Clause * ******************************************************************************/ /* Hans Pabst (Intel Corp.) ******************************************************************************/ #ifndef LIBXSMM_TRACE_H #define LIBXSMM_TRACE_H #include #if (defined(__TRACE) || defined(LIBXSMM_BUILD) || !defined(_WIN32)) # define LIBXSMM_TRACE #endif #if !defined(LIBXSMM_TRACE_CALLERID_MAXDEPTH) # define LIBXSMM_TRACE_CALLERID_MAXDEPTH 8 #endif #if !defined(LIBXSMM_TRACE_CALLERID_GCCBUILTIN) && \ ((!defined(_WIN32) || defined(__MINGW32__) || (defined(_MSC_VER) && defined(__clang__))) && \ (!defined(__PGI) || LIBXSMM_VERSION2(19, 0) <= LIBXSMM_VERSION2(__PGIC__, __PGIC_MINOR__)) && \ (defined(__GNUC__) || defined(__clang__))) # define LIBXSMM_TRACE_CALLERID_GCCBUILTIN #endif /** Initializes the trace facility; NOT thread-safe. */ LIBXSMM_API int libxsmm_trace_init( /* Filter for thread id (-1: all). */ int filter_threadid, /* Specify min. depth of stack trace (0: all). */ int filter_mindepth, /* Specify max. depth of stack trace (-1: all). */ int filter_maxnsyms); /** Finalizes the trace facility; NOT thread-safe. */ LIBXSMM_API int libxsmm_trace_finalize(void); /** Receives the backtrace of up to 'size' addresses. Returns the actual number of addresses (n <= size). */ LIBXSMM_API unsigned int libxsmm_backtrace(const void* buffer[], unsigned int size, unsigned int skip); #if defined(LIBXSMM_TRACE_CALLERID_GCCBUILTIN) && !defined(__INTEL_COMPILER) # if defined(__clang__) # pragma clang diagnostic push # elif defined(__GNUC__) && LIBXSMM_VERSION2(4, 6) <= LIBXSMM_VERSION2(__GNUC__, __GNUC_MINOR__) # pragma GCC diagnostic push # endif # if defined(__clang__) # pragma clang diagnostic ignored "-Wunknown-warning-option" # if LIBXSMM_VERSION2(9, 0) <= LIBXSMM_VERSION2(__clang_major__, __clang_minor__) # pragma clang diagnostic ignored "-Wframe-address" # endif # elif defined(__GNUC__) /* no version-check */ # pragma GCC diagnostic ignored "-Wpragmas" # pragma GCC diagnostic ignored "-Wframe-address" # endif #endif LIBXSMM_API_INLINE const void* libxsmm_trace_caller_id(unsigned int level) { /* must be inline */ #if defined(LIBXSMM_TRACE_CALLERID_GCCBUILTIN) switch (level) { # if 0 case 0: return __builtin_extract_return_addr(__builtin_return_address(0)); case 1: return __builtin_extract_return_addr(__builtin_return_address(1)); case 2: return __builtin_extract_return_addr(__builtin_return_address(2)); case 3: return __builtin_extract_return_addr(__builtin_return_address(3)); # else case 0: return __builtin_frame_address(1); case 1: return __builtin_frame_address(2); case 2: return __builtin_frame_address(3); case 3: return __builtin_frame_address(4); # endif default: #else { # if defined(_WIN32) if (0 == level) return _AddressOfReturnAddress(); else # endif #endif { const void* stacktrace[LIBXSMM_TRACE_CALLERID_MAXDEPTH]; const unsigned int n = libxsmm_backtrace(stacktrace, LIBXSMM_TRACE_CALLERID_MAXDEPTH, 0/*skip*/); return (level < n ? stacktrace[level] : NULL); } } } #if defined(LIBXSMM_TRACE_CALLERID_GCCBUILTIN) && !defined(__INTEL_COMPILER) # if defined(__clang__) # pragma clang diagnostic pop # elif defined(__GNUC__) && LIBXSMM_VERSION2(4, 6) <= LIBXSMM_VERSION2(__GNUC__, __GNUC_MINOR__) # pragma GCC diagnostic pop # endif #endif /** Returns the name of the function where libxsmm_trace is called from; thread-safe. */ LIBXSMM_API const char* libxsmm_trace_info( /* Query and output the abs. location in stacktrace (no input). */ unsigned int* depth, /* Query and output the thread id (no input). */ unsigned int* threadid, /* Filter for thread id (-1: all, NULL: libxsmm_trace_init). */ const int* filter_threadid, /* Lookup symbol (depth argument becomes relative to symbol position). */ const void* filter_symbol, /* Specify min. abs. position in stack trace (-1 or 0: all, NULL: libxsmm_trace_init). */ const int* filter_mindepth, /* Specify max. depth of stack trace (-1 or 0: all, NULL: libxsmm_trace_init). */ const int* filter_maxnsyms); /** Prints an entry of the function where libxsmm_trace is called from (indented/hierarchical). */ LIBXSMM_API void libxsmm_trace(FILE* stream, /* Filter for thread id (-1: all, NULL: libxsmm_trace_init). */ const int* filter_threadid, /* Lookup symbol (depth argument becomes relative to symbol position). */ const void* filter_symbol, /* Specify min. absolute pos. in stack trace (-1 or 0: all, NULL: libxsmm_trace_init). */ const int* filter_mindepth, /* Specify max. depth of stack trace (-1 or 0: all, NULL: libxsmm_trace_init). */ const int* filter_maxnsyms); #endif /*LIBXSMM_TRACE_H*/