Disable omitting frame pointers for simpler unwind by azat · Pull Request #103811 · ClickHouse/ClickHouse · GitHub
Skip to content

Disable omitting frame pointers for simpler unwind#103811

Draft
azat wants to merge 3 commits into
ClickHouse:masterfrom
azat:no-omit-fp
Draft

Disable omitting frame pointers for simpler unwind#103811
azat wants to merge 3 commits into
ClickHouse:masterfrom
azat:no-omit-fp

Conversation

@azat

@azat azat commented Apr 30, 2026

Copy link
Copy Markdown
Member

Changelog category (leave one):

  • Performance Improvement

Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):

Disable omitting frame pointers for simpler unwind

Although it is not a problem in ClickHouse, since we use libunwind that handles this well, it is a problem for perf, or if we will want to use eBPF to do some performance analysis (to avoid overhead in the clickhouse-server process), though there are also other options 1.

Refs: https://www.brendangregg.com/blog/2024-03-17/the-return-of-the-frame-pointers.html

Although it is not a problem in ClickHouse, since we use libunwind that
handles this well, it is a problem for perf, or if we will want to use
eBPF to do some performance analysis (to avoid overhead in the
clickhouse-server process), though there are also other options [1].

  [1]: parca-dev/parca-agent#948

Refs: https://www.brendangregg.com/blog/2024-03-17/the-return-of-the-frame-pointers.html
@clickhouse-gh

clickhouse-gh Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

@clickhouse-gh clickhouse-gh Bot added the pr-performance Pull request with some performance improvements label Apr 30, 2026
Comment thread CMakeLists.txt
set (CMAKE_C_FLAGS_ADD "${CMAKE_C_FLAGS_ADD} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer")
set (CMAKE_ASM_FLAGS_ADD "${CMAKE_ASM_FLAGS_ADD} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer")
endif()
set (CMAKE_CXX_FLAGS_ADD "${CMAKE_CXX_FLAGS_ADD} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making frame-pointer preservation unconditional for every build removes the previous opt-in behavior and will impose a permanent runtime overhead for production users (historically this cost is measurable in CPU-heavy workloads). Please keep a CMake switch so packagers/operators can choose this trade-off, for example defaulting to ON in CI/profiling builds but allowing explicit opt-out in throughput-sensitive deployments.

@EmeraldShift

Copy link
Copy Markdown
Contributor

Enabling frame pointers is a nice move for easy debuggability with perf and existing continuous profiling infrastructure! Some notes:

  1. Maybe it should be optional? I am personally happy to pay a 1-5% performance cost to ensure I can easily and with low overhead run perf to find out what's costing CPU. But maybe other customers will be fine with the libunwind-based sampling profiler and rather not pay the frame pointer tax.
  2. That said, you might not have to pay the frame pointer tax forever! There is an upcoming technology SFrame that compiles a more efficient set of debug info into the program, and Linux and perf are in the process of supporting it. Maybe it will be ready for use, and can replace frame pointers, in a year?

@azat

azat commented May 4, 2026

Copy link
Copy Markdown
Member Author

Enabling frame pointers is a nice move for easy debuggability with perf and existing continuous profiling infrastructure!

Yes, this is the reason, though there are other options to overcome this:

Maybe it should be optional?

It was optional already

I am personally happy to pay a 1-5% performance cost to ensure I can easily and with low overhead run perf to find out what's costing CPU. But maybe other customers will be fine with the libunwind-based sampling profiler and rather not pay the frame pointer tax.

This is just an experiment, if the performance cost will be visible it will not be applied

That said, you might not have to pay the frame pointer tax forever! There is an upcoming technology SFrame that compiles a more efficient set of debug info into the program, and Linux and perf are in the process of supporting it. Maybe it will be ready for use, and can replace frame pointers, in a year?

Yes, this is not that new format AFAIR, and does it support is a good idea right now is an open question.

<uncompressed_cache_size>1000000000</uncompressed_cache_size>
<asynchronous_metrics_update_period_s>10</asynchronous_metrics_update_period_s>
<remap_executable replace="replace">true</remap_executable>
<!-- FIXME: Broken w/o omitting frame pointers -->

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is a bit confusing as written: w/o omitting frame pointers reads ambiguously and can be interpreted in the opposite way. Please reword it explicitly (for example, Broken with frame pointers enabled) so future maintainers can immediately understand the condition.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This FIXME means the new always-on frame-pointer policy is known to break remap_executable, but the PR only turns the setting off in the performance harness. Server.cpp still accepts remap_executable=true and calls remapExecutable, and ServerSettings.cpp still documents the setting, so users can still enable a combination this PR already knows is broken at startup. Please either make remapExecutable work with frame-pointer builds or reject remap_executable=true explicitly and document that restriction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

make it worse pr-performance Pull request with some performance improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants