From 979e063581512a867d1587964013afc6eea17f8f Mon Sep 17 00:00:00 2001 From: akallabeth Date: Fri, 29 Apr 2022 11:38:46 +0200 Subject: [PATCH] Moved execinfo backtrace to own file --- winpr/libwinpr/utils/CMakeLists.txt | 6 ++ winpr/libwinpr/utils/debug.c | 81 ++++++------------------ winpr/libwinpr/utils/execinfo/debug.c | 88 +++++++++++++++++++++++++++ winpr/libwinpr/utils/execinfo/debug.h | 40 ++++++++++++ 4 files changed, 154 insertions(+), 61 deletions(-) create mode 100644 winpr/libwinpr/utils/execinfo/debug.c create mode 100644 winpr/libwinpr/utils/execinfo/debug.h diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index b19d7bddb..18ee48870 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -114,6 +114,12 @@ if (ANDROID) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) endif() +if (HAVE_EXECINFO_H) + list(APPEND SRCS + execinfo/debug.c + execinfo/debug.h) +endif() + winpr_module_add(${SRCS} ${COLLECTIONS_SRCS} ${LODEPNG_SRCS} diff --git a/winpr/libwinpr/utils/debug.c b/winpr/libwinpr/utils/debug.c index 503f4afe1..e09dacd88 100644 --- a/winpr/libwinpr/utils/debug.c +++ b/winpr/libwinpr/utils/debug.c @@ -27,7 +27,7 @@ #include #if defined(HAVE_EXECINFO_H) -#include +#include #endif #if defined(ANDROID) @@ -79,15 +79,6 @@ static const char* support_msg = "Invalid stacktrace buffer! check if platform is supported!"; -#if defined(HAVE_EXECINFO_H) -typedef struct -{ - void** buffer; - size_t max; - size_t used; -} t_execinfo; -#endif - #if defined(_WIN32) || defined(_WIN64) typedef struct { @@ -259,15 +250,10 @@ USHORT RtlCaptureStackBackTrace(ULONG FramesToSkip, ULONG FramesToCapture, PVOID void winpr_backtrace_free(void* buffer) { if (!buffer) - { - LOGF(support_msg); return; - } #if defined(HAVE_EXECINFO_H) - t_execinfo* data = (t_execinfo*)buffer; - free(data->buffer); - free(data); + winpr_execinfo_backtrace_free(buffer); #elif defined(ANDROID) t_corkscrew_data* data = (t_corkscrew_data*)buffer; free(data->buffer); @@ -286,22 +272,7 @@ void winpr_backtrace_free(void* buffer) void* winpr_backtrace(DWORD size) { #if defined(HAVE_EXECINFO_H) - t_execinfo* data = calloc(1, sizeof(t_execinfo)); - - if (!data) - return NULL; - - data->buffer = calloc(size, sizeof(void*)); - - if (!data->buffer) - { - free(data); - return NULL; - } - - data->max = size; - data->used = backtrace(data->buffer, size); - return data; + return winpr_execinfo_backtrace(size); #elif defined(ANDROID) t_corkscrew_data* data = calloc(1, sizeof(t_corkscrew_data)); @@ -357,15 +328,7 @@ char** winpr_backtrace_symbols(void* buffer, size_t* used) } #if defined(HAVE_EXECINFO_H) - t_execinfo* data = (t_execinfo*)buffer; - - if (!data) - return NULL; - - if (used) - *used = data->used; - - return backtrace_symbols(data->buffer, data->used); + return winpr_execinfo_backtrace_symbols(buffer, used); #elif defined(ANDROID) t_corkscrew_data* data = (t_corkscrew_data*)buffer; @@ -478,24 +441,18 @@ void winpr_backtrace_symbols_fd(void* buffer, int fd) } #if defined(HAVE_EXECINFO_H) - t_execinfo* data = (t_execinfo*)buffer; - - if (!data) - return; - - backtrace_symbols_fd(data->buffer, data->used, fd); -#elif defined(_WIN32) || defined(_WIN64) || defined(ANDROID) + winpr_execinfo_backtrace_symbols_fd(buffer, fd); +#elif !defined(ANDROID) { - DWORD i; - size_t used; - char** lines; - lines = winpr_backtrace_symbols(buffer, &used); + size_t i; + size_t used = 0; + char** lines = winpr_backtrace_symbols(buffer, &used); - if (lines) - { - for (i = 0; i < used; i++) - write(fd, lines[i], strlen(lines[i])); - } + if (!lines) + return; + + for (i = 0; i < used; i++) + write(fd, lines[i], (unsigned)strnlen(lines[i], UINT32_MAX)); } #else LOGF(support_msg); @@ -527,7 +484,9 @@ void winpr_log_backtrace_ex(wLog* log, DWORD level, DWORD size) for (x = 0; x < used; x++) WLog_Print(log, level, "%" PRIuz ": %s\n", x, msg[x]); } - + free(msg); + +fail: winpr_backtrace_free(stack); } @@ -552,11 +511,11 @@ char* winpr_strerror(DWORD dw, char* dmsg, size_t size) if (rc) { #if defined(UNICODE) - WideCharToMultiByte(CP_ACP, 0, msg, rc, dmsg, size - 1, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, msg, rc, dmsg, (int)MIN(size - 1, INT_MAX), NULL, NULL); #else /* defined(UNICODE) */ - memcpy(dmsg, msg, min(rc, size - 1)); + memcpy(dmsg, msg, MIN(rc, size - 1)); #endif /* defined(UNICODE) */ - dmsg[min(rc, size - 1)] = 0; + dmsg[MIN(rc, size - 1)] = 0; #ifdef FORMAT_MESSAGE_ALLOCATE_BUFFER LocalFree(msg); #else diff --git a/winpr/libwinpr/utils/execinfo/debug.c b/winpr/libwinpr/utils/execinfo/debug.c new file mode 100644 index 000000000..509d1f7d7 --- /dev/null +++ b/winpr/libwinpr/utils/execinfo/debug.c @@ -0,0 +1,88 @@ +/** + * WinPR: Windows Portable Runtime + * Debugging Utils + * + * Copyright 2014 Armin Novak + * Copyright 2014 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include "debug.h" + +typedef struct +{ + void** buffer; + size_t max; + size_t used; +} t_execinfo; + +void winpr_execinfo_backtrace_free(void* buffer) +{ + t_execinfo* data = (t_execinfo*)buffer; + if (!data) + return; + + free(data->buffer); + free(data); +} + +void* winpr_execinfo_backtrace(DWORD size) +{ + t_execinfo* data = calloc(1, sizeof(t_execinfo)); + + if (!data) + return NULL; + + data->buffer = calloc(size, sizeof(void*)); + + if (!data->buffer) + { + free(data); + return NULL; + } + + data->max = size; + data->used = backtrace(data->buffer, size); + return data; +} + +char** winpr_execinfo_backtrace_symbols(void* buffer, size_t* used) +{ + t_execinfo* data = (t_execinfo*)buffer; + if (used) + *used = 0; + + if (!data) + return NULL; + + if (used) + *used = data->used; + + return backtrace_symbols(data->buffer, data->used); +} + +void winpr_execinfo_backtrace_symbols_fd(void* buffer, int fd) +{ + t_execinfo* data = (t_execinfo*)buffer; + + if (!data) + return; + + backtrace_symbols_fd(data->buffer, data->used, fd); +} diff --git a/winpr/libwinpr/utils/execinfo/debug.h b/winpr/libwinpr/utils/execinfo/debug.h new file mode 100644 index 000000000..aaf7748a3 --- /dev/null +++ b/winpr/libwinpr/utils/execinfo/debug.h @@ -0,0 +1,40 @@ +/** + * WinPR: Windows Portable Runtime + * WinPR Debugging helpers + * + * Copyright 2022 Armin Novak + * Copyright 2022 Thincast Technologies GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_DEBUG_EXECINFO_H +#define WINPR_DEBUG_EXECINFO_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + + void* winpr_execinfo_backtrace(DWORD size); + void winpr_execinfo_backtrace_free(void* buffer); + char** winpr_execinfo_backtrace_symbols(void* buffer, size_t* used); + void winpr_execinfo_backtrace_symbols_fd(void* buffer, int fd); + +#ifdef __cplusplus +} +#endif + +#endif /* WINPR_DEBUG_EXECINFO_H */