[Python-checkins] bpo-44895: Introduce PYTHONDUMPREFSFILE variable for refcount dumping (GH-27767)
corona10
webhook-mailer at python.org
Tue Aug 17 11:53:04 EDT 2021
https://github.com/python/cpython/commit/c2c857b40f226575d64e0d56a759cbd799f51e62
commit: c2c857b40f226575d64e0d56a759cbd799f51e62
branch: main
author: Dong-hee Na <donghee.na92 at gmail.com>
committer: corona10 <donghee.na92 at gmail.com>
date: 2021-08-18T00:52:50+09:00
summary:
bpo-44895: Introduce PYTHONDUMPREFSFILE variable for refcount dumping (GH-27767)
files:
A Misc/NEWS.d/next/Core and Builtins/2021-08-14-20-13-21.bpo-44895.Ic9m90.rst
M Doc/using/cmdline.rst
M Include/cpython/initconfig.h
M Python/initconfig.c
M Python/pylifecycle.c
diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
index 9e391604a1a59d..7ebc34f47fc39b 100644
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -975,3 +975,12 @@ Debug-mode variables
shutting down the interpreter.
Need Python configured with the :option:`--with-trace-refs` build option.
+
+.. envvar:: PYTHONDUMPREFSFILE=FILENAME
+
+ If set, Python will dump objects and reference counts still alive
+ after shutting down the interpreter into a file called *FILENAME*.
+
+ Need Python configured with the :option:`--with-trace-refs` build option.
+
+ .. versionadded:: 3.11
diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h
index 5f03b8c57f8bc8..22ad0f14e58004 100644
--- a/Include/cpython/initconfig.h
+++ b/Include/cpython/initconfig.h
@@ -143,6 +143,7 @@ typedef struct PyConfig {
int no_debug_ranges;
int show_ref_count;
int dump_refs;
+ wchar_t *dump_refs_file;
int malloc_stats;
wchar_t *filesystem_encoding;
wchar_t *filesystem_errors;
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-08-14-20-13-21.bpo-44895.Ic9m90.rst b/Misc/NEWS.d/next/Core and Builtins/2021-08-14-20-13-21.bpo-44895.Ic9m90.rst
new file mode 100644
index 00000000000000..d369ac76505974
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-08-14-20-13-21.bpo-44895.Ic9m90.rst
@@ -0,0 +1,2 @@
+A debug variable :envvar:`PYTHONDUMPREFSFILE` is added for creating a dump file
+which is generated by :option:`--with-trace-refs`. Patch by Dong-hee Na.
diff --git a/Python/initconfig.c b/Python/initconfig.c
index d328f227cead25..61cd0e6213ed17 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -898,6 +898,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
COPY_ATTR(no_debug_ranges);
COPY_ATTR(show_ref_count);
COPY_ATTR(dump_refs);
+ COPY_ATTR(dump_refs_file);
COPY_ATTR(malloc_stats);
COPY_WSTR_ATTR(pycache_prefix);
@@ -1701,6 +1702,14 @@ config_read_env_vars(PyConfig *config)
config->malloc_stats = 1;
}
+ if (config->dump_refs_file == NULL) {
+ status = CONFIG_GET_ENV_DUP(config, &config->dump_refs_file,
+ L"PYTHONDUMPREFSFILE", "PYTHONDUMPREFSFILE");
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+
if (config->pythonpath_env == NULL) {
status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env,
L"PYTHONPATH", "PYTHONPATH");
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index eeaf20b4617a20..f3b6b0ac68a1ea 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1737,6 +1737,7 @@ Py_FinalizeEx(void)
#endif
#ifdef Py_TRACE_REFS
int dump_refs = tstate->interp->config.dump_refs;
+ wchar_t *dump_refs_file = tstate->interp->config.dump_refs_file;
#endif
#ifdef WITH_PYMALLOC
int malloc_stats = tstate->interp->config.malloc_stats;
@@ -1835,9 +1836,22 @@ Py_FinalizeEx(void)
* Alas, a lot of stuff may still be alive now that will be cleaned
* up later.
*/
+
+ FILE *dump_refs_fp = NULL;
+ if (dump_refs_file != NULL) {
+ dump_refs_fp = _Py_wfopen(dump_refs_file, L"w");
+ if (dump_refs_fp == NULL) {
+ fprintf(stderr, "PYTHONDUMPREFSFILE: cannot create file: %ls\n", dump_refs_file);
+ }
+ }
+
if (dump_refs) {
_Py_PrintReferences(stderr);
}
+
+ if (dump_refs_fp != NULL) {
+ _Py_PrintReferences(dump_refs_fp);
+ }
#endif /* Py_TRACE_REFS */
finalize_interp_clear(tstate);
@@ -1848,9 +1862,15 @@ Py_FinalizeEx(void)
* An address can be used to find the repr of the object, printed
* above by _Py_PrintReferences.
*/
+
if (dump_refs) {
_Py_PrintReferenceAddresses(stderr);
}
+
+ if (dump_refs_fp != NULL) {
+ _Py_PrintReferenceAddresses(dump_refs_fp);
+ fclose(dump_refs_fp);
+ }
#endif /* Py_TRACE_REFS */
#ifdef WITH_PYMALLOC
if (malloc_stats) {
More information about the Python-checkins
mailing list