Skip to content

Commit 3766fed

Browse files
godlygeekpablogsal
authored andcommitted
Create TLS vars before installing fork handlers
The fork handlers now depend (at least on macOS) on calling `pthread_getspecific` and `pthread_setspecific` for our recursion guard, we need to ensure that the TLS key has been created before we install our fork handlers. Signed-off-by: Matt Wozniski <[email protected]>
1 parent cc80cc2 commit 3766fed

File tree

4 files changed

+21
-12
lines changed

4 files changed

+21
-12
lines changed

src/memray/_memray.pyx

+2-5
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ from _memray.source cimport FileSource
5555
from _memray.source cimport SocketSource
5656
from _memray.tracking_api cimport Tracker as NativeTracker
5757
from _memray.tracking_api cimport install_trace_function
58+
from _memray.tracking_api cimport set_up_pthread_fork_handlers
5859
from cpython cimport PyErr_CheckSignals
5960
from libc.math cimport ceil
6061
from libc.stdint cimport uint64_t
@@ -76,16 +77,12 @@ from ._metadata import Metadata
7677
from ._stats import Stats
7778
from ._thread_name_interceptor import ThreadNameInterceptor
7879

79-
80-
cdef extern from "pthread.h" nogil:
81-
int pthread_atfork(void (*prepare)(), void (*parent)(), void (*child)())
82-
8380
# NOTE: We can't reinitialize tracking in a child process until the interpreter
8481
# has reinitialized its locks, so we do it in a Python fork handler.
8582
# But, Python fork handlers aren't guaranteed to run for every fork, and
8683
# the child process must never inherit an active tracker, so we must use
8784
# a pthread fork handler to disable tracking before forking.
88-
pthread_atfork(&NativeTracker.prepareFork, &NativeTracker.parentFork, NULL)
85+
set_up_pthread_fork_handlers()
8986
os.register_at_fork(after_in_child=NativeTracker.childFork)
9087

9188

src/memray/_memray/tracking_api.cpp

+12-1
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,6 @@ Tracker::Tracker(
559559
{
560560
static std::once_flag once;
561561
call_once(once, [] {
562-
RecursionGuard::initialize();
563562
// We use the pthread TLS API for this vector because we must be able
564563
// to re-create it while TLS destructors are running (a destructor can
565564
// call malloc, hitting our malloc hook). POSIX guarantees multiple
@@ -1235,6 +1234,18 @@ Tracker::handleGreenletSwitch(PyObject* from, PyObject* to)
12351234
PythonStackTracker::get().handleGreenletSwitch(from, to);
12361235
}
12371236

1237+
void
1238+
set_up_pthread_fork_handlers()
1239+
{
1240+
static std::once_flag once;
1241+
call_once(once, [] {
1242+
// On macOS the recursion guard uses pthread TLS keys, so we
1243+
// need to create those keys before we install our handlers.
1244+
RecursionGuard::initialize();
1245+
pthread_atfork(&Tracker::prepareFork, &Tracker::parentFork, NULL);
1246+
});
1247+
}
1248+
12381249
void
12391250
install_trace_function()
12401251
{

src/memray/_memray/tracking_api.h

+6
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ PyTraceTrampoline(PyObject* obj, PyFrameObject* frame, int what, PyObject* arg);
134134
void
135135
install_trace_function();
136136

137+
/**
138+
* Install our pthread fork handlers.
139+
*/
140+
void
141+
set_up_pthread_fork_handlers();
142+
137143
class NativeTrace
138144
{
139145
public:

src/memray/_memray/tracking_api.pxd

+1-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ from libcpp.string cimport string
66

77

88
cdef extern from "tracking_api.h" namespace "memray::tracking_api":
9+
void set_up_pthread_fork_handlers() except+
910
void install_trace_function() except*
1011

1112
cdef cppclass Tracker:
@@ -36,11 +37,5 @@ cdef extern from "tracking_api.h" namespace "memray::tracking_api":
3637
@staticmethod
3738
void registerThreadNameById(uint64_t, const char*) except+
3839

39-
@staticmethod
40-
void prepareFork() noexcept nogil
41-
42-
@staticmethod
43-
void parentFork() noexcept nogil
44-
4540
@staticmethod
4641
void childFork() noexcept nogil

0 commit comments

Comments
 (0)