From b0edcd4c405bef6e8063379a4e23643cdc789554 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 14 Aug 2021 19:36:44 +0900 Subject: [PATCH 1/9] bpo-44895: Introduce PYTHONDUMPFILE variable for refcount dumping --- Doc/using/cmdline.rst | 7 +++++++ Include/cpython/initconfig.h | 1 + .../2021-08-14-20-13-21.bpo-44895.Ic9m90.rst | 2 ++ Python/initconfig.c | 5 +++++ Python/pylifecycle.c | 16 ++++++++++++++-- 5 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-08-14-20-13-21.bpo-44895.Ic9m90.rst diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 9e391604a1a59df..32e5bf370322127 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -975,3 +975,10 @@ Debug-mode variables shutting down the interpreter. Need Python configured with the :option:`--with-trace-refs` build option. + +.. envvar:: PYTHONDUMPFILE + + If set, Python will create a file 'cpython-tracerefs-.dump` as dump file + which is generated by :envvar:`PYTHONDUMPREFS`. + + Need Python configured with the :option:`--with-trace-refs` build option. diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 5f03b8c57f8bc82..538234722e7eaad 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -144,6 +144,7 @@ typedef struct PyConfig { int show_ref_count; int dump_refs; int malloc_stats; + int dump_file; wchar_t *filesystem_encoding; wchar_t *filesystem_errors; wchar_t *pycache_prefix; 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 000000000000000..195bb330fd0d26d --- /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:`PYTHONDUMPFILE` is added for creating a dump file +which is generated by :envvar:`PYTHONDUMPREFS`. Patch by Dong-hee Na. diff --git a/Python/initconfig.c b/Python/initconfig.c index d328f227cead258..d11aa57a36d3e9e 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -611,6 +611,7 @@ config_check_consistency(const PyConfig *config) assert(config->show_ref_count >= 0); assert(config->dump_refs >= 0); assert(config->malloc_stats >= 0); + assert(config->dump_file >= 0); assert(config->site_import >= 0); assert(config->bytes_warning >= 0); assert(config->warn_default_encoding >= 0); @@ -898,6 +899,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_file); COPY_ATTR(malloc_stats); COPY_WSTR_ATTR(pycache_prefix); @@ -1700,6 +1702,9 @@ config_read_env_vars(PyConfig *config) if (config_get_env(config, "PYTHONMALLOCSTATS")) { config->malloc_stats = 1; } + if (config_get_env(config, "PYTHONDUMPFILE")) { + config->dump_file = 1; + } if (config->pythonpath_env == NULL) { status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env, diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index eeaf20b4617a209..1f2e66e403cbce7 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1736,6 +1736,7 @@ Py_FinalizeEx(void) int show_ref_count = tstate->interp->config.show_ref_count; #endif #ifdef Py_TRACE_REFS + int dump_file = tstate->interp->config.dump_file; int dump_refs = tstate->interp->config.dump_refs; #endif #ifdef WITH_PYMALLOC @@ -1835,8 +1836,16 @@ Py_FinalizeEx(void) * Alas, a lot of stuff may still be alive now that will be cleaned * up later. */ + + FILE *fp = stderr; + if (dump_file) { + char dump_file_name[255]; + time_t now = time(NULL); + sprintf(dump_file_name, "cpython-tracerefs-%ld.dump", now); + fp = fopen(dump_file_name,"w"); + } if (dump_refs) { - _Py_PrintReferences(stderr); + _Py_PrintReferences(fp); } #endif /* Py_TRACE_REFS */ @@ -1849,7 +1858,10 @@ Py_FinalizeEx(void) * above by _Py_PrintReferences. */ if (dump_refs) { - _Py_PrintReferenceAddresses(stderr); + _Py_PrintReferenceAddresses(fp); + } + if (fp != NULL && fp != stderr) { + fclose(fp); } #endif /* Py_TRACE_REFS */ #ifdef WITH_PYMALLOC From 4f0a425e60c79d15c46d85c66521811bb0952f4c Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 15 Aug 2021 00:23:07 +0900 Subject: [PATCH 2/9] bpo-44895: Address code review --- Doc/using/cmdline.rst | 4 ++-- Include/cpython/initconfig.h | 2 +- .../2021-08-14-20-13-21.bpo-44895.Ic9m90.rst | 2 +- Python/initconfig.c | 12 ++++++++---- Python/pylifecycle.c | 9 ++++----- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 32e5bf370322127..6437549e2e629a3 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -976,9 +976,9 @@ Debug-mode variables Need Python configured with the :option:`--with-trace-refs` build option. -.. envvar:: PYTHONDUMPFILE +.. envvar:: PYTHONDUMPDIR - If set, Python will create a file 'cpython-tracerefs-.dump` as dump file + If set, Python will create a file at '$(PYTHONDUMPDIR)/cpython-tracerefs-.txt` as dump file which is generated by :envvar:`PYTHONDUMPREFS`. Need Python configured with the :option:`--with-trace-refs` build option. diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 538234722e7eaad..0620db080d73480 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -144,7 +144,7 @@ typedef struct PyConfig { int show_ref_count; int dump_refs; int malloc_stats; - int dump_file; + wchar_t *python_dump_dir; wchar_t *filesystem_encoding; wchar_t *filesystem_errors; wchar_t *pycache_prefix; 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 index 195bb330fd0d26d..51ff98926046fd9 100644 --- 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 @@ -1,2 +1,2 @@ -A debug variable :envvar:`PYTHONDUMPFILE` is added for creating a dump file +A debug variable :envvar:`PYTHONDUMPDIR` is added for creating a dump file which is generated by :envvar:`PYTHONDUMPREFS`. Patch by Dong-hee Na. diff --git a/Python/initconfig.c b/Python/initconfig.c index d11aa57a36d3e9e..27b02dbb55dd6ee 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -611,7 +611,6 @@ config_check_consistency(const PyConfig *config) assert(config->show_ref_count >= 0); assert(config->dump_refs >= 0); assert(config->malloc_stats >= 0); - assert(config->dump_file >= 0); assert(config->site_import >= 0); assert(config->bytes_warning >= 0); assert(config->warn_default_encoding >= 0); @@ -899,7 +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_file); + COPY_ATTR(python_dump_dir); COPY_ATTR(malloc_stats); COPY_WSTR_ATTR(pycache_prefix); @@ -1702,8 +1701,13 @@ config_read_env_vars(PyConfig *config) if (config_get_env(config, "PYTHONMALLOCSTATS")) { config->malloc_stats = 1; } - if (config_get_env(config, "PYTHONDUMPFILE")) { - config->dump_file = 1; + + if (config->python_dump_dir == NULL) { + status = CONFIG_GET_ENV_DUP(config, &config->python_dump_dir, + L"PYTHONDUMPDIR", "PYTHONDUMPDIR"); + if (_PyStatus_EXCEPTION(status)) { + return status; + } } if (config->pythonpath_env == NULL) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 1f2e66e403cbce7..28a44541b691cb4 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -32,7 +32,7 @@ #ifdef MS_WINDOWS # undef BYTE # include "windows.h" - +# define getpid GetCurrentProcessId extern PyTypeObject PyWindowsConsoleIO_Type; # define PyWindowsConsoleIO_Check(op) \ (PyObject_TypeCheck((op), &PyWindowsConsoleIO_Type)) @@ -1736,7 +1736,7 @@ Py_FinalizeEx(void) int show_ref_count = tstate->interp->config.show_ref_count; #endif #ifdef Py_TRACE_REFS - int dump_file = tstate->interp->config.dump_file; + wchar_t *python_dump_dir = tstate->interp->config.python_dump_dir; int dump_refs = tstate->interp->config.dump_refs; #endif #ifdef WITH_PYMALLOC @@ -1838,10 +1838,9 @@ Py_FinalizeEx(void) */ FILE *fp = stderr; - if (dump_file) { + if (python_dump_dir != NULL) { char dump_file_name[255]; - time_t now = time(NULL); - sprintf(dump_file_name, "cpython-tracerefs-%ld.dump", now); + sprintf(dump_file_name, "%S/python-tracerefs-%d.txt", python_dump_dir, getpid()); fp = fopen(dump_file_name,"w"); } if (dump_refs) { From 5d93958e4e79193001e859282186941e0206c76d Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 15 Aug 2021 00:33:13 +0900 Subject: [PATCH 3/9] bpo-44895: Update docs --- Doc/using/cmdline.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 6437549e2e629a3..708c7a6d8a27699 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -978,7 +978,9 @@ Debug-mode variables .. envvar:: PYTHONDUMPDIR - If set, Python will create a file at '$(PYTHONDUMPDIR)/cpython-tracerefs-.txt` as dump file + If set, Python will create a file at '$(PYTHONDUMPDIR)/cpython-tracerefs-.txt` as dump file which is generated by :envvar:`PYTHONDUMPREFS`. Need Python configured with the :option:`--with-trace-refs` build option. + + .. versionadded:: 3.11 From 5324b4f7f4f4723146bd399a91e363958da4379e Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Mon, 16 Aug 2021 20:21:13 +0900 Subject: [PATCH 4/9] bpo-44895 Address Victor's suggestion --- Doc/using/cmdline.rst | 4 ++-- Include/cpython/initconfig.h | 2 +- .../2021-08-14-20-13-21.bpo-44895.Ic9m90.rst | 2 +- Python/initconfig.c | 8 ++++---- Python/pylifecycle.c | 10 ++++------ 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 708c7a6d8a27699..b860366689a080c 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -976,9 +976,9 @@ Debug-mode variables Need Python configured with the :option:`--with-trace-refs` build option. -.. envvar:: PYTHONDUMPDIR +.. envvar:: PYTHONDUMPFILE - If set, Python will create a file at '$(PYTHONDUMPDIR)/cpython-tracerefs-.txt` as dump file + If set, Python will create a file at `$PYTHONDUMPFILE` as dump file which is generated by :envvar:`PYTHONDUMPREFS`. Need Python configured with the :option:`--with-trace-refs` build option. diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 0620db080d73480..ae7d5cd558393cc 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -144,7 +144,7 @@ typedef struct PyConfig { int show_ref_count; int dump_refs; int malloc_stats; - wchar_t *python_dump_dir; + wchar_t *python_dump_file; wchar_t *filesystem_encoding; wchar_t *filesystem_errors; wchar_t *pycache_prefix; 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 index 51ff98926046fd9..195bb330fd0d26d 100644 --- 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 @@ -1,2 +1,2 @@ -A debug variable :envvar:`PYTHONDUMPDIR` is added for creating a dump file +A debug variable :envvar:`PYTHONDUMPFILE` is added for creating a dump file which is generated by :envvar:`PYTHONDUMPREFS`. Patch by Dong-hee Na. diff --git a/Python/initconfig.c b/Python/initconfig.c index 27b02dbb55dd6ee..6cd16045b277be8 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -898,7 +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(python_dump_dir); + COPY_ATTR(python_dump_file); COPY_ATTR(malloc_stats); COPY_WSTR_ATTR(pycache_prefix); @@ -1702,9 +1702,9 @@ config_read_env_vars(PyConfig *config) config->malloc_stats = 1; } - if (config->python_dump_dir == NULL) { - status = CONFIG_GET_ENV_DUP(config, &config->python_dump_dir, - L"PYTHONDUMPDIR", "PYTHONDUMPDIR"); + if (config->python_dump_file == NULL) { + status = CONFIG_GET_ENV_DUP(config, &config->python_dump_file, + L"PYTHONDUMPFILE", "PYTHONDUMPFILE"); if (_PyStatus_EXCEPTION(status)) { return status; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 28a44541b691cb4..3e045845eee2a1e 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -32,7 +32,7 @@ #ifdef MS_WINDOWS # undef BYTE # include "windows.h" -# define getpid GetCurrentProcessId + extern PyTypeObject PyWindowsConsoleIO_Type; # define PyWindowsConsoleIO_Check(op) \ (PyObject_TypeCheck((op), &PyWindowsConsoleIO_Type)) @@ -1736,7 +1736,7 @@ Py_FinalizeEx(void) int show_ref_count = tstate->interp->config.show_ref_count; #endif #ifdef Py_TRACE_REFS - wchar_t *python_dump_dir = tstate->interp->config.python_dump_dir; + wchar_t *python_dump_file = tstate->interp->config.python_dump_file; int dump_refs = tstate->interp->config.dump_refs; #endif #ifdef WITH_PYMALLOC @@ -1838,10 +1838,8 @@ Py_FinalizeEx(void) */ FILE *fp = stderr; - if (python_dump_dir != NULL) { - char dump_file_name[255]; - sprintf(dump_file_name, "%S/python-tracerefs-%d.txt", python_dump_dir, getpid()); - fp = fopen(dump_file_name,"w"); + if (python_dump_file != NULL) { + fp = _Py_wfopen(python_dump_file, L"w"); } if (dump_refs) { _Py_PrintReferences(fp); From 1895e6909f9bd107ec3e9265736399569ea00ea9 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Mon, 16 Aug 2021 20:49:17 +0900 Subject: [PATCH 5/9] bpo-44895: Update doc --- Doc/using/cmdline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index b860366689a080c..3120efbb00b3519 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -978,7 +978,7 @@ Debug-mode variables .. envvar:: PYTHONDUMPFILE - If set, Python will create a file at `$PYTHONDUMPFILE` as dump file + If set, Python will create a file named `$PYTHONDUMPFILE` as the dump file which is generated by :envvar:`PYTHONDUMPREFS`. Need Python configured with the :option:`--with-trace-refs` build option. From 82a34d5ef303da1b77acc96fbcb027cd76047bd1 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Tue, 17 Aug 2021 13:05:41 +0900 Subject: [PATCH 6/9] bpo-44895: Address Victor's code review --- Doc/using/cmdline.rst | 7 +++-- Include/cpython/initconfig.h | 2 +- .../2021-08-14-20-13-21.bpo-44895.Ic9m90.rst | 2 +- Python/initconfig.c | 8 ++--- Python/pylifecycle.c | 29 +++++++++++-------- 5 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 3120efbb00b3519..b541678ee70eafc 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -976,10 +976,11 @@ Debug-mode variables Need Python configured with the :option:`--with-trace-refs` build option. -.. envvar:: PYTHONDUMPFILE +.. envvar:: PYTHONDUMPREFSFILE - If set, Python will create a file named `$PYTHONDUMPFILE` as the dump file - which is generated by :envvar:`PYTHONDUMPREFS`. + If set, Python will dump objects and reference counts still alive + as file named `$PYTHONDUMPREFSFILE` still alive after shutting down + the interpreter. Need Python configured with the :option:`--with-trace-refs` build option. diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index ae7d5cd558393cc..22ad0f14e58004c 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -143,8 +143,8 @@ typedef struct PyConfig { int no_debug_ranges; int show_ref_count; int dump_refs; + wchar_t *dump_refs_file; int malloc_stats; - wchar_t *python_dump_file; wchar_t *filesystem_encoding; wchar_t *filesystem_errors; wchar_t *pycache_prefix; 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 index 195bb330fd0d26d..b4a1a69d9852a63 100644 --- 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 @@ -1,2 +1,2 @@ -A debug variable :envvar:`PYTHONDUMPFILE` is added for creating a dump file +A debug variable :envvar:`PYTHONDUMPREFSFILE` is added for creating a dump file which is generated by :envvar:`PYTHONDUMPREFS`. Patch by Dong-hee Na. diff --git a/Python/initconfig.c b/Python/initconfig.c index 6cd16045b277be8..61cd0e6213ed17b 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -898,7 +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(python_dump_file); + COPY_ATTR(dump_refs_file); COPY_ATTR(malloc_stats); COPY_WSTR_ATTR(pycache_prefix); @@ -1702,9 +1702,9 @@ config_read_env_vars(PyConfig *config) config->malloc_stats = 1; } - if (config->python_dump_file == NULL) { - status = CONFIG_GET_ENV_DUP(config, &config->python_dump_file, - L"PYTHONDUMPFILE", "PYTHONDUMPFILE"); + 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; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 3e045845eee2a1e..36ffcb60e7b8eda 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1736,8 +1736,8 @@ Py_FinalizeEx(void) int show_ref_count = tstate->interp->config.show_ref_count; #endif #ifdef Py_TRACE_REFS - wchar_t *python_dump_file = tstate->interp->config.python_dump_file; 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; @@ -1837,12 +1837,13 @@ Py_FinalizeEx(void) * up later. */ - FILE *fp = stderr; - if (python_dump_file != NULL) { - fp = _Py_wfopen(python_dump_file, L"w"); - } - if (dump_refs) { - _Py_PrintReferences(fp); + FILE *fp = dump_refs_file ? _Py_wfopen(dump_refs_file, L"w") : stderr; + if (dump_refs || dump_refs_file != NULL) { + if (fp == NULL) { + fprintf(stderr, "Can not log all live objects.\n"); + } else { + _Py_PrintReferences(fp); + } } #endif /* Py_TRACE_REFS */ @@ -1854,11 +1855,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(fp); - } - if (fp != NULL && fp != stderr) { - fclose(fp); + if (dump_refs || dump_refs_file) { + if (fp == NULL) { + fprintf(stderr, "Can not log the addresses of all live objects.\n"); + } else { + _Py_PrintReferenceAddresses(fp); + if (fp != stderr) { + fclose(fp); + } + } } #endif /* Py_TRACE_REFS */ #ifdef WITH_PYMALLOC From 960930310839bea270ec7f9381bdc15d8681a0eb Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Tue, 17 Aug 2021 22:44:50 +0900 Subject: [PATCH 7/9] bpo-44895: Address code review --- Doc/using/cmdline.rst | 5 ++--- Python/pylifecycle.c | 36 +++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index b541678ee70eafc..7503ba7423dce3e 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -976,11 +976,10 @@ Debug-mode variables Need Python configured with the :option:`--with-trace-refs` build option. -.. envvar:: PYTHONDUMPREFSFILE +.. envvar:: PYTHONDUMPREFSFILE=FILENAME If set, Python will dump objects and reference counts still alive - as file named `$PYTHONDUMPREFSFILE` still alive after shutting down - the interpreter. + after shutting down the interpreter into a file called `$FILENAME`. Need Python configured with the :option:`--with-trace-refs` build option. diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 36ffcb60e7b8eda..f3b6b0ac68a1ea9 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1837,14 +1837,21 @@ Py_FinalizeEx(void) * up later. */ - FILE *fp = dump_refs_file ? _Py_wfopen(dump_refs_file, L"w") : stderr; - if (dump_refs || dump_refs_file != NULL) { - if (fp == NULL) { - fprintf(stderr, "Can not log all live objects.\n"); - } else { - _Py_PrintReferences(fp); + 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); @@ -1855,15 +1862,14 @@ Py_FinalizeEx(void) * An address can be used to find the repr of the object, printed * above by _Py_PrintReferences. */ - if (dump_refs || dump_refs_file) { - if (fp == NULL) { - fprintf(stderr, "Can not log the addresses of all live objects.\n"); - } else { - _Py_PrintReferenceAddresses(fp); - if (fp != stderr) { - fclose(fp); - } - } + + 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 From 1b1daa45ccc0439d1057225d9d725d80386843b4 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Tue, 17 Aug 2021 23:07:47 +0900 Subject: [PATCH 8/9] bpo-44895: Update NEWS.d --- .../Core and Builtins/2021-08-14-20-13-21.bpo-44895.Ic9m90.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index b4a1a69d9852a63..d369ac765059745 100644 --- 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 @@ -1,2 +1,2 @@ A debug variable :envvar:`PYTHONDUMPREFSFILE` is added for creating a dump file -which is generated by :envvar:`PYTHONDUMPREFS`. Patch by Dong-hee Na. +which is generated by :option:`--with-trace-refs`. Patch by Dong-hee Na. From d148abcf31cad117108b329efd88bd0aa4f97a69 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Tue, 17 Aug 2021 15:20:54 +0000 Subject: [PATCH 9/9] Update Doc/using/cmdline.rst Co-authored-by: Victor Stinner --- Doc/using/cmdline.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 7503ba7423dce3e..7ebc34f47fc39b3 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -979,7 +979,7 @@ Debug-mode variables .. envvar:: PYTHONDUMPREFSFILE=FILENAME If set, Python will dump objects and reference counts still alive - after shutting down the interpreter into a file called `$FILENAME`. + after shutting down the interpreter into a file called *FILENAME*. Need Python configured with the :option:`--with-trace-refs` build option.