Skip to content

Commit b20eefd

Browse files
authored
[mypyc] Give more guidance about debugging segfaults in tests (#18475)
When a test case segfaults, detect it and print more information. Add more detail to developer docs about debugging segfaults, including some macOS specific information.
1 parent c9ed867 commit b20eefd

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

mypyc/doc/dev-intro.md

+21-6
Original file line numberDiff line numberDiff line change
@@ -376,28 +376,43 @@ If you experience a segfault, it's recommended to use a debugger that supports
376376
C, such as gdb or lldb, to look into the segfault.
377377

378378
If a test case segfaults, you can run tests using the debugger, so
379-
you can inspect the stack:
379+
you can inspect the stack. Example of inspecting the C stack when a
380+
test case segfaults (user input after `$` and `(gdb)` prompts):
380381

381382
```
382383
$ pytest mypyc -n0 -s --mypyc-debug=gdb -k <name-of-test>
384+
...
385+
(gdb) r
386+
...
387+
Program received signal SIGSEGV, Segmentation fault.
388+
...
389+
(gdb) bt
390+
#0 0x00005555556ed1a2 in _PyObject_HashFast (op=0x0) at ./Include/object.h:336
391+
#1 PyDict_GetItemWithError (op=0x7ffff6c894c0, key=0x0) at Objects/dictobject.c:2394
392+
...
383393
```
384394

385395
You must use `-n0 -s` to enable interactive input to the debugger.
386-
Instad of `gdb`, you can also try `lldb`.
396+
Instad of `gdb`, you can also try `lldb` (especially on macOS).
387397

388398
To get better C stack tracebacks and more assertions in the Python
389-
runtime, you can build Python in debug mode and use that to run tests
390-
or debug outside the test framework.
399+
runtime, you can build Python in debug mode and use that to run tests,
400+
or to manually run the debugger outside the test framework.
391401

392-
Here are some hints that may help (for Ubuntu):
402+
**Note:** You may need to build Python yourself on macOS, as official
403+
Python builds may not have sufficient entitlements to use a debugger.
404+
405+
Here are some hints about building a debug version of CPython that may
406+
help (for Ubuntu, macOS is mostly similar except for installing build
407+
dependencies):
393408

394409
```
395410
$ sudo apt install gdb build-essential libncursesw5-dev libssl-dev libgdbm-dev libc6-dev libsqlite3-dev libbz2-dev libffi-dev libgdbm-compat-dev
396411
$ <download Python tarball and extract it>
397412
$ cd Python-3.XX.Y
398413
$ ./configure --with-pydebug
399414
$ make -s -j16
400-
$ ./python -m venv ~/<venv-location>
415+
$ ./python -m venv ~/<venv-location> # Use ./python.exe -m venv ... on macOS
401416
$ source ~/<venv-location>/bin/activate
402417
$ cd <mypy-repo-dir>
403418
$ pip install -r test-requirements.txt

mypyc/test/test_run.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,22 @@ def run_case_step(self, testcase: DataDrivenTestCase, incremental_step: int) ->
328328
show_c(cfiles)
329329
if proc.returncode != 0:
330330
print()
331-
print("*** Exit status: %d" % proc.returncode)
331+
signal = proc.returncode == -11
332+
extra = ""
333+
if signal:
334+
extra = " (likely segmentation fault)"
335+
print(f"*** Exit status: {proc.returncode}{extra}")
336+
if signal and not sys.platform.startswith("win"):
337+
print()
338+
if sys.platform == "darwin":
339+
debugger = "lldb"
340+
else:
341+
debugger = "gdb"
342+
print(
343+
f'hint: Use "pytest -n0 -s --mypyc-debug={debugger} -k <name-substring>" to run test in debugger'
344+
)
345+
print("hint: You may need to build a debug version of Python first and use it")
346+
print('hint: See also "Debuggging Segfaults" in mypyc/doc/dev-intro.md')
332347

333348
# Verify output.
334349
if bench:

0 commit comments

Comments
 (0)