@@ -11,16 +11,6 @@ static __thread int in_stacktrace = 0;
11
11
#include <patchlevel.h>
12
12
#include <stdbool.h>
13
13
14
- #ifdef _WIN32
15
- #define DD_TRACE_INSTALLED_PREFIX "\\ddtrace\\"
16
- #define TESTS_PREFIX "\\tests\\"
17
- #define SITE_PACKAGES_PREFIX "\\site-packages\\"
18
- #else
19
- #define DD_TRACE_INSTALLED_PREFIX "/ddtrace/"
20
- #define TESTS_PREFIX "/tests/"
21
- #define SITE_PACKAGES_PREFIX "/site-packages/"
22
- #endif
23
-
24
14
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 11
25
15
#include <internal/pycore_frame.h>
26
16
#define GET_LINENO (frame ) PyFrame_GetLineNumber((PyFrameObject*)frame)
@@ -99,6 +89,10 @@ static ssize_t STDLIB_PATH_LEN = 0;
99
89
static char * PURELIB_PATH = NULL ;
100
90
static ssize_t PURELIB_PATH_LEN = 0 ;
101
91
92
+ // ddtrace module path
93
+ static char * DDTRACE_PATH = NULL ;
94
+ static ssize_t DDTRACE_PATH_LEN = 0 ;
95
+
102
96
static inline PyObject *
103
97
SAFE_GET_LOCALS (PyFrameObject * frame )
104
98
{
@@ -144,7 +138,7 @@ _is_special_frame(const char* filename)
144
138
static inline bool
145
139
_is_ddtrace_filename (const char * filename )
146
140
{
147
- return filename && strstr ( filename , DD_TRACE_INSTALLED_PREFIX ) != NULL && strstr (filename , TESTS_PREFIX ) == NULL ;
141
+ return filename && DDTRACE_PATH && strncmp (filename , DDTRACE_PATH , DDTRACE_PATH_LEN ) == 0 ;
148
142
}
149
143
150
144
static inline bool
@@ -189,6 +183,46 @@ get_sysconfig_path(const char* name)
189
183
return res ;
190
184
}
191
185
186
+ static char *
187
+ get_ddtrace_path ()
188
+ {
189
+ char * res = NULL ;
190
+ PyObject * ddtrace_mod = NULL ;
191
+ PyObject * path = NULL ;
192
+
193
+ ddtrace_mod = PyImport_ImportModule ("ddtrace" );
194
+ if (!ddtrace_mod ) {
195
+ goto exit ;
196
+ }
197
+
198
+ path = PyObject_GetAttrString (ddtrace_mod , "__file__" );
199
+ if (!path ) {
200
+ goto exit ;
201
+ }
202
+
203
+ const char * path_str = PyUnicode_AsUTF8 (path );
204
+ if (path_str ) {
205
+ // Remove /__init__.py from the end. Suffix is removed by length,
206
+ // so no need to check for Windows vs Unix path separator.
207
+ const int ddtrace_len = sizeof ("ddtrace" ) - 1 ;
208
+ const int suffix_len = sizeof ("/__init__.py" ) - 1 ;
209
+ const int path_len = strlen (path_str );
210
+ if (path_len < ddtrace_len + suffix_len ) {
211
+ goto exit ;
212
+ }
213
+ const char * ddtrace_part = path_str + path_len - ddtrace_len - suffix_len ;
214
+ if (strncmp (ddtrace_part , "ddtrace" , ddtrace_len ) != 0 ) {
215
+ goto exit ;
216
+ }
217
+ res = strndup (path_str , path_len - suffix_len );
218
+ }
219
+
220
+ exit :
221
+ Py_XDECREF (path );
222
+ Py_XDECREF (ddtrace_mod );
223
+ return res ;
224
+ }
225
+
192
226
/**
193
227
* Gets a reference to a PyFrameObject and walks up the stack until a relevant frame is found.
194
228
*
@@ -343,5 +377,9 @@ PyInit__stacktrace(void)
343
377
if (PURELIB_PATH ) {
344
378
PURELIB_PATH_LEN = strlen (PURELIB_PATH );
345
379
}
380
+ DDTRACE_PATH = get_ddtrace_path ();
381
+ if (DDTRACE_PATH ) {
382
+ DDTRACE_PATH_LEN = strlen (DDTRACE_PATH );
383
+ }
346
384
return m ;
347
385
}
0 commit comments