diff options
author | Chris Mihelich <cmihelic@google.com> | 2024-05-28 15:15:46 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-05-28 15:16:44 -0700 |
commit | 44e077d6660f06e5500a604b48f8c109396d6d0d (patch) | |
tree | 8b01a8d4e8c2a13e76a33476334e16613e23c378 /absl/debugging/internal | |
parent | 3ef92c6f375e71316c313a3f1a204c494cd3f762 (diff) |
Demangle thread_local helper functions.
PiperOrigin-RevId: 638039514
Change-Id: I623d87e91ebe0a1166fee175151179b61ef54249
Diffstat (limited to 'absl/debugging/internal')
-rw-r--r-- | absl/debugging/internal/demangle.cc | 27 | ||||
-rw-r--r-- | absl/debugging/internal/demangle_test.cc | 10 |
2 files changed, 33 insertions, 4 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 1290ff65..36713e77 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -1049,7 +1049,8 @@ static bool ParseOperatorName(State *state, int *arity) { // ::= TT <type> // ::= TI <type> // ::= TS <type> -// ::= TH <type> # thread-local +// ::= TW <name> # thread-local wrapper +// ::= TH <name> # thread-local initialization // ::= Tc <call-offset> <call-offset> <(base) encoding> // ::= GV <(object) name> // ::= T <call-offset> <(base) encoding> @@ -1062,13 +1063,31 @@ static bool ParseOperatorName(State *state, int *arity) { // ::= Th <call-offset> <(base) encoding> // ::= Tv <call-offset> <(base) encoding> // -// Note: we don't care much about them since they don't appear in -// stack traces. The are special data. +// Note: Most of these are special data, not functions that occur in stack +// traces. Exceptions are TW and TH, which denote functions supporting the +// thread_local feature. For these see: +// +// https://maskray.me/blog/2021-02-14-all-about-thread-local-storage static bool ParseSpecialName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; ParseState copy = state->parse_state; - if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTISH") && + + if (ParseTwoCharToken(state, "TW")) { + MaybeAppend(state, "thread-local wrapper routine for "); + if (ParseName(state)) return true; + state->parse_state = copy; + return false; + } + + if (ParseTwoCharToken(state, "TH")) { + MaybeAppend(state, "thread-local initialization routine for "); + if (ParseName(state)) return true; + state->parse_state = copy; + return false; + } + + if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTIS") && ParseType(state)) { return true; } diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 5fd50aff..a2586e34 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -631,6 +631,16 @@ TEST(Demangle, ReferenceQualifiedFunctionTypes) { EXPECT_STREQ("f()", tmp); } +TEST(Demangle, ThreadLocalWrappers) { + char tmp[80]; + + EXPECT_TRUE(Demangle("_ZTWN2ns3varE", tmp, sizeof(tmp))); + EXPECT_STREQ("thread-local wrapper routine for ns::var", tmp); + + EXPECT_TRUE(Demangle("_ZTHN2ns3varE", tmp, sizeof(tmp))); + EXPECT_STREQ("thread-local initialization routine for ns::var", tmp); +} + // Test one Rust symbol to exercise Demangle's delegation path. Rust demangling // itself is more thoroughly tested in demangle_rust_test.cc. TEST(Demangle, DelegatesToDemangleRustSymbolEncoding) { |