27 #include <winpr/string.h>
29 #include <corkscrew/backtrace.h>
31 #include <winpr/crt.h>
32 #include <winpr/wlog.h>
36 #define TAG "com.winpr.utils.debug"
40 WLog_Print(WLog_Get(TAG), WLOG_TRACE, __VA_ARGS__); \
45 WLog_Print(WLog_Get(TAG), WLOG_DEBUG, __VA_ARGS__); \
50 WLog_Print(WLog_Get(TAG), WLOG_INFO, __VA_ARGS__); \
55 WLog_Print(WLog_Get(TAG), WLOG_WARN, __VA_ARGS__); \
60 WLog_Print(WLog_Get(TAG), WLOG_ERROR, __VA_ARGS__); \
65 WLog_Print(WLog_Get(TAG), WLOG_FATAL, __VA_ARGS__); \
68 static const char* support_msg =
"Invalid stacktrace buffer! check if platform is supported!";
82 ssize_t (*unwind_backtrace_thread)(pid_t tid,
backtrace_frame_t* backtrace,
size_t ignore_depth,
84 ssize_t (*unwind_backtrace_ptrace)(pid_t tid,
const ptrace_context_t* context,
93 void (*format_backtrace_line)(
unsigned frameNumber,
const backtrace_frame_t* frame,
98 static pthread_once_t initialized = PTHREAD_ONCE_INIT;
99 static t_corkscrew* fkt = NULL;
101 void load_library(
void)
103 static t_corkscrew lib;
105 lib.hdl = dlopen(
"libcorkscrew.so", RTLD_LAZY);
109 LOGF(
"dlopen error %s", dlerror());
113 lib.unwind_backtrace = dlsym(lib.hdl,
"unwind_backtrace");
115 if (!lib.unwind_backtrace)
117 LOGF(
"dlsym error %s", dlerror());
121 lib.unwind_backtrace_thread = dlsym(lib.hdl,
"unwind_backtrace_thread");
123 if (!lib.unwind_backtrace_thread)
125 LOGF(
"dlsym error %s", dlerror());
129 lib.unwind_backtrace_ptrace = dlsym(lib.hdl,
"unwind_backtrace_ptrace");
131 if (!lib.unwind_backtrace_ptrace)
133 LOGF(
"dlsym error %s", dlerror());
137 lib.get_backtrace_symbols = dlsym(lib.hdl,
"get_backtrace_symbols");
139 if (!lib.get_backtrace_symbols)
141 LOGF(
"dlsym error %s", dlerror());
145 lib.get_backtrace_symbols_ptrace = dlsym(lib.hdl,
"get_backtrace_symbols_ptrace");
147 if (!lib.get_backtrace_symbols_ptrace)
149 LOGF(
"dlsym error %s", dlerror());
153 lib.free_backtrace_symbols = dlsym(lib.hdl,
"free_backtrace_symbols");
155 if (!lib.free_backtrace_symbols)
157 LOGF(
"dlsym error %s", dlerror());
161 lib.format_backtrace_line = dlsym(lib.hdl,
"format_backtrace_line");
163 if (!lib.format_backtrace_line)
165 LOGF(
"dlsym error %s", dlerror());
181 void winpr_corkscrew_backtrace_free(
void* buffer)
183 t_corkscrew_data* data = (t_corkscrew_data*)buffer;
191 void* winpr_corkscrew_backtrace(DWORD size)
193 t_corkscrew_data* data = calloc(1,
sizeof(t_corkscrew_data));
206 pthread_once(&initialized, load_library);
208 data->used = fkt->unwind_backtrace(data->buffer, 0, size);
212 char** winpr_corkscrew_backtrace_symbols(
void* buffer,
size_t* used)
214 t_corkscrew_data* data = (t_corkscrew_data*)buffer;
221 pthread_once(&initialized, load_library);
230 size_t line_len = (data->max > 1024) ? data->max : 1024;
231 size_t array_size = data->used *
sizeof(
char*);
232 size_t lines_size = data->used * line_len;
233 char** vlines = calloc(1, array_size + lines_size);
236 if (!vlines || !symbols)
244 for (
size_t i = 0; i < data->used; i++)
245 vlines[i] = (
char*)vlines + array_size + i * line_len;
247 fkt->get_backtrace_symbols(data->buffer, data->used, symbols);
249 for (
size_t i = 0; i < data->used; i++)
250 fkt->format_backtrace_line(i, &data->buffer[i], &symbols[i], vlines[i], line_len);
252 fkt->free_backtrace_symbols(symbols, data->used);