summaryrefslogtreecommitdiff
path: root/absl/debugging/internal
diff options
context:
space:
mode:
authorGravatar Chris Mihelich <cmihelic@google.com>2024-05-28 15:15:46 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2024-05-28 15:16:44 -0700
commit44e077d6660f06e5500a604b48f8c109396d6d0d (patch)
tree8b01a8d4e8c2a13e76a33476334e16613e23c378 /absl/debugging/internal
parent3ef92c6f375e71316c313a3f1a204c494cd3f762 (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.cc27
-rw-r--r--absl/debugging/internal/demangle_test.cc10
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) {