diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 9e391604a1a59d..32e5bf37032212 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 5f03b8c57f8bc8..538234722e7eaa 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 00000000000000..195bb330fd0d26 --- /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 d328f227cead25..d11aa57a36d3e9 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 eeaf20b4617a20..1f2e66e403cbce 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