feat(pprof): switch CPU profiler to framehop unwinder (#9125)

* feat(pprof): switch CPU profiler to framehop unwinder

Replace the default libgcc-based unwinder in pprof-rs with the
framehop unwinder, which is designed to be async-signal-safe:

- framehop performs no heap allocation during unwinding
  (MustNotAllocateDuringUnwind)
- It handles prologue/epilogue interruption correctly
- It falls back to frame-pointer unwinding when CFI is unavailable
- It does not depend on libgcc's unwind implementation, which is
  documented as not signal-safe (see tikv/pprof-rs#36)

Bump pprof from 0.14 to 0.15 in all three consumers (common-pprof,
cmd, servers) to unify on a single version. pprof 0.15 also replaces
parking_lot with spin-rs to avoid a potential profiler deadlock (#268).

This addresses the libgcc_s.so.1 #GP crash observed in production
when CPU profiling is active, by eliminating the libgcc unwinder
from the signal handler path entirely.

Signed-off-by: Lei, HUANG <ratuthomm@gmail.com>

* fix(pprof): gate framehop-unwinder to supported targets

framehop-unwinder is only available on x86_64/aarch64 Linux/macOS.
Enabling it unconditionally for all Unix targets breaks the build on
riscv64 and other platforms: pprof disables its backtrace-rs fallback
when framehop-unwinder is set, but the framehop module is not compiled
on unsupported targets, leaving no TraceImpl implementation.

Split the pprof dependency: the base target.'cfg(unix)' block carries
the common features (flamegraph, prost-codec, protobuf), and a separate
target block adds framehop-unwinder only on supported targets.
Cargo unions features from both blocks on matching targets, so x86_64
and aarch64 Linux/macOS get the full feature set while other Unix
targets fall back to the default backtrace-rs implementation.

Addresses review comment discussion_r3987313632.

Signed-off-by: Lei, HUANG <ratuthomm@gmail.com>

---------

Signed-off-by: Lei, HUANG <ratuthomm@gmail.com>
(cherry picked from commit 21aed0371f)
Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com>
This commit is contained in:
Lei, HUANG
2026-09-14 14:36:05 +08:00
committed by discord9
parent b6e72d23f4
commit 658c30b15e
4 changed files with 113 additions and 28 deletions
Generated
+104 -25
View File
@@ -1187,7 +1187,7 @@ dependencies = [
"cfg-if",
"libc",
"miniz_oxide",
"object",
"object 0.36.7",
"rustc-demangle",
"windows-targets 0.52.6",
]
@@ -5151,7 +5151,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
"libc",
"windows-sys 0.60.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -5239,6 +5239,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "fallible-iterator"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "fallible-streaming-iterator"
version = "0.1.9"
@@ -5530,7 +5536,7 @@ checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
dependencies = [
"futures-core",
"futures-sink",
"spin",
"spin 0.9.8",
]
[[package]]
@@ -5576,6 +5582,20 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619"
[[package]]
name = "framehop"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a5a3f0acb82df800ca3aa50c0d60d286c5d13d4cfc3114b3a9663f13b032fe"
dependencies = [
"arrayvec",
"cfg-if",
"fallible-iterator 0.3.0",
"gimli",
"macho-unwind-info",
"pe-unwind-info",
]
[[package]]
name = "frontend"
version = "1.2.0"
@@ -5723,7 +5743,7 @@ checksum = "94e7099f6313ecacbe1256e8ff9d617b75d1bcb16a6fddef94866d225a01a14a"
dependencies = [
"io-lifetimes 2.0.4",
"rustix 1.0.7",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -6039,6 +6059,10 @@ name = "gimli"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
dependencies = [
"fallible-iterator 0.3.0",
"stable_deref_trait",
]
[[package]]
name = "git2"
@@ -7119,7 +7143,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20fd6de4ccfcc187e38bc21cfa543cb5a302cb86a8b114eb7f0bf0dc9f8ac00f"
dependencies = [
"io-lifetimes 3.0.1",
"windows-sys 0.60.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -7157,7 +7181,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi",
"libc",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -7716,7 +7740,7 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
dependencies = [
"spin",
"spin 0.9.8",
]
[[package]]
@@ -8205,6 +8229,17 @@ dependencies = [
"thiserror 1.0.69",
]
[[package]]
name = "macho-unwind-info"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb4bdc8b0ce69932332cf76d24af69c3a155242af95c226b2ab6c2e371ed1149"
dependencies = [
"thiserror 2.0.17",
"zerocopy",
"zerocopy-derive",
]
[[package]]
name = "mappings"
version = "0.7.1"
@@ -8321,6 +8356,15 @@ dependencies = [
"thiserror 1.0.69",
]
[[package]]
name = "memmap2"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
dependencies = [
"libc",
]
[[package]]
name = "memmap2"
version = "0.9.5"
@@ -8745,7 +8789,7 @@ dependencies = [
"httparse",
"memchr",
"mime",
"spin",
"spin 0.9.8",
"version_check",
]
@@ -9387,6 +9431,16 @@ dependencies = [
"objc2-core-foundation",
]
[[package]]
name = "object"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
dependencies = [
"flate2",
"memchr",
]
[[package]]
name = "object"
version = "0.36.7"
@@ -10465,6 +10519,19 @@ dependencies = [
"hmac 0.12.1",
]
[[package]]
name = "pe-unwind-info"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "500fa4cdeacd98997c5865e3d0d1cb8fe7e9d7d75ecc775e07989a433a9a9a59"
dependencies = [
"arrayvec",
"bitflags 2.12.1",
"thiserror 2.0.17",
"zerocopy",
"zerocopy-derive",
]
[[package]]
name = "peeking_take_while"
version = "1.0.0"
@@ -10978,7 +11045,7 @@ dependencies = [
"base64 0.22.1",
"byteorder",
"bytes",
"fallible-iterator",
"fallible-iterator 0.2.0",
"hmac 0.13.0",
"md-5 0.11.0",
"memchr",
@@ -10996,7 +11063,7 @@ dependencies = [
"array-init",
"bytes",
"chrono",
"fallible-iterator",
"fallible-iterator 0.2.0",
"postgres-protocol",
"serde_core",
"serde_json",
@@ -11019,30 +11086,33 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "pprof"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebbe2f8898beba44815fdc9e5a4ae9c929e21c5dc29b0c774a15555f7f58d6d0"
checksum = "38a01da47675efa7673b032bf8efd8214f1917d89685e07e395ab125ea42b187"
dependencies = [
"aligned-vec",
"backtrace",
"cfg-if",
"criterion 0.5.1",
"findshlibs",
"framehop",
"inferno 0.11.21",
"libc",
"log",
"memmap2 0.5.10",
"nix 0.26.4",
"object 0.29.0",
"once_cell",
"parking_lot 0.12.4",
"prost 0.12.6",
"prost-build 0.12.6",
"prost-derive 0.12.6",
"protobuf 2.28.0",
"protobuf 3.7.2",
"sha2 0.10.9",
"smallvec",
"spin 0.10.1",
"symbolic-demangle",
"tempfile",
"thiserror 1.0.69",
"thiserror 2.0.17",
]
[[package]]
@@ -11848,7 +11918,7 @@ dependencies = [
"once_cell",
"socket2 0.5.10",
"tracing",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -12806,7 +12876,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.4.15",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -12819,7 +12889,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.9.4",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -12910,7 +12980,7 @@ dependencies = [
"security-framework 3.7.0",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -13859,6 +13929,15 @@ dependencies = [
"lock_api",
]
[[package]]
name = "spin"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3"
dependencies = [
"lock_api",
]
[[package]]
name = "spki"
version = "0.7.3"
@@ -14209,7 +14288,7 @@ dependencies = [
"cfg-if",
"libc",
"psm",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -14486,7 +14565,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a1150bdda9314f6cfeeea801c23f5593c6e6a6c72e64f67e48d723a12b8efdb"
dependencies = [
"debugid",
"memmap2",
"memmap2 0.9.5",
"stable_deref_trait",
"uuid",
]
@@ -14649,7 +14728,7 @@ dependencies = [
"lru 0.16.4",
"lz4_flex 0.13.1",
"measure_time",
"memmap2",
"memmap2 0.9.5",
"once_cell",
"oneshot",
"rayon",
@@ -14818,7 +14897,7 @@ dependencies = [
"getrandom 0.3.4",
"once_cell",
"rustix 1.0.7",
"windows-sys 0.61.2",
"windows-sys 0.52.0",
]
[[package]]
@@ -15276,7 +15355,7 @@ dependencies = [
"async-trait",
"byteorder",
"bytes",
"fallible-iterator",
"fallible-iterator 0.2.0",
"futures-channel",
"futures-util",
"log",
@@ -17065,7 +17144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f3fd376f71958b862e7afb20cfe5a22830e1963462f3a17f49d82a6c1d1f42d"
dependencies = [
"bitflags 2.12.1",
"windows-sys 0.59.0",
"windows-sys 0.52.0",
]
[[package]]
+1 -1
View File
@@ -118,7 +118,7 @@ tonic.workspace = true
tracing-appender.workspace = true
[target.'cfg(unix)'.dependencies]
pprof = { version = "0.14", features = [
pprof = { version = "0.15", features = [
"flamegraph",
] }
+7 -1
View File
@@ -11,11 +11,17 @@ snafu.workspace = true
tokio.workspace = true
[target.'cfg(unix)'.dependencies]
pprof = { version = "0.14", features = [
pprof = { version = "0.15", features = [
"flamegraph",
"prost-codec",
"protobuf",
] }
# framehop-unwinder is only available on x86_64/aarch64 Linux/macOS.
# Enabling it on other targets (e.g. riscv64) would disable the
# backtrace-rs fallback without providing a TraceImpl, breaking the build.
[target.'cfg(all(unix, any(target_arch = "x86_64", target_arch = "aarch64"), any(target_os = "linux", target_os = "macos")))'.dependencies]
pprof = { version = "0.15", features = ["framehop-unwinder"] }
[lints]
workspace = true
+1 -1
View File
@@ -171,7 +171,7 @@ tokio-postgres.workspace = true
tokio-postgres-rustls = "0.14"
[target.'cfg(unix)'.dev-dependencies]
pprof = { version = "0.14", features = ["criterion", "flamegraph"] }
pprof = { version = "0.15", features = ["criterion", "flamegraph"] }
[build-dependencies]
common-version.workspace = true