tarantool / tarantool/tarantool

LuaJIT: replace `backtrace` with libunwind-based unwinder in sysprof

Open
#7,243 4 comments 1 reaction 1 assignee View on GitHub

@mkokryashkin is already working on this.

Since Jun 6, 2022.

2.10 luajit sysprof
Dominant language
Lua
Stars
3.7k
Forks
419
Avg merge
1d 23h
Merged PRs (30d)
88

Description

At the present moment, LuaJIT is built with -fomit-frame-pointer option and, moreover, the dynasm part uses the rbp register as a general purpose register. The man (3) backtrace clearly says the backtrace has certain assumptions about the stack:

These functions make some assumptions about how a function's  return  ad‐
dress is stored on the stack.  Note the following:

       *  Omission  of the frame pointers (as implied by any of gcc(1)'s nonzero
          optimization levels) may cause these assumptions to be violated.

       *  Inlined functions do not have stack frames.

       *  Tail-call optimization causes one stack frame to replace another.

       *  backtrace() and backtrace_symbols_fd() don't call malloc() explicitly,
          but  they are part of libgcc, which gets loaded dynamically when first
          used.  Dynamic loading usually triggers a call to malloc(3).   If  you
          need  certain  calls to these two functions to not allocate memory (in
          signal handlers, for example), you need to make sure libgcc is  loaded
          beforehand.

One can clearly see that LuaJIT doesn't meet the first assumption. Although, the -fomit-frame-pointer option can be replaced with the -fno-omit-frame-pointer option, there is no easy way to fix the violated assumption in the dynasm part.

Violation of that assumption leads to an invalid stack trace in the sysprof output and, sometimes, it causes a crash with the following core dump:

Module /home/maxim/Programming/luajit/build/src/luajit with build-id 2fb6cf5f0169ea599f31f0962a1a97bd808d6648
                Module /home/maxim/Programming/luajit/build/test/tarantool-tests/misclib-sysprof-capi/testsysprof.so with build-id199f17ab38a1f43a85692b07ab59d9fabb22523d
                Module linux-vdso.so.1 with build-id f9d8dc6bbf64b232d9edf275e424114037d46f1d
                Module ld-linux-x86-64.so.2 with build-id c09c6f50f6bcec73c64a0b4be77eadb8f7202410
                Module libc.so.6 with build-id 85766e9d8458b16e9c7ce6e07c712c02b8471dbc
                Module libgcc_s.so.1 with build-id 5d817452a709ca3a213341555ddcf446ecee37fa
                Module libm.so.6 with build-id 596b63a006a4386dcab30912d2b54a7a61827b07
                Stack trace of thread 5200:
                #0  0x00007f7a1bf49f68 x86_64_fallback_frame_state (libgcc_s.so.1 + 0xff68)
                #1  0x00007f7a1bf4bc84 _Unwind_Backtrace (libgcc_s.so.1 + 0x11c84)
                #2  0x00007f7a1be4f8a3 __backtrace (libc.so.6 + 0x11f8a3)
                #3  0x00005598c16e5935 n/a (/home/maxim/Programming/luajit/build/src/luajit + 0x4f935)
                ELF object binary architecture: AMD x86-64

I propose to add the -fasync-tables build option and replace the backtrace with a custom libunwind-based unwinder. Since libunwind makes use of the DWARF-tables, it will resolve the issue.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.