Skip to content

Commit f4758c4

Browse files
committed
Provide heuristics for the user to provide a library to set tracing to all threads. Fixes microsoft#617
1 parent 02477b5 commit f4758c4

File tree

1 file changed

+76
-16
lines changed

1 file changed

+76
-16
lines changed

src/debugpy/_vendored/pydevd/pydevd_tracing.py

+76-16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from _pydev_imps._pydev_saved_modules import thread, threading
55
from _pydev_bundle import pydev_log, pydev_monkey
66
from os.path import os
7+
import platform
78
try:
89
import ctypes
910
except ImportError:
@@ -130,33 +131,92 @@ def _load_python_helper_lib_uncached():
130131
or hasattr(sys, 'gettotalrefcount') or LOAD_NATIVE_LIB_FLAG in ENV_FALSE_LOWER_VALUES):
131132
return None
132133

134+
libdir = os.path.join(os.path.dirname(__file__), 'pydevd_attach_to_process')
135+
136+
arch = ''
133137
if IS_WINDOWS:
134-
if IS_64BIT_PROCESS:
135-
suffix = 'amd64'
136-
else:
137-
suffix = 'x86'
138+
# prefer not using platform.machine() when possible (it's a bit heavyweight as it may
139+
# spawn a subprocess).
140+
arch = os.environ.get("PROCESSOR_ARCHITEW6432", os.environ.get('PROCESSOR_ARCHITECTURE', ''))
141+
142+
if not arch:
143+
arch = platform.machine()
144+
if not arch:
145+
pydev_log.info('platform.machine() did not return valid value.') # This shouldn't happen...
146+
return None
138147

139-
filename = os.path.join(os.path.dirname(__file__), 'pydevd_attach_to_process', 'attach_%s.dll' % (suffix,))
148+
if IS_WINDOWS:
149+
dllsuffix = '.dll'
140150

141151
elif IS_LINUX:
152+
dllsuffix = '.so'
153+
154+
elif IS_MAC:
155+
dllsuffix = '.dylib'
156+
157+
else:
158+
pydev_log.info('Unable to set trace to all threads in platform: %s', sys.platform)
159+
return None
160+
161+
if arch.lower() not in ('amd64', 'x86', 'x86_64', 'i386', 'x86'):
162+
# We don't support this processor by default. Still, let's support the case where the
163+
# user manually compiled it himself with some heuristics.
164+
#
165+
# Ideally the user would provide a library in the format: "attach_<arch>.<dllsuffix>"
166+
# based on the way it's currently compiled -- see:
167+
# - windows/compile_windows.bat
168+
# - linux_and_mac/compile_linux.sh
169+
# - linux_and_mac/compile_mac.sh
170+
171+
try:
172+
found = [name for name in os.listdir(libdir) if name.startswith('attach_') and name.endswith(dllsuffix)]
173+
except:
174+
pydev_log.exception('Error listing dir: %s', libdir)
175+
return None
176+
177+
expected_name = 'attach_' + arch + dllsuffix
178+
expected_name_linux = 'attach_linux_' + arch + dllsuffix
179+
180+
filename = None
181+
if expected_name in found: # Heuristic: user compiled with "attach_<arch>.<dllsuffix>"
182+
filename = os.path.join(libdir, expected_name)
183+
184+
elif IS_LINUX and expected_name_linux in found: # Heuristic: user compiled with "attach_linux_<arch>.<dllsuffix>"
185+
filename = os.path.join(libdir, expected_name_linux)
186+
187+
elif len(found) == 1: # Heuristic: user removed all libraries and just left his own lib.
188+
filename = os.path.join(libdir, found[0])
189+
190+
else: # Heuristic: there's one additional library which doesn't seem to be our own. Find the odd one.
191+
filtered = [name for name in found if not name.endswith(('amd64' + dllsuffix, 'x86' + dllsuffix))]
192+
if len(filtered) == 1: # If more than one is available we can't be sure...
193+
filename = os.path.join(libdir, found[0])
194+
195+
if filename is None:
196+
pydev_log.info(
197+
'Unable to set trace to all threads in arch: %s (did not find a %s lib in %s).', (
198+
arch, expected_name, libdir
199+
)
200+
)
201+
return None
202+
203+
pydev_log.info('Using %s lib in arch: %s.', filename, arch)
204+
205+
else:
142206
if IS_64BIT_PROCESS:
143207
suffix = 'amd64'
144208
else:
145209
suffix = 'x86'
146210

147-
filename = os.path.join(os.path.dirname(__file__), 'pydevd_attach_to_process', 'attach_linux_%s.so' % (suffix,))
148-
149-
elif IS_MAC:
150-
if IS_64BIT_PROCESS:
151-
suffix = 'x86_64.dylib'
211+
if IS_WINDOWS or IS_MAC: # just the dllsuffix changes
212+
prefix = 'attach_'
213+
elif IS_LINUX: #
214+
prefix = 'attach_linux_' # historically it has a different name
152215
else:
153-
suffix = 'x86.dylib'
154-
155-
filename = os.path.join(os.path.dirname(__file__), 'pydevd_attach_to_process', 'attach_%s' % (suffix,))
216+
pydev_log.info('Unable to set trace to all threads in platform: %s', sys.platform)
217+
return None
156218

157-
else:
158-
pydev_log.info('Unable to set trace to all threads in platform: %s', sys.platform)
159-
return None
219+
filename = os.path.join(libdir, '%s%s%s' % (prefix, suffix, dllsuffix))
160220

161221
if not os.path.exists(filename):
162222
pydev_log.critical('Expected: %s to exist.', filename)

0 commit comments

Comments
 (0)