Skip to content

fix(profiling): re-initialise string tables post-fork [backport 4.8]#18531

Merged
KowalskiThomas merged 1 commit into
4.8from
backport-18063-to-4.8
Jun 9, 2026
Merged

fix(profiling): re-initialise string tables post-fork [backport 4.8]#18531
KowalskiThomas merged 1 commit into
4.8from
backport-18063-to-4.8

Conversation

@dd-octo-sts

@dd-octo-sts dd-octo-sts Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Backport #18063 to 4.8

## Description

This PR ensures we clear the string tables post-fork. This is meant to address a crash happening on (at least) 4.8.0rc5.

```
Error UnixSignal: Process terminated with SEGV_MAPERR (SIGSEGV)
#0   0x0000000000000000 std::__detail::_Hashtable_base<unsigned long, std::pair<unsigned long const, std::string>, std::__detail::_Select1st, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<false, false, true> >::_M_equals(unsigned long const&, unsigned long, std::__detail::_Hash_node<std::pair<unsigned long const, std::string>, false>*) const (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/hashtable_policy.h:1804)
#1   0x000073afd44ec124 std::__detail::_Hashtable_base<unsigned long, std::pair<unsigned long const, std::string>, std::__detail::_Select1st, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<false, false, true> >::_M_equals(unsigned long const&, unsigned long, std::__detail::_Hash_node<std::pair<unsigned long const, std::string>, false>*) const (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/hashtable_policy.h:1804)
#2   0x000073afd44ec124 std::_Hashtable<unsigned long, std::pair<unsigned long const, std::string>, std::allocator<std::pair<unsigned long const, std::string> >, std::__detail::_Select1st, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_find_before_node(unsigned long, unsigned long const&, unsigned long) const [clone .constprop.0] (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/hashtable.h:1580)
#3   0x000073afd44ece4b std::_Hashtable<unsigned long, std::pair<unsigned long const, std::string>, std::allocator<std::pair<unsigned long const, std::string> >, std::__detail::_Select1st, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_find_node(unsigned long, unsigned long const&, unsigned long) const [clone .isra.0] (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/hashtable.h:694)
#4   0x0000000000000000 std::_Hashtable<unsigned long, std::pair<unsigned long const, std::string>, std::allocator<std::pair<unsigned long const, std::string> >, std::__detail::_Select1st, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::find(unsigned long const&) (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/hashtable.h:1455)
#5   0x0000000000000000 std::unordered_map<unsigned long, std::string, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, std::string> > >::find(unsigned long const&) (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/unordered_map.h:920)
#6   0x000073afd44e4e61 std::_Hashtable<unsigned long, std::pair<unsigned long const, std::string>, std::allocator<std::pair<unsigned long const, std::string> >, std::__detail::_Select1st, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::find(unsigned long const&) (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/hashtable.h:1455)
#7   0x000073afd44e4e61 std::unordered_map<unsigned long, std::string, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, std::string> > >::find(unsigned long const&) (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/unordered_map.h:920)
#8   0x000073afd44e4e61 StringTable::key(_object*, StringTag) (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/echion/strings.cc:58)
#9   0x000073afd44e517f Frame::create(EchionSampler&, PyCodeObject*, int) [clone .localalias] (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/echion/frame.cc:24)
#10  0x000073afd44e5436 Frame::get(EchionSampler&, PyCodeObject*, int) [clone .localalias] (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/echion/frame.cc:214)
#11  0x000073afd44e55b1 Frame::read(EchionSampler&, _PyInterpreterFrame*, _PyInterpreterFrame**) (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/echion/frame.cc:153)
#12  0x000073afd44e56c0 unwind_frame(EchionSampler&, _object*, FrameStack&, unsigned long) [clone .localalias] (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/echion/stacks.cc:56)
#13  0x000073afd44e5859 unwind_python_stack(EchionSampler&, _ts*, FrameStack&) (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/echion/stacks.cc:103)
#14  0x000073afd44e7bbf ThreadInfo::unwind(EchionSampler&, _ts*) [clone .localalias] (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/echion/threads.cc:15)
#15  0x0000000000000000 __gnu_cxx::__normal_iterator<std::unique_ptr<StackInfo, std::default_delete<StackInfo> > const*, std::vector<std::unique_ptr<StackInfo, std::default_delete<StackInfo> >, std::allocator<std::unique_ptr<StackInfo, std::default_delete<StackInfo> > > > >::__normal_iterator(std::unique_ptr<StackInfo, std::default_delete<StackInfo> > const* const&) (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_iterator.h:979)
#16  0x0000000000000000 std::vector<std::unique_ptr<StackInfo, std::default_delete<StackInfo> >, std::allocator<std::unique_ptr<StackInfo, std::default_delete<StackInfo> > > >::end() const (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_vector.h:839)
#17  0x0000000000000000 std::vector<std::unique_ptr<StackInfo, std::default_delete<StackInfo> >, std::allocator<std::unique_ptr<StackInfo, std::default_delete<StackInfo> > > >::empty() const (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_vector.h:1008)
#18  0x000073afd44eb2eb __gnu_cxx::__normal_iterator<std::unique_ptr<StackInfo, std::default_delete<StackInfo> > const*, std::vector<std::unique_ptr<StackInfo, std::default_delete<StackInfo> >, std::allocator<std::unique_ptr<StackInfo, std::default_delete<StackInfo> > > > >::__normal_iterator(std::unique_ptr<StackInfo, std::default_delete<StackInfo> > const* const&) (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_iterator.h:979)
#19  0x000073afd44eb2eb std::vector<std::unique_ptr<StackInfo, std::default_delete<StackInfo> >, std::allocator<std::unique_ptr<StackInfo, std::default_delete<StackInfo> > > >::end() const (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_vector.h:839)
#20  0x000073afd44eb2eb std::vector<std::unique_ptr<StackInfo, std::default_delete<StackInfo> >, std::allocator<std::unique_ptr<StackInfo, std::default_delete<StackInfo> > > >::empty() const (/opt/rh/devtoolset-10/root/usr/include/c++/10/bits/stl_vector.h:1008)
#21  0x000073afd44eb2eb ThreadInfo::sample(EchionSampler&, _ts*, long) (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/echion/threads.cc:698)
#22  0x000073afd44eb789 Datadog::Sampler::sampling_thread(unsigned long) [clone .localalias] (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/sampler.cpp:287)
#23  0x000073afd44ebad0 call_sampling_thread(void*) (/go/src/github.com/DataDog/apm-reliability/dd-trace-py/ddtrace/internal/datadog/profiling/stack/src/sampler.cpp:45)
#24  0x000073afdf06bac3 start_thread (nptl/nptl/pthread_create.c:442)
#25  0x000073afdf0fd8d0 __clone3
```

Co-authored-by: thomas.kowalski <thomas.kowalski@datadoghq.com>
(cherry picked from commit f1f6901)

Co-authored-by: Thomas Kowalski <thomas.kowalski@datadoghq.com>
@dd-octo-sts dd-octo-sts Bot requested review from a team as code owners June 9, 2026 08:48
@dd-octo-sts dd-octo-sts Bot requested review from KowalskiThomas and taegyunkim and removed request for a team June 9, 2026 08:48
@cit-pr-commenter-54b7da

Copy link
Copy Markdown

Codeowners resolved as

ddtrace/internal/datadog/profiling/stack/echion/echion/strings.h        @DataDog/profiling-python
ddtrace/internal/datadog/profiling/stack/src/sampler.cpp                @DataDog/profiling-python
releasenotes/notes/profiling-fix-post-fork-crash-string-table-2b3c3c6749b2c102.yaml  @DataDog/apm-python

@KowalskiThomas KowalskiThomas enabled auto-merge (squash) June 9, 2026 08:50
@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 9dc0cf1 | Docs | Datadog PR Page | Give us feedback!

@KowalskiThomas KowalskiThomas merged commit cc24fb7 into 4.8 Jun 9, 2026
424 checks passed
@KowalskiThomas KowalskiThomas deleted the backport-18063-to-4.8 branch June 9, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant