Skip to content

Commit b7683c4

Browse files
authored
Merge pull request #1397 from WebPlatformForEmbedded/pgorszkowski/wpe-2.38/fix_backtrace_generation
[WPE][GTK] Symbolize `StackTrace` using `libbacktrace`
2 parents afd54aa + e5fb707 commit b7683c4

7 files changed

Lines changed: 177 additions & 2 deletions

File tree

Source/WTF/wtf/PlatformGTK.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,9 @@ list(APPEND WTF_SYSTEM_INCLUDE_DIRECTORIES
9090
${GIO_UNIX_INCLUDE_DIRS}
9191
${GLIB_INCLUDE_DIRS}
9292
)
93+
94+
if (USE_LIBBACKTRACE)
95+
list(APPEND WTF_LIBRARIES
96+
LIBBACKTRACE::LIBBACKTRACE
97+
)
98+
endif ()

Source/WTF/wtf/PlatformWPE.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,9 @@ list(APPEND WTF_SYSTEM_INCLUDE_DIRECTORIES
6262
${GIO_UNIX_INCLUDE_DIRS}
6363
${GLIB_INCLUDE_DIRS}
6464
)
65+
66+
if (USE_LIBBACKTRACE)
67+
list(APPEND WTF_LIBRARIES
68+
LIBBACKTRACE::LIBBACKTRACE
69+
)
70+
endif ()

Source/WTF/wtf/StackTrace.cpp

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
#include <wtf/Assertions.h>
3131
#include <wtf/PrintStream.h>
3232

33+
#if USE(LIBBACKTRACE)
34+
#include <string.h>
35+
#include <wtf/NeverDestroyed.h>
36+
#endif
37+
3338
#if HAVE(BACKTRACE_SYMBOLS) || HAVE(BACKTRACE)
3439
#include <execinfo.h>
3540
#endif
@@ -58,6 +63,55 @@ void WTFGetBacktrace(void** stack, int* size)
5863

5964
namespace WTF {
6065

66+
#if USE(LIBBACKTRACE)
67+
static struct backtrace_state* backtraceState()
68+
{
69+
static NeverDestroyed<struct backtrace_state*> backtraceState = backtrace_create_state(nullptr, 1, nullptr, nullptr);
70+
return backtraceState;
71+
}
72+
73+
static void backtraceSyminfoCallback(void* data, uintptr_t, const char* symname, uintptr_t, uintptr_t)
74+
{
75+
const char** symbol = static_cast<const char**>(data);
76+
*symbol = symname;
77+
}
78+
79+
static int backtraceFullCallback(void* data, uintptr_t, const char*, int, const char* function)
80+
{
81+
const char** symbol = static_cast<const char**>(data);
82+
*symbol = function;
83+
return 0;
84+
}
85+
86+
char** symbolize(void* const* addresses, int size)
87+
{
88+
struct backtrace_state* state = backtraceState();
89+
if (!state)
90+
return nullptr;
91+
92+
char** symbols = static_cast<char**>(malloc(sizeof(char*) * size));
93+
94+
for (int i = 0; i < size; ++i) {
95+
uintptr_t pc = reinterpret_cast<uintptr_t>(addresses[i]);
96+
char* symbol;
97+
98+
backtrace_pcinfo(state, pc, backtraceFullCallback, nullptr, &symbol);
99+
if (!symbol)
100+
backtrace_syminfo(backtraceState(), pc, backtraceSyminfoCallback, nullptr, &symbol);
101+
102+
if (symbol) {
103+
char* demangled = abi::__cxa_demangle(symbol, nullptr, nullptr, nullptr);
104+
if (demangled)
105+
symbols[i] = demangled;
106+
else
107+
symbols[i] = strdup(symbol);
108+
} else
109+
symbols[i] = strdup("???");
110+
}
111+
return symbols;
112+
}
113+
#endif
114+
61115
ALWAYS_INLINE size_t StackTrace::instanceSize(int capacity)
62116
{
63117
ASSERT(capacity >= 1);
@@ -110,7 +164,11 @@ auto StackTrace::demangle(void* pc) -> std::optional<DemangleEntry>
110164
void StackTrace::dump(PrintStream& out, const char* indentString) const
111165
{
112166
const auto* stack = this->stack();
113-
#if HAVE(BACKTRACE_SYMBOLS)
167+
#if USE(LIBBACKTRACE)
168+
char** symbols = symbolize(stack, m_size);
169+
if (!symbols)
170+
return;
171+
#elif HAVE(BACKTRACE_SYMBOLS)
114172
char** symbols = backtrace_symbols(stack, m_size);
115173
if (!symbols)
116174
return;
@@ -146,7 +204,11 @@ void StackTrace::dump(PrintStream& out, const char* indentString) const
146204
out.printf("%s%s%-3d %p\n", m_prefix ? m_prefix : "", indentString, frameNumber, stack[i]);
147205
}
148206

149-
#if HAVE(BACKTRACE_SYMBOLS)
207+
#if USE(LIBBACKTRACE)
208+
for (int i = 0; i < m_size; ++i)
209+
free(symbols[i]);
210+
free(symbols);
211+
#elif HAVE(BACKTRACE_SYMBOLS)
150212
free(symbols);
151213
#endif
152214
}

Source/WTF/wtf/StackTrace.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,18 @@
2929
#include <optional>
3030
#include <wtf/SystemFree.h>
3131

32+
#if USE(LIBBACKTRACE)
33+
#include <backtrace.h>
34+
#endif
35+
3236
namespace WTF {
3337

3438
class PrintStream;
3539

40+
#if USE(LIBBACKTRACE)
41+
WTF_EXPORT_PRIVATE char** symbolize(void* const*, int);
42+
#endif
43+
3644
class StackTrace {
3745
WTF_MAKE_FAST_ALLOCATED;
3846
public:
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# - Try to find libbacktrace.
2+
# Once done, this will define
3+
#
4+
# LIBBACKTRACE_FOUND - libbacktrace was found
5+
# LIBBACKTRACE_INCLUDE_DIRS - the libbacktrace include directories
6+
# LIBBACKTRACE_LIBRARIES - link these to use libbacktrace.
7+
#
8+
# Copyright (C) 2023 Igalia S.L.
9+
#
10+
# Redistribution and use in source and binary forms, with or without
11+
# modification, are permitted provided that the following conditions
12+
# are met:
13+
# 1. Redistributions of source code must retain the above copyright
14+
# notice, this list of conditions and the following disclaimer.
15+
# 2. Redistributions in binary form must reproduce the above copyright
16+
# notice, this list of conditions and the following disclaimer in the
17+
# documentation and/or other materials provided with the distribution.
18+
#
19+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
20+
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
23+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26+
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28+
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29+
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
31+
find_package(PkgConfig QUIET)
32+
pkg_check_modules(PC_LIBBACKTRACE QUIET backtrace)
33+
set(LIBBACKTRACE_COMPILE_OPTIONS ${PC_LIBBACKTRACE_CFLAGS_OTHER})
34+
set(LIBBACKTRACE_VERSION ${PC_LIBBACKTRACE_VERSION})
35+
36+
find_path(LIBBACKTRACE_INCLUDE_DIR
37+
NAMES backtrace.h
38+
HINTS ${PC_LIBBACKTRACE_INCLUDEDIR}
39+
${PC_LIBBACKTRACE_INCLUDE_DIRS}
40+
)
41+
42+
find_library(LIBBACKTRACE_LIBRARY
43+
NAMES backtrace
44+
HINTS ${PC_LIBBACKTRACE_LIBDIR}
45+
${PC_LIBBACKTRACE_LIBRARY_DIRS}
46+
)
47+
48+
include(FindPackageHandleStandardArgs)
49+
find_package_handle_standard_args(LibBacktrace
50+
REQUIRED_VARS LIBBACKTRACE_INCLUDE_DIR LIBBACKTRACE_LIBRARY
51+
VERSION_VAR LIBBACKTRACE_VERSION
52+
)
53+
54+
if (LIBBACKTRACE_LIBRARY AND NOT TARGET LIBBACKTRACE::LIBBACKTRACE)
55+
add_library(LIBBACKTRACE::LIBBACKTRACE UNKNOWN IMPORTED GLOBAL)
56+
set_target_properties(LIBBACKTRACE::LIBBACKTRACE PROPERTIES
57+
IMPORTED_LOCATION "${LIBBACKTRACE_LIBRARY}"
58+
INTERFACE_COMPILE_OPTIONS "${LIBBACKTRACE_COMPILE_OPTIONS}"
59+
INTERFACE_INCLUDE_DIRECTORIES "${LIBBACKTRACE_INCLUDE_DIR}"
60+
)
61+
endif ()
62+
63+
mark_as_advanced(
64+
LIBBACKTRACE_INCLUDE_DIR
65+
LIBBACKTRACE_LIBRARY
66+
)
67+
68+
if (LIBBACKTRACE_FOUND)
69+
set(LIBBACKTRACE_LIBRARIES ${LIBBACKTRACE_LIBRARY})
70+
set(LIBBACKTRACE_INCLUDE_DIRS ${LIBBACKTRACE_INCLUDE_DIR})
71+
endif ()

Source/cmake/OptionsGTK.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLI
6868
WEBKIT_OPTION_DEFINE(USE_GTK4 "Whether to enable usage of GTK4 instead of GTK3." PUBLIC OFF)
6969
WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
7070
WEBKIT_OPTION_DEFINE(USE_LCMS "Whether to enable support for image color management using libcms2." PUBLIC ON)
71+
WEBKIT_OPTION_DEFINE(USE_LIBBACKTRACE "Whether to enable usage of libbacktrace." PUBLIC OFF)
7172
WEBKIT_OPTION_DEFINE(USE_LIBHYPHEN "Whether to enable the default automatic hyphenation implementation." PUBLIC ON)
7273
WEBKIT_OPTION_DEFINE(USE_LIBSECRET "Whether to enable the persistent credential storage using libsecret." PUBLIC ON)
7374
WEBKIT_OPTION_DEFINE(USE_OPENGL_OR_ES "Whether to use OpenGL or ES." PUBLIC ON)
@@ -476,6 +477,13 @@ if (USE_LCMS)
476477
endif ()
477478
endif ()
478479

480+
if (USE_LIBBACKTRACE)
481+
find_package(LibBacktrace)
482+
if (NOT LIBBACKTRACE_FOUND)
483+
message(FATAL_ERROR "libbacktrace is required for USE_LIBBACKTRACE")
484+
endif ()
485+
endif ()
486+
479487
# Override the cached variable, gtk-doc does not really work when building on Mac.
480488
if (APPLE)
481489
set(ENABLE_GTKDOC OFF)

Source/cmake/OptionsWPE.cmake

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ WEBKIT_OPTION_DEFINE(ENABLE_WPE_QT_API "Whether to enable support for the Qt5/QM
9595
WEBKIT_OPTION_DEFINE(USE_AVIF "Whether to enable support for AVIF images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
9696
WEBKIT_OPTION_DEFINE(USE_JPEGXL "Whether to enable support for JPEG-XL images." PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES})
9797
WEBKIT_OPTION_DEFINE(USE_LCMS "Whether to enable support for image color management using libcms2." PUBLIC ON)
98+
WEBKIT_OPTION_DEFINE(USE_LIBBACKTRACE "Whether to enable usage of libbacktrace." PUBLIC OFF)
9899
WEBKIT_OPTION_DEFINE(USE_OPENJPEG "Whether to enable support for JPEG2000 images." PUBLIC ON)
99100
WEBKIT_OPTION_DEFINE(USE_SOUP2 "Whether to enable usage of Soup 2 instead of Soup 3." PUBLIC OFF)
100101
WEBKIT_OPTION_DEFINE(USE_WOFF2 "Whether to enable support for WOFF2 Web Fonts." PUBLIC ON)
@@ -366,6 +367,13 @@ SET_AND_EXPOSE_TO_BUILD(USE_COORDINATED_GRAPHICS TRUE)
366367
SET_AND_EXPOSE_TO_BUILD(USE_NICOSIA TRUE)
367368
SET_AND_EXPOSE_TO_BUILD(HAVE_OS_DARK_MODE_SUPPORT 1)
368369

370+
if (USE_LIBBACKTRACE)
371+
find_package(LibBacktrace)
372+
if (NOT LIBBACKTRACE_FOUND)
373+
message(FATAL_ERROR "libbacktrace is required for USE_LIBBACKTRACE")
374+
endif ()
375+
endif ()
376+
369377
# GUri is available in GLib since version 2.66, but we only want to use it if version is >= 2.67.1.
370378
if (PC_GLIB_VERSION VERSION_GREATER "2.67.1" OR PC_GLIB_VERSION STREQUAL "2.67.1")
371379
SET_AND_EXPOSE_TO_BUILD(HAVE_GURI 1)
@@ -427,3 +435,9 @@ if (COMPILER_IS_GCC_OR_CLANG AND UNIX AND NOT APPLE)
427435
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${CMAKE_COMPILER_SIZE_OPT_FLAGS} -ffunction-sections -fdata-sections -fno-rtti")
428436
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--gc-sections")
429437
endif ()
438+
439+
if (USE_LIBBACKTRACE)
440+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}${CMAKE_COMPILER_SIZE_OPT_FLAGS} -funwind-tables")
441+
442+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${CMAKE_COMPILER_SIZE_OPT_FLAGS} -funwind-tables")
443+
endif ()

0 commit comments

Comments
 (0)