Compare commits
1 Commits
main
...
jr/emscrip
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da533c0ef0 |
@ -66,7 +66,40 @@ else()
|
||||
endif()
|
||||
|
||||
# ========================================== Platform Support and Auto-config ==========================================
|
||||
include(cmake/Autoconfig.cmake)
|
||||
if(NOT EMSCRIPTEN)
|
||||
include(cmake/Autoconfig.cmake)
|
||||
else()
|
||||
if(
|
||||
CPPTRACE_UNWIND_WITH_UNWIND OR
|
||||
CPPTRACE_UNWIND_WITH_LIBUNWIND OR
|
||||
CPPTRACE_UNWIND_WITH_EXECINFO OR
|
||||
CPPTRACE_UNWIND_WITH_WINAPI OR
|
||||
CPPTRACE_UNWIND_WITH_DBGHELP OR
|
||||
CPPTRACE_UNWIND_WITH_NOTHING
|
||||
)
|
||||
message(FATAL_ERROR "Cpptrace config error: Unwinding back-end may not be specified under emscripten.")
|
||||
endif()
|
||||
if(
|
||||
CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE OR
|
||||
CPPTRACE_GET_SYMBOLS_WITH_LIBDL OR
|
||||
CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE OR
|
||||
CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF OR
|
||||
CPPTRACE_GET_SYMBOLS_WITH_DBGHELP OR
|
||||
CPPTRACE_GET_SYMBOLS_WITH_NOTHING
|
||||
)
|
||||
message(FATAL_ERROR "Cpptrace config error: Symbol back-end may not be specified under emscripten.")
|
||||
endif()
|
||||
if(
|
||||
CPPTRACE_DEMANGLE_WITH_CXXABI OR
|
||||
CPPTRACE_DEMANGLE_WITH_WINAPI OR
|
||||
CPPTRACE_DEMANGLE_WITH_NOTHING
|
||||
)
|
||||
message(FATAL_ERROR "Cpptrace config error: Demangling back-end may not be specified under emscripten.")
|
||||
endif()
|
||||
set(CPPTRACE_UNWIND_WITH_NOTHING On)
|
||||
set(CPPTRACE_GET_SYMBOLS_WITH_NOTHING On)
|
||||
set(CPPTRACE_DEMANGLE_WITH_NOTHING On)
|
||||
endif()
|
||||
|
||||
# =================================================== Library Setup ====================================================
|
||||
|
||||
@ -469,6 +502,13 @@ if(CPPTRACE_DEMANGLE_WITH_NOTHING)
|
||||
target_compile_definitions(${target_name} PUBLIC CPPTRACE_DEMANGLE_WITH_NOTHING)
|
||||
endif()
|
||||
|
||||
# Emscripten
|
||||
if(EMSCRIPTEN)
|
||||
target_compile_definitions(${target_name} PUBLIC CPPTRACE_EMSCRIPTEN)
|
||||
endif()
|
||||
|
||||
# Other options
|
||||
|
||||
if(NOT "${CPPTRACE_BACKTRACE_PATH}" STREQUAL "")
|
||||
target_compile_definitions(${target_name} PUBLIC CPPTRACE_BACKTRACE_PATH=${CPPTRACE_BACKTRACE_PATH})
|
||||
endif()
|
||||
|
||||
@ -68,7 +68,7 @@ namespace detail {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
#else // Windows
|
||||
#elif IS_WINDOWS
|
||||
Result<std::uintptr_t, internal_error> get_module_image_base(const std::string& object_path) {
|
||||
static std::mutex mutex;
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
@ -107,7 +107,7 @@ namespace detail {
|
||||
return frame;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#elif IS_WINDOWS
|
||||
std::string get_module_name(HMODULE handle) {
|
||||
static std::mutex mutex;
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
@ -153,6 +153,10 @@ namespace detail {
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
#elif IS_EMSCRIPTEN
|
||||
object_frame get_frame_object_info(frame_ptr) {
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<object_frame> get_frames_object_info(const std::vector<frame_ptr>& addresses) {
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include <cstdint>
|
||||
|
||||
namespace cpptrace {
|
||||
|
||||
namespace detail {
|
||||
object_frame get_frame_object_info(frame_ptr address);
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "binary/object.hpp"
|
||||
#include "binary/safe_dl.hpp"
|
||||
#include "snippets/snippet.hpp"
|
||||
#include "platform/emscripten.hpp"
|
||||
|
||||
namespace cpptrace {
|
||||
CPPTRACE_FORCE_NO_INLINE
|
||||
@ -396,12 +397,16 @@ namespace cpptrace {
|
||||
CPPTRACE_FORCE_NO_INLINE
|
||||
stacktrace generate_trace(std::size_t skip, std::size_t max_depth) {
|
||||
try {
|
||||
#if IS_EMSCRIPTEN
|
||||
return detail::generate_emscripten_trace(skip + 1, max_depth);
|
||||
#else
|
||||
std::vector<frame_ptr> frames = detail::capture_frames(skip + 1, max_depth);
|
||||
std::vector<stacktrace_frame> trace = detail::resolve_frames(frames);
|
||||
for(auto& frame : trace) {
|
||||
frame.symbol = detail::demangle(frame.symbol);
|
||||
}
|
||||
return {std::move(trace)};
|
||||
#endif
|
||||
} catch(...) { // NOSONAR
|
||||
if(!detail::should_absorb_trace_exceptions()) {
|
||||
throw;
|
||||
|
||||
33
src/platform/emscripten.hpp
Normal file
33
src/platform/emscripten.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef EMSCRIPTEN_HPP
|
||||
#define EMSCRIPTEN_HPP
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#if IS_EMSCRIPTEN
|
||||
|
||||
#include <emscripten.h>
|
||||
#include <memory>
|
||||
#include "utils/microfmt.hpp"
|
||||
|
||||
namespace cpptrace {
|
||||
namespace detail {
|
||||
CPPTRACE_FORCE_NO_INLINE
|
||||
stacktrace generate_emscripten_trace(std::size_t skip, std::size_t max_depth) {
|
||||
int estimated_size = emscripten_get_callstack(0, nullptr, 0);
|
||||
VERIFY(estimated_size >= 0);
|
||||
// "Note that this might be fully accurate since subsequent calls will carry different line numbers, so it is
|
||||
// best to allocate a few bytes extra to be safe."
|
||||
// Thanks, emscripten
|
||||
const auto max_size = estimated_size + 1000;
|
||||
// actually do the trace now
|
||||
std::unique_ptr<char[]> buffer(new char[max_size]);
|
||||
emscripten_get_callstack(0, buffer.get(), max_size);
|
||||
microfmt::print("{}\n", buffer.get());
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -14,6 +14,9 @@
|
||||
#elif defined(__APPLE__)
|
||||
#undef IS_APPLE
|
||||
#define IS_APPLE 1
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#undef IS_EMSCRIPTEN
|
||||
#define IS_EMSCRIPTEN 1
|
||||
#else
|
||||
#error "Unexpected platform"
|
||||
#endif
|
||||
@ -32,7 +35,7 @@
|
||||
#undef IS_MSVC
|
||||
#define IS_MSVC 1
|
||||
#else
|
||||
#error "Unsupported compiler"
|
||||
// #error "Unsupported compiler"
|
||||
#endif
|
||||
|
||||
#define IS_LIBSTDCXX 0
|
||||
|
||||
@ -84,7 +84,9 @@ namespace detail {
|
||||
}
|
||||
|
||||
std::vector<stacktrace_frame> resolve_frames(const std::vector<object_frame>& frames) {
|
||||
#if defined(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF) && defined(CPPTRACE_GET_SYMBOLS_WITH_DBGHELP)
|
||||
#if IS_EMSCRIPTEN
|
||||
return {}; // TODO
|
||||
#elif defined(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF) && defined(CPPTRACE_GET_SYMBOLS_WITH_DBGHELP)
|
||||
std::vector<stacktrace_frame> trace = libdwarf::resolve_frames(frames);
|
||||
fill_blanks(trace, dbghelp::resolve_frames);
|
||||
return trace;
|
||||
@ -120,7 +122,9 @@ namespace detail {
|
||||
}
|
||||
|
||||
std::vector<stacktrace_frame> resolve_frames(const std::vector<frame_ptr>& frames) {
|
||||
#if defined(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF) \
|
||||
#if IS_EMSCRIPTEN
|
||||
return {}; // TODO
|
||||
#elif defined(CPPTRACE_GET_SYMBOLS_WITH_LIBDWARF) \
|
||||
|| defined(CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE)
|
||||
auto dlframes = get_frames_object_info(frames);
|
||||
#endif
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
void trace() {
|
||||
cpptrace::generate_trace().print();
|
||||
cpptrace::generate_trace().print_with_snippets();
|
||||
throw cpptrace::logic_error("foobar");
|
||||
// throw cpptrace::logic_error("foobar");
|
||||
}
|
||||
|
||||
void foo(int n) {
|
||||
|
||||
@ -25,7 +25,7 @@ CPPTRACE_FORCE_NO_INLINE static void raw_trace_basic() {
|
||||
EXPECT_LE(raw_trace.frames[0], reinterpret_cast<uintptr_t>(raw_trace_basic) + 90);
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) && !defined(__EMSCRIPTEN__)
|
||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_basic_precise() {
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
@ -46,7 +46,7 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_basic_precise() {
|
||||
|
||||
TEST(RawTrace, Basic) {
|
||||
raw_trace_basic();
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) && !defined(__EMSCRIPTEN__)
|
||||
raw_trace_basic_precise();
|
||||
#endif
|
||||
[[maybe_unused]] volatile int x = 0; // prevent raw_trace_basic_precise() above being a jmp
|
||||
@ -80,7 +80,7 @@ CPPTRACE_FORCE_NO_INLINE void record_parent(uintptr_t low_bound, uintptr_t high_
|
||||
parents.insert(parents.begin(), {low_bound, high_bound});
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) && !defined(__EMSCRIPTEN__)
|
||||
CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_3() {
|
||||
a:
|
||||
auto raw_trace = cpptrace::generate_raw_trace();
|
||||
@ -161,7 +161,7 @@ CPPTRACE_FORCE_NO_INLINE void raw_trace_multi_precise_1() {
|
||||
TEST(RawTrace, MultipleCalls) {
|
||||
parents.clear();
|
||||
raw_trace_multi_1();
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) && !defined(__EMSCRIPTEN__)
|
||||
raw_trace_multi_precise_1();
|
||||
#endif
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user