21#include <winpr/config.h>
22#include <winpr/platform.h>
25WINPR_PRAGMA_DIAG_IGNORED_RESERVED_ID_MACRO
26WINPR_PRAGMA_DIAG_IGNORED_UNUSED_MACRO
28#define __STDC_WANT_LIB_EXT1__ 1
37#include <winpr/string.h>
39#if defined(USE_EXECINFO)
40#include <execinfo/debug.h>
43#if defined(USE_UNWIND)
44#include <unwind/debug.h>
47#if defined(WINPR_HAVE_CORKSCREW)
48#include <corkscrew/debug.h>
51#if defined(_WIN32) || defined(_WIN64)
53#include <windows/debug.h>
56#include <winpr/wlog.h>
57#include <winpr/debug.h>
59#define TAG "com.winpr.utils.debug"
61#define LINE_LENGTH_MAX 2048
63static const char support_msg[] =
"Invalid stacktrace buffer! check if platform is supported!";
65void winpr_backtrace_free(
void* buffer)
70#if defined(USE_UNWIND)
71 winpr_unwind_backtrace_free(buffer);
72#elif defined(USE_EXECINFO)
73 winpr_execinfo_backtrace_free(buffer);
74#elif defined(WINPR_HAVE_CORKSCREW)
75 winpr_corkscrew_backtrace_free(buffer);
76#elif defined(_WIN32) || defined(_WIN64)
77 winpr_win_backtrace_free(buffer);
80 WLog_FATAL(TAG,
"%s", support_msg);
84void* winpr_backtrace(DWORD size)
86#if defined(USE_UNWIND)
87 return winpr_unwind_backtrace(size);
88#elif defined(USE_EXECINFO)
89 return winpr_execinfo_backtrace(size);
90#elif defined(WINPR_HAVE_CORKSCREW)
91 return winpr_corkscrew_backtrace(size);
92#elif (defined(_WIN32) || defined(_WIN64)) && !defined(_UWP)
93 return winpr_win_backtrace(size);
95 WLog_FATAL(TAG,
"%s", support_msg);
98 return strndup(support_msg,
sizeof(support_msg));
102char** winpr_backtrace_symbols(
void* buffer,
size_t* used)
109 WLog_FATAL(TAG,
"%s", support_msg);
113#if defined(USE_UNWIND)
114 return winpr_unwind_backtrace_symbols(buffer, used);
115#elif defined(USE_EXECINFO)
116 return winpr_execinfo_backtrace_symbols(buffer, used);
117#elif defined(WINPR_HAVE_CORKSCREW)
118 return winpr_corkscrew_backtrace_symbols(buffer, used);
119#elif (defined(_WIN32) || defined(_WIN64)) && !defined(_UWP)
120 return winpr_win_backtrace_symbols(buffer, used);
122 WLog_FATAL(TAG,
"%s", support_msg);
130 size_t len = strnlen(support_msg,
sizeof(support_msg));
131 char* ppmsg = calloc(
sizeof(
char*) + len + 1,
sizeof(
char));
134 char** msgptr = (
char**)ppmsg;
135 char* msg = &ppmsg[
sizeof(
char*)];
138 strncpy(msg, support_msg, len);
144void winpr_backtrace_symbols_fd(
void* buffer,
int fd)
148 WLog_FATAL(TAG,
"%s", support_msg);
152#if defined(USE_EXECINFO) && !defined(USE_UNWIND)
153 winpr_execinfo_backtrace_symbols_fd(buffer, fd);
154#elif !defined(ANDROID)
157 char** lines = winpr_backtrace_symbols(buffer, &used);
162 for (
size_t i = 0; i < used; i++)
163 (
void)_write(fd, lines[i], (
unsigned)strnlen(lines[i], LINE_LENGTH_MAX));
167 WLog_FATAL(TAG,
"%s", support_msg);
171void winpr_log_backtrace(
const char* tag, DWORD level, DWORD size)
173 winpr_log_backtrace_ex(WLog_Get(tag), level, size);
176void winpr_log_backtrace_ex(wLog* log, DWORD level, WINPR_ATTR_UNUSED DWORD size)
180 void* stack = winpr_backtrace(20);
184 WLog_Print(log, WLOG_ERROR,
"winpr_backtrace failed!\n");
188 msg = winpr_backtrace_symbols(stack, &used);
192 for (
size_t x = 0; x < used; x++)
193 WLog_Print(log, level,
"%" PRIuz
": %s", x, msg[x]);
198 winpr_backtrace_free(stack);
201char* winpr_strerror(INT32 dw,
char* dmsg,
size_t size)
203#ifdef __STDC_LIB_EXT1__
204 (void)strerror_s(dw, dmsg, size);
205#elif defined(WINPR_HAVE_STRERROR_R)
206 (void)strerror_r(dw, dmsg, size);
208 (void)_snprintf(dmsg, size,
"%s", strerror(dw));