From 9ba0fdc2964f1c42d013d40e0b81c421c1e02d97 Mon Sep 17 00:00:00 2001 From: Maxim Kokryashkin Date: Mon, 4 Dec 2023 21:26:04 +0300 Subject: [PATCH] bisect --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- src/lj_sysprof.c | 100 ++++++++++++++------------------------------- 3 files changed, 33 insertions(+), 71 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2638467abe..9f9a21713d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,7 +222,7 @@ else() CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" ) ) - AppendFlags(CMAKE_C_FLAGS -fno-omit-frame-pointer -fasynchronous-unwind-tables) + #AppendFlags(CMAKE_C_FLAGS -fno-omit-frame-pointer -fasynchronous-unwind-tables) if(ENABLE_BUNDLED_LUAJIT) AppendFlags(TARGET_C_FLAGS -DLUAJIT_EXTERNAL_SYSPROF_BACKTRACER) else() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index be7df569c2..bd8e21249d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -284,7 +284,7 @@ add_dependencies(core_shared buildvm_output) list(APPEND TARGET_LIBS m) -if(NOT LUAJIT_DISABLE_SYSPROF) +if(${LIBUNWIND_FOUND}) list(APPEND TARGET_LIBS ${LIBUNWIND_LIBRARIES}) endif() diff --git a/src/lj_sysprof.c b/src/lj_sysprof.c index b7b0b0608a..c6c20de289 100644 --- a/src/lj_sysprof.c +++ b/src/lj_sysprof.c @@ -26,17 +26,7 @@ #include #include - -#ifndef LUAJIT_EXTERNAL_SYSPROF_BACKTRACER -/* -** We only need local unwinding, then a special implementation -** can be selected which may run much faster than the generic -** implementation which supports both kinds of unwinding, local -** and remote. -*/ -#define UNW_LOCAL_ONLY -#include -#endif +#include /* ** Number of profiler frames we need to omit during stack @@ -95,56 +85,6 @@ static struct sysprof sysprof = {0}; /* --- Stream ------------------------------------------------------------- */ -#ifndef LUAJIT_EXTERNAL_SYSPROF_BACKTRACER - -static ssize_t collect_stack(void **buffer, int size) -{ - int frame_no = 0; - unw_context_t unw_ctx; - unw_cursor_t unw_cur; - - int rc = unw_getcontext(&unw_ctx); - if (rc != 0) - return -1; - - rc = unw_init_local(&unw_cur, &unw_ctx); - if (rc != 0) - return -1; - - for (; frame_no < size; ++frame_no) { - unw_word_t ip; - rc = unw_get_reg(&unw_cur, UNW_REG_IP, &ip); - if (rc != 0) - return -1; - - buffer[frame_no] = (void *)ip; - rc = unw_step(&unw_cur); - if (rc <= 0) - break; - } - return frame_no; -} - -static void default_backtrace_host(void *(writer)(int frame_no, void *addr)) -{ - static void *backtrace_buf[SYSPROF_BACKTRACE_FRAME_MAX] = {}; - - struct sysprof *sp = &sysprof; - int max_depth = sp->opt.mode == LUAM_SYSPROF_LEAF - ? SYSPROF_HANDLER_STACK_DEPTH + 1 - : SYSPROF_BACKTRACE_FRAME_MAX; - const int depth = collect_stack(backtrace_buf, max_depth); - int level; - - lj_assertX(depth <= max_depth, "backtrace is too deep"); - lj_assertX(depth != -1, "failed to collect backtrace"); - for (level = SYSPROF_HANDLER_STACK_DEPTH; level < depth; ++level) { - if (!writer(level - SYSPROF_HANDLER_STACK_DEPTH + 1, backtrace_buf[level])) - return; - } -} -#endif - static const uint8_t ljp_header[] = {'l', 'j', 'p', LJP_FORMAT_VERSION, 0x0, 0x0, 0x0}; @@ -265,6 +205,24 @@ static void *stream_frame_host(int frame_no, void *addr) return addr; } +static void default_backtrace_host(void *(writer)(int frame_no, void *addr)) +{ + static void *backtrace_buf[SYSPROF_BACKTRACE_FRAME_MAX] = {}; + + struct sysprof *sp = &sysprof; + int max_depth = sp->opt.mode == LUAM_SYSPROF_LEAF + ? SYSPROF_HANDLER_STACK_DEPTH + 1 + : SYSPROF_BACKTRACE_FRAME_MAX; + const int depth = backtrace(backtrace_buf, max_depth); + int level; + + lj_assertX(depth <= max_depth, "depth of C stack is too big"); + for (level = SYSPROF_HANDLER_STACK_DEPTH; level < depth; ++level) { + if (!writer(level - SYSPROF_HANDLER_STACK_DEPTH + 1, backtrace_buf[level])) + return; + } +} + static void stream_backtrace_host(struct sysprof *sp) { lj_assertX(sp->backtracer != NULL, "uninitialized sysprof backtracer"); @@ -469,16 +427,20 @@ int lj_sysprof_set_backtracer(luam_Sysprof_backtracer backtracer) { if (sp->state != SPS_IDLE) return PROFILE_ERRUSE; - - if (backtracer == NULL) -#ifndef LUAJIT_EXTERNAL_SYSPROF_BACKTRACER + if (backtracer == NULL) { sp->backtracer = default_backtrace_host; -#else - return PROFILE_ERRUSE; -#endif - else + /* + ** XXX: `backtrace` is not signal-safe, according to man, + ** because it is lazy loaded on the first call, which triggers + ** allocations. We need to call `backtrace` before starting profiling + ** to avoid lazy loading. + */ + void *dummy = NULL; + backtrace(&dummy, 1); + } + else { sp->backtracer = backtracer; - + } if (!is_unconfigured(sp)) { sp->state = SPS_IDLE; }