Skip to content

Commit 7b71a56

Browse files
Add get_gc_stats to RemoteUnwinder
1 parent c305d81 commit 7b71a56

3 files changed

Lines changed: 163 additions & 24 deletions

File tree

Modules/_remote_debugging/clinic/module.c.h

Lines changed: 93 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_remote_debugging/gc_stats.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extern "C" {
1616
typedef struct {
1717
PyObject *result;
1818
bool all_interpreters;
19-
} ReadGCStatsContext;
19+
} GetGCStatsContext;
2020

2121
static int
2222
read_gc_stats(struct gc_stats *stats, int64_t iid, PyObject *result)
@@ -125,7 +125,7 @@ get_gc_stats_from_interpreter_state(RuntimeOffsets *offsets,
125125
int64_t iid,
126126
void *context)
127127
{
128-
ReadGCStatsContext *ctx = (ReadGCStatsContext *)context;
128+
GetGCStatsContext *ctx = (GetGCStatsContext *)context;
129129
if (!ctx->all_interpreters && iid > 0) {
130130
return 0;
131131
}

Modules/_remote_debugging/module.c

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,13 +1031,77 @@ _remote_debugging_RemoteUnwinder_resume_threads_impl(RemoteUnwinderObject *self)
10311031
#endif
10321032
}
10331033

1034+
static PyObject *
1035+
get_gc_stats(RuntimeOffsets *offsets, bool all_interpreters)
1036+
{
1037+
PyObject *result = PyList_New(0);
1038+
if (result == NULL) {
1039+
return NULL;
1040+
}
1041+
GetGCStatsContext ctx = {
1042+
.result = result,
1043+
.all_interpreters = all_interpreters,
1044+
};
1045+
if (0 > iterate_interpreters(offsets, get_gc_stats_from_interpreter_state, &ctx)) {
1046+
Py_CLEAR(result);
1047+
return NULL;
1048+
}
1049+
1050+
return result;
1051+
}
1052+
1053+
/*[clinic input]
1054+
@permit_long_docstring_body
1055+
@critical_section
1056+
_remote_debugging.RemoteUnwinder.get_gc_stats
1057+
1058+
all_interpreters: bool = False
1059+
If True, return GC statistics from all interpreters.
1060+
If False, return only from main interpreter.
1061+
1062+
Get garbage collector statistics from external Python process.
1063+
1064+
Returns a list of dictionaries with GC statistics data.
1065+
1066+
Returns:
1067+
List of dicts.
1068+
dict: A dictionary containing:
1069+
- gen:
1070+
- iid:
1071+
- ts_start:
1072+
- ts_stop:
1073+
- heap_size:
1074+
- collections:
1075+
- collected:
1076+
- uncollectable:
1077+
- candidates:
1078+
- duration:
1079+
1080+
Raises:
1081+
RuntimeError:
1082+
[clinic start generated code]*/
1083+
1084+
static PyObject *
1085+
_remote_debugging_RemoteUnwinder_get_gc_stats_impl(RemoteUnwinderObject *self,
1086+
int all_interpreters)
1087+
/*[clinic end generated code: output=ee2f7cb3e4ea7bc1 input=c025864b40478df2]*/
1088+
{
1089+
RuntimeOffsets offsets = {
1090+
.handle = self->handle,
1091+
.runtime_start_address = self->runtime_start_address,
1092+
.debug_offsets = self->debug_offsets,
1093+
};
1094+
return get_gc_stats(&offsets, all_interpreters);
1095+
}
1096+
10341097
static PyMethodDef RemoteUnwinder_methods[] = {
10351098
_REMOTE_DEBUGGING_REMOTEUNWINDER_GET_STACK_TRACE_METHODDEF
10361099
_REMOTE_DEBUGGING_REMOTEUNWINDER_GET_ALL_AWAITED_BY_METHODDEF
10371100
_REMOTE_DEBUGGING_REMOTEUNWINDER_GET_ASYNC_STACK_TRACE_METHODDEF
10381101
_REMOTE_DEBUGGING_REMOTEUNWINDER_GET_STATS_METHODDEF
10391102
_REMOTE_DEBUGGING_REMOTEUNWINDER_PAUSE_THREADS_METHODDEF
10401103
_REMOTE_DEBUGGING_REMOTEUNWINDER_RESUME_THREADS_METHODDEF
1104+
_REMOTE_DEBUGGING_REMOTEUNWINDER_GET_GC_STATS_METHODDEF
10411105
{NULL, NULL}
10421106
};
10431107

@@ -1857,14 +1921,10 @@ Get garbage collector statistics from external Python process.
18571921
- ts_start:
18581922
- ts_stop:
18591923
- heap_size:
1860-
- work_to_do:
18611924
- collections:
1862-
- object_visits:
18631925
- collected:
18641926
- uncollectable:
18651927
- candidates:
1866-
- objects_transitively_reachable:
1867-
- objects_not_transitively_reachable:
18681928
- duration:
18691929
18701930
Raises:
@@ -1874,7 +1934,7 @@ Get garbage collector statistics from external Python process.
18741934
static PyObject *
18751935
_remote_debugging_get_gc_stats_impl(PyObject *module, int pid,
18761936
int all_interpreters)
1877-
/*[clinic end generated code: output=d9dce5f7add149bb input=8f05aee4d4230428]*/
1937+
/*[clinic end generated code: output=d9dce5f7add149bb input=6a2afe531da4cfda]*/
18781938
{
18791939
RuntimeOffsets offsets;
18801940

@@ -1905,19 +1965,10 @@ _remote_debugging_get_gc_stats_impl(PyObject *module, int pid,
19051965
goto error;
19061966
}
19071967

1908-
result = PyList_New(0);
1909-
if (result == NULL) {
1910-
goto error;
1968+
result = get_gc_stats(&offsets, all_interpreters);
1969+
if (result != NULL) {
1970+
goto done;
19111971
}
1912-
ReadGCStatsContext ctx = {
1913-
.result = result,
1914-
.all_interpreters = all_interpreters,
1915-
};
1916-
if (0 > iterate_interpreters(&offsets, get_gc_stats_from_interpreter_state, &ctx)) {
1917-
goto error;
1918-
}
1919-
1920-
goto done;
19211972

19221973
error:
19231974
Py_CLEAR(result);

0 commit comments

Comments
 (0)