pystack 1.4.1__tar.gz → 1.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. {pystack-1.4.1 → pystack-1.6.0}/.bumpversion.cfg +1 -1
  2. {pystack-1.4.1 → pystack-1.6.0}/MANIFEST.in +0 -1
  3. {pystack-1.4.1 → pystack-1.6.0}/Makefile +1 -1
  4. {pystack-1.4.1 → pystack-1.6.0}/NEWS.rst +55 -0
  5. {pystack-1.4.1 → pystack-1.6.0}/PKG-INFO +11 -2
  6. {pystack-1.4.1 → pystack-1.6.0}/pyproject.toml +13 -25
  7. {pystack-1.4.1 → pystack-1.6.0}/setup.py +15 -2
  8. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/__main__.py +21 -6
  9. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/code.h +39 -0
  10. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/frame.h +26 -0
  11. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/gc.h +24 -0
  12. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/interpreter.h +78 -0
  13. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/runtime.h +217 -0
  14. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/string.h +18 -0
  15. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/thread.h +67 -0
  16. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/elf_common.cpp +6 -3
  17. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/elf_common.h +4 -1
  18. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/mem.cpp +119 -5
  19. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/mem.h +16 -1
  20. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/process.cpp +36 -5
  21. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/process.h +8 -0
  22. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pycode.cpp +31 -4
  23. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pycode.h +2 -1
  24. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pyframe.cpp +18 -5
  25. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pytypes.cpp +0 -1
  26. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pytypes.h +0 -3
  27. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/unwinder.cpp +2 -2
  28. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/version.cpp +259 -194
  29. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/version.h +1 -1
  30. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack.pyi +12 -11
  31. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack.pyx +1 -0
  32. pystack-1.6.0/src/pystack/_version.py +1 -0
  33. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/process.py +7 -4
  34. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/traceback_formatter.py +20 -6
  35. {pystack-1.4.1 → pystack-1.6.0}/src/pystack.egg-info/PKG-INFO +11 -2
  36. {pystack-1.4.1 → pystack-1.6.0}/src/pystack.egg-info/SOURCES.txt +0 -1
  37. pystack-1.4.1/build_scripts/elfutils_contiguous_segments.diff +0 -66
  38. pystack-1.4.1/src/pystack/_version.py +0 -1
  39. {pystack-1.4.1 → pystack-1.6.0}/.pre-commit-config.yaml +0 -0
  40. {pystack-1.4.1 → pystack-1.6.0}/LICENSE +0 -0
  41. {pystack-1.4.1 → pystack-1.6.0}/README.md +0 -0
  42. {pystack-1.4.1 → pystack-1.6.0}/setup.cfg +0 -0
  43. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/__init__.py +0 -0
  44. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/CMakeLists.txt +0 -0
  45. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/__init__.pxd +0 -0
  46. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/compat.h +0 -0
  47. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/corefile.cpp +0 -0
  48. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/corefile.h +0 -0
  49. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/corefile.pxd +0 -0
  50. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/dict.h +0 -0
  51. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/float.h +0 -0
  52. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/int.h +0 -0
  53. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/list.h +0 -0
  54. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/object.h +0 -0
  55. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/pthread.h +0 -0
  56. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/cpython/tuple.h +0 -0
  57. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/elf_common.pxd +0 -0
  58. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/logging.cpp +0 -0
  59. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/logging.h +0 -0
  60. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/logging.pxd +0 -0
  61. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/mem.pxd +0 -0
  62. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/native_frame.h +0 -0
  63. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/native_frame.pxd +0 -0
  64. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/process.pxd +0 -0
  65. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pycode.pxd +0 -0
  66. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pycompat.h +0 -0
  67. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pyframe.h +0 -0
  68. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pyframe.pxd +0 -0
  69. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pythread.cpp +0 -0
  70. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pythread.h +0 -0
  71. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/pythread.pxd +0 -0
  72. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/structure.h +0 -0
  73. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/_pystack/unwinder.h +0 -0
  74. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/colors.py +0 -0
  75. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/engine.py +0 -0
  76. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/errors.py +0 -0
  77. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/maps.py +0 -0
  78. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/py.typed +0 -0
  79. {pystack-1.4.1 → pystack-1.6.0}/src/pystack/types.py +0 -0
  80. {pystack-1.4.1 → pystack-1.6.0}/src/pystack.egg-info/dependency_links.txt +0 -0
  81. {pystack-1.4.1 → pystack-1.6.0}/src/pystack.egg-info/entry_points.txt +0 -0
  82. {pystack-1.4.1 → pystack-1.6.0}/src/pystack.egg-info/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 1.4.1
2
+ current_version = 1.6.0
3
3
  commit = True
4
4
  message =
5
5
  Prepare for {new_version} release
@@ -14,7 +14,6 @@ include README.md
14
14
  include src/pystack/py.typed
15
15
  include .bumpversion.cfg
16
16
  include .pre-commit-config.yaml
17
- include build_scripts/elfutils_contiguous_segments.diff
18
17
 
19
18
  recursive-include src/pystack/_pystack *
20
19
  recursive-include src/pystack *.py
@@ -71,7 +71,7 @@ valgrind: ## Run valgrind, with the correct configuration
71
71
  .PHONY: ccoverage
72
72
  ccoverage: ## Run the test suite, with C++ code coverage
73
73
  $(MAKE) clean
74
- CFLAGS="$(CFLAGS) -O0 -pg --coverage" $(MAKE) build
74
+ CFLAGS="$(CFLAGS) -O0 -pg --coverage" CXXFLAGS="$(CXXFLAGS) -O0 -pg --coverage" $(MAKE) build
75
75
  $(MAKE) check
76
76
  gcov -i build/*/src/pystack/_pystack -i -d
77
77
  lcov --capture --directory . --output-file cppcoverage.lcov
@@ -8,6 +8,61 @@ Changelog
8
8
 
9
9
  .. towncrier release notes start
10
10
 
11
+ pystack 1.6.0 (2026-01-25)
12
+ --------------------------
13
+
14
+ Features
15
+ ~~~~~~~~
16
+
17
+ - Provide wheels for free-threaded builds of Python 3.13 (#271)
18
+ - Add the Python 3.14 trove classifier to our package metadata (#269)
19
+ - Improve some error messages and log messages (#260, #258)
20
+
21
+
22
+ Bug Fixes
23
+ ~~~~~~~~~
24
+
25
+ - Fix handling of duplicate ``_PyRuntime`` symbols when ctypes mmaps a statically linked Python interpreter's binary in order to create a trampoline. Previously this led to "Invalid address in remote process" errors. (#258)
26
+
27
+
28
+ pystack 1.5.1 (2025-08-18)
29
+ --------------------------
30
+
31
+ Bug Fixes
32
+ ~~~~~~~~~
33
+
34
+ - Correct a bug in our GitHub Actions workflow that prevented artifacts for 1.5.0 from being uploaded to PyPI. No changes have been made to the PyStack code itself since 1.5.0 (#250)
35
+
36
+
37
+ pystack 1.5.0 (2025-08-18)
38
+ --------------------------
39
+
40
+ Features
41
+ ~~~~~~~~
42
+
43
+ - Add a new ``--native-last`` command line flag to only show the C frames after the last Python frame. (#182)
44
+ - Add support for Python 3.14 (#229)
45
+ - Support kernels that don't have CONFIG_CROSS_MEMORY_ATTACH set. (#240)
46
+
47
+
48
+ Deprecations and Removals
49
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
50
+
51
+ - We no longer provide x86-64 musllinux_1_1 wheels. The manylinux project dropped support for musllinux_1_1 on November 1st, 2024. (#237)
52
+ - We no longer provide Python 3.7 wheels. Python 3.7 has been end-of-life since June 2023. (#237)
53
+
54
+
55
+ Bug Fixes
56
+ ~~~~~~~~~
57
+
58
+ - Fix incorrect file offset calculation when analyzing ELF files with
59
+ non-standard ELF layouts. Previously, pystack would fail to correctly analyze
60
+ Python binaries that had non-standard ELF layouts (for example when compiled
61
+ with certain linker options). The fix properly accounts for PT_LOAD segment
62
+ mappings when calculating file offsets. (#220)
63
+ - Improve handling of core files where we cannot determine the executable. (#221)
64
+
65
+
11
66
  pystack 1.4.1 (2024-10-04)
12
67
  --------------------------
13
68
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pystack
3
- Version: 1.4.1
3
+ Version: 1.6.0
4
4
  Summary: Analysis of the stack of remote python processes
5
5
  Home-page: https://github.com/bloomberg/pystack
6
6
  Author: Pablo Galindo Salgado
@@ -13,11 +13,20 @@ Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
16
17
  Classifier: Programming Language :: Python :: Implementation :: CPython
17
18
  Classifier: Topic :: Software Development :: Debuggers
18
19
  Requires-Python: >=3.7.0
19
20
  Description-Content-Type: text/markdown
20
21
  License-File: LICENSE
22
+ Dynamic: author
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: home-page
27
+ Dynamic: license-file
28
+ Dynamic: requires-python
29
+ Dynamic: summary
21
30
 
22
31
  <p align="center">
23
32
  <img src="https://user-images.githubusercontent.com/11718525/226942590-de015c9a-4d5b-4960-9c42-8c1eac0845c1.png" width="70%">
@@ -46,19 +46,18 @@ underlines = "-~"
46
46
  build = ["cp38-*", "cp39-*", "cp310-*", "cp311-*"]
47
47
  manylinux-x86_64-image = "manylinux2014"
48
48
  manylinux-i686-image = "manylinux2014"
49
- musllinux-x86_64-image = "musllinux_1_1"
49
+ musllinux-x86_64-image = "musllinux_1_2"
50
50
  skip = "*-musllinux_aarch64"
51
51
 
52
52
  [tool.cibuildwheel.linux]
53
53
  before-all = [
54
- "yum install -y python-devel-2.7.5",
54
+ "yum install -y libzstd-devel",
55
55
  "cd /",
56
- "VERS=0.189",
56
+ "VERS=0.193",
57
57
  "curl https://sourceware.org/elfutils/ftp/$VERS/elfutils-$VERS.tar.bz2 > ./elfutils.tar.bz2",
58
58
  "tar -xf elfutils.tar.bz2",
59
59
  "cd elfutils-$VERS",
60
- "patch libdwfl/dwfl_segment_report_module.c < {package}/build_scripts/elfutils_contiguous_segments.diff",
61
- "CFLAGS='-w' ./configure --enable-libdebuginfod=dummy --disable-debuginfod --prefix=/usr --libdir=/usr/lib64",
60
+ "CFLAGS='-Wno-error -g -O3' CXXFLAGS='-Wno-error -g -O3' ./configure --disable-nls --enable-libdebuginfod=dummy --disable-debuginfod --with-zstd",
62
61
  "make install"
63
62
  ]
64
63
 
@@ -70,34 +69,22 @@ before-all = [
70
69
  # dependency of elfutils.
71
70
  "apk del gettext-dev glib-dev",
72
71
 
73
- # Build musl-fts from source. This is a build dependency of elfutils, but
74
- # isn't in the Alpine repos of the musllinux_1_1 image. The build steps come
75
- # from https://git.alpinelinux.org/aports/tree/main/musl-fts/APKBUILD
76
- # Setting PATH before calling boostrap.sh fixes an automake failure. I think
77
- # the failure may be caused by a different pkg-config in /usr/local/bin.
78
- "cd /",
79
- "apk add --update automake autoconf libtool",
80
- "VERS=1.2.7",
81
- "curl -L https://github.com/void-linux/musl-fts/archive/refs/tags/v$VERS.tar.gz > ./musl-fts.tar.gz",
82
- "tar -xf musl-fts.tar.gz",
83
- "cd musl-fts-$VERS",
84
- "PATH=/usr/bin:/bin ./bootstrap.sh",
85
- "CFLAGS=-fPIC ./configure --prefix=/usr",
86
- "make install",
87
-
88
72
  # Build the latest elfutils from source. The build steps come from
89
73
  # https://git.alpinelinux.org/aports/tree/main/elfutils, and the need to
90
74
  # set the FNM_EXTMATCH macro to get the build to succeed is seen here:
91
75
  # https://git.alpinelinux.org/aports/tree/main/elfutils/musl-macros.patch
92
76
  "cd /",
93
- "apk add --update argp-standalone bison bsd-compat-headers bzip2-dev flex-dev libtool linux-headers musl-libintl musl-obstack-dev xz-dev zlib-dev zstd-dev",
94
- "VERS=0.189",
77
+ "apk add --update argp-standalone bison bsd-compat-headers bzip2-dev flex-dev libtool linux-headers musl-fts-dev musl-libintl musl-obstack-dev xz-dev zlib-dev zstd-dev",
78
+ "VERS=0.193",
95
79
  "curl https://sourceware.org/elfutils/ftp/$VERS/elfutils-$VERS.tar.bz2 > ./elfutils.tar.bz2",
96
80
  "tar -xf elfutils.tar.bz2",
97
81
  "cd elfutils-$VERS",
98
- "patch libdwfl/dwfl_segment_report_module.c < {package}/build_scripts/elfutils_contiguous_segments.diff",
99
- "CFLAGS='-w -DFNM_EXTMATCH=0' ./configure --prefix=/usr --disable-nls --disable-libdebuginfod --disable-debuginfod --with-zstd",
100
- "make install"
82
+ "CFLAGS='-Wno-error -DFNM_EXTMATCH=0 -g -O3' CXXFLAGS='-Wno-error -g -O3' ./configure --disable-nls --enable-libdebuginfod=dummy --disable-debuginfod --with-zstd",
83
+ "make install",
84
+
85
+ # Reinstall libintl, as the Python interpreter requires it
86
+ "apk del musl-libintl",
87
+ "apk add libintl",
101
88
  ]
102
89
 
103
90
  [tool.coverage.run]
@@ -121,3 +108,4 @@ show_missing = true
121
108
  # pytest retains all temp files from the last 3 test suite runs by default.
122
109
  # Keep only ones for failed tests to avoid filling up a disk.
123
110
  tmp_path_retention_policy = "failed"
111
+ testpaths = ["tests"]
@@ -33,6 +33,7 @@ COMPILER_DIRECTIVES = {
33
33
  "cdivision": True,
34
34
  "c_string_type": "unicode",
35
35
  "c_string_encoding": "utf8",
36
+ "freethreading_compatible": True,
36
37
  }
37
38
 
38
39
  DEFINE_MACROS = []
@@ -50,6 +51,7 @@ if TEST_BUILD:
50
51
  "infer_types": True,
51
52
  "c_string_type": "unicode",
52
53
  "c_string_encoding": "utf8",
54
+ "freethreading_compatible": True,
53
55
  }
54
56
  DEFINE_MACROS.extend([("CYTHON_TRACE", "1"), ("CYTHON_TRACE_NOGIL", "1")])
55
57
 
@@ -64,6 +66,11 @@ except pkgconfig.PackageNotFoundError as e:
64
66
  print("Package Not Found", e)
65
67
  print("Falling back to static flags.")
66
68
 
69
+ if "define_macros" not in library_flags:
70
+ library_flags["define_macros"] = []
71
+
72
+ library_flags["define_macros"].extend(DEFINE_MACROS)
73
+
67
74
  PYSTACK_EXTENSION = setuptools.Extension(
68
75
  name="pystack._pystack",
69
76
  sources=[
@@ -83,7 +90,6 @@ PYSTACK_EXTENSION = setuptools.Extension(
83
90
  language="c++",
84
91
  extra_compile_args=["-std=c++17"],
85
92
  extra_link_args=["-std=c++17"],
86
- define_macros=DEFINE_MACROS,
87
93
  **library_flags,
88
94
  )
89
95
 
@@ -116,6 +122,7 @@ setuptools.setup(
116
122
  "Programming Language :: Python :: 3.11",
117
123
  "Programming Language :: Python :: 3.12",
118
124
  "Programming Language :: Python :: 3.13",
125
+ "Programming Language :: Python :: 3.14",
119
126
  "Programming Language :: Python :: Implementation :: CPython",
120
127
  "Topic :: Software Development :: Debuggers",
121
128
  ],
@@ -127,7 +134,13 @@ setuptools.setup(
127
134
  compiler_directives=COMPILER_DIRECTIVES,
128
135
  ),
129
136
  install_requires=install_requires,
130
- include_package_data=True,
137
+ include_package_data=False,
138
+ package_data={
139
+ "pystack": [
140
+ "pystack/*.pyi",
141
+ "pystack/*.typed",
142
+ ]
143
+ },
131
144
  entry_points={
132
145
  "console_scripts": ["pystack=pystack.__main__:main"],
133
146
  },
@@ -166,6 +166,15 @@ def generate_cli_parser() -> argparse.ArgumentParser:
166
166
  help="Include native (C) frames from threads not registered with "
167
167
  "the interpreter (implies --native)",
168
168
  )
169
+ remote_parser.add_argument(
170
+ "--native-last",
171
+ action="store_const",
172
+ dest="native_mode",
173
+ const=NativeReportingMode.LAST,
174
+ default=NativeReportingMode.OFF,
175
+ help="Include native (C) frames only after the last python frame "
176
+ "in the resulting stack trace",
177
+ )
169
178
  remote_parser.add_argument(
170
179
  "--locals",
171
180
  action="store_true",
@@ -212,6 +221,15 @@ def generate_cli_parser() -> argparse.ArgumentParser:
212
221
  help="Include native (C) frames from threads not registered with "
213
222
  "the interpreter (implies --native)",
214
223
  )
224
+ core_parser.add_argument(
225
+ "--native-last",
226
+ action="store_const",
227
+ dest="native_mode",
228
+ const=NativeReportingMode.LAST,
229
+ default=NativeReportingMode.OFF,
230
+ help="Include native (C) frames only after the last python frame "
231
+ "in the resulting stack trace",
232
+ )
215
233
  core_parser.add_argument(
216
234
  "--locals",
217
235
  action="store_true",
@@ -274,8 +292,7 @@ def process_remote(parser: argparse.ArgumentParser, args: argparse.Namespace) ->
274
292
  locals=args.locals,
275
293
  method=StackMethod.ALL if args.exhaustive else StackMethod.AUTO,
276
294
  ):
277
- native = args.native_mode != NativeReportingMode.OFF
278
- print_thread(thread, native)
295
+ print_thread(thread, args.native_mode)
279
296
 
280
297
 
281
298
  def format_psinfo_information(psinfo: Dict[str, Any]) -> str:
@@ -331,7 +348,7 @@ def process_core(parser: argparse.ArgumentParser, args: argparse.Namespace) -> N
331
348
  if args.executable is None:
332
349
  corefile_analyzer = CoreFileAnalyzer(corefile)
333
350
  executable = pathlib.Path(corefile_analyzer.extract_executable())
334
- if not executable.exists() or not is_elf(executable):
351
+ if not is_elf(executable):
335
352
  first_map = next(
336
353
  (
337
354
  map
@@ -343,7 +360,6 @@ def process_core(parser: argparse.ArgumentParser, args: argparse.Namespace) -> N
343
360
  if (
344
361
  first_map is not None
345
362
  and first_map.path is not None
346
- and first_map.path.exists()
347
363
  and is_elf(first_map.path)
348
364
  ):
349
365
  executable = first_map.path
@@ -406,8 +422,7 @@ def process_core(parser: argparse.ArgumentParser, args: argparse.Namespace) -> N
406
422
  locals=args.locals,
407
423
  method=StackMethod.ALL if args.exhaustive else StackMethod.AUTO,
408
424
  ):
409
- native = args.native_mode != NativeReportingMode.OFF
410
- print_thread(thread, native)
425
+ print_thread(thread, args.native_mode)
411
426
 
412
427
 
413
428
  if __name__ == "__main__": # pragma: no cover
@@ -197,4 +197,43 @@ typedef struct
197
197
  } PyCodeObject;
198
198
  } // namespace Python3_13
199
199
 
200
+ namespace Python3_14 {
201
+ typedef uint16_t _Py_CODEUNIT;
202
+
203
+ typedef struct
204
+ {
205
+ PyObject_VAR_HEAD PyObject* co_consts;
206
+ PyObject* co_names;
207
+ PyObject* co_exceptiontable;
208
+ int co_flags;
209
+ int co_argcount;
210
+ int co_posonlyargcount;
211
+ int co_kwonlyargcount;
212
+ int co_stacksize;
213
+ int co_firstlineno;
214
+ int co_nlocalsplus;
215
+ int co_framesize;
216
+ int co_nlocals;
217
+ int co_ncellvars;
218
+ int co_nfreevars;
219
+ uint32_t co_version;
220
+ PyObject* co_localsplusnames;
221
+ PyObject* co_localspluskinds;
222
+ PyObject* co_filename;
223
+ PyObject* co_name;
224
+ PyObject* co_qualname;
225
+ PyObject* co_linetable;
226
+ PyObject* co_weakreflist;
227
+ void* co_executors;
228
+ void* _co_cached;
229
+ uintptr_t _co_instrumentation_version;
230
+ void* _co_monitoring;
231
+ Py_ssize_t _co_unique_id;
232
+ int _co_firsttraceable;
233
+ void* co_extra;
234
+ /* deal with co_tlbc somehow */
235
+ char co_code_adaptive[1];
236
+ } PyCodeObject;
237
+ } // namespace Python3_14
238
+
200
239
  } // namespace pystack
@@ -126,4 +126,30 @@ typedef struct _interpreter_frame
126
126
 
127
127
  } // namespace Python3_12
128
128
 
129
+ namespace Python3_14 {
130
+
131
+ typedef union _PyStackRef {
132
+ uintptr_t bits;
133
+ } _PyStackRef;
134
+
135
+ typedef struct _interpreter_frame
136
+ {
137
+ _PyStackRef f_executable;
138
+ void* previous;
139
+ void* f_funcobj;
140
+ PyObject* f_globals;
141
+ PyObject* f_builtins;
142
+ PyObject* f_locals;
143
+ PyObject* frame_obj;
144
+ _Py_CODEUNIT* instr_ptr;
145
+ _PyStackRef stackpointer;
146
+ /* int32_t tlbc_index; */
147
+ uint16_t return_offset;
148
+ char owner;
149
+ uint8_t visited;
150
+ void* localsplus[1];
151
+ } PyFrameObject;
152
+
153
+ } // namespace Python3_14
154
+
129
155
  } // namespace pystack
@@ -82,4 +82,28 @@ struct _gc_runtime_state
82
82
  };
83
83
 
84
84
  } // namespace Python3_8
85
+
86
+ namespace Python3_14 {
87
+
88
+ struct _gc_runtime_state
89
+ {
90
+ PyObject* trash_delete_later;
91
+ int trash_delete_nesting;
92
+ int enabled;
93
+ int debug;
94
+ struct Python3_8::gc_generation young;
95
+ struct Python3_8::gc_generation old[2];
96
+ struct Python3_8::gc_generation permanent_generation;
97
+ struct gc_generation_stats generation_stats[NUM_GENERATIONS];
98
+ int collecting;
99
+ PyObject* garbage;
100
+ PyObject* callbacks;
101
+ Py_ssize_t heap_size;
102
+ Py_ssize_t work_to_do;
103
+ int visited_space;
104
+ int phase;
105
+ };
106
+
107
+ } // namespace Python3_14
108
+
85
109
  } // namespace pystack
@@ -338,4 +338,82 @@ typedef struct _is
338
338
  struct _import_state imports;
339
339
  } PyInterpreterState;
340
340
  } // namespace Python3_13
341
+
342
+ namespace Python3_14 {
343
+
344
+ struct _pythreadstate;
345
+
346
+ typedef struct
347
+ {
348
+ Python3_13::PyMutex mutex;
349
+ unsigned long long thread;
350
+ size_t level;
351
+ } _PyRecursiveMutex;
352
+
353
+ struct _import_state
354
+ {
355
+ PyObject* modules;
356
+ PyObject* modules_by_index;
357
+ PyObject* importlib;
358
+ int override_frozen_modules;
359
+ int override_multi_interp_extensions_check;
360
+ PyObject* import_func;
361
+ _PyRecursiveMutex lock;
362
+ /* diagnostic info in PyImport_ImportModuleLevelObject() */
363
+ struct
364
+ {
365
+ int import_level;
366
+ int64_t accumulated;
367
+ int header;
368
+ } find_and_load;
369
+ };
370
+
371
+ struct _gil_runtime_state
372
+ {
373
+ unsigned long interval;
374
+ struct _pythreadstate* last_holder;
375
+ int locked;
376
+ unsigned long switch_number;
377
+ pthread_cond_t cond;
378
+ pthread_cond_t mutex;
379
+ #ifdef FORCE_SWITCHING
380
+ pthread_cond_t switch_cond;
381
+ pthread_cond_t switch_mutex;
382
+ #endif
383
+ };
384
+
385
+ typedef struct _is
386
+ {
387
+ struct _ceval_state ceval;
388
+ void* _malloced;
389
+ struct _is* next;
390
+ int64_t id;
391
+ Py_ssize_t id_refcount;
392
+ int requires_idref;
393
+ long _whence;
394
+ int _initialized;
395
+ int _ready;
396
+ int finalizing;
397
+ uintptr_t last_restart_version;
398
+ struct pythreads
399
+ {
400
+ uint64_t next_unique_id;
401
+ struct _pythreadstate* head;
402
+ struct _pythreadstate* preallocated;
403
+ struct _pythreadstate* main;
404
+ Py_ssize_t count;
405
+ size_t stacksize;
406
+ } threads;
407
+ void* runtime;
408
+ struct _pythreadstate* _finalizing;
409
+ unsigned long _finalizing_id;
410
+ struct _gc_runtime_state gc;
411
+ PyObject* sysdict;
412
+ PyObject* builtins;
413
+ struct _import_state imports;
414
+ struct _gil_runtime_state _gil;
415
+ } PyInterpreterState;
416
+
417
+ } // namespace Python3_14
418
+
341
419
  } // namespace pystack