summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-08-08 04:36:25 (GMT)
committerGitHub <noreply@github.com>2023-08-08 04:36:25 (GMT)
commit328d925244511b2134d5ac926e307e4486ff4500 (patch)
tree5664372efae8658277c3a175bbd42065b533d362 /Python
parent2df58dcd500dbedc61d0630374f9e94c522fe523 (diff)
downloadcpython-328d925244511b2134d5ac926e307e4486ff4500.zip
cpython-328d925244511b2134d5ac926e307e4486ff4500.tar.gz
cpython-328d925244511b2134d5ac926e307e4486ff4500.tar.bz2
gh-107758: Improvements to lltrace feature (#107757)
- The `dump_stack()` method could call a `__repr__` method implemented in Python, causing (infinite) recursion. I rewrote it to only print out the values for some fundamental types (`int`, `str`, etc.); for everything else it just prints `<type_name @ 0xdeadbeef>`. - The lltrace-like feature for uops wrote to `stderr`, while the one in `ceval.c` writes to `stdout`; I changed the uops to write to stdout as well.
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c34
-rw-r--r--Python/executor.c2
-rw-r--r--Python/optimizer.c2
3 files changed, 30 insertions, 8 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 30f722e..1dc4fd8 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -109,11 +109,24 @@ dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer)
if (ptr != stack_base) {
printf(", ");
}
- if (PyObject_Print(*ptr, stdout, 0) != 0) {
+ if (*ptr == NULL) {
+ printf("<nil>");
+ continue;
+ }
+ if (
+ *ptr == Py_None
+ || PyBool_Check(*ptr)
+ || PyLong_CheckExact(*ptr)
+ || PyFloat_CheckExact(*ptr)
+ || PyUnicode_CheckExact(*ptr)
+ ) {
+ if (PyObject_Print(*ptr, stdout, 0) == 0) {
+ continue;
+ }
PyErr_Clear();
- printf("<%s object at %p>",
- Py_TYPE(*ptr)->tp_name, (void *)(*ptr));
}
+ // Don't call __repr__(), it might recurse into the interpreter.
+ printf("<%s at %p>", Py_TYPE(*ptr)->tp_name, (void *)(*ptr));
}
printf("]\n");
fflush(stdout);
@@ -128,9 +141,6 @@ lltrace_instruction(_PyInterpreterFrame *frame,
if (frame->owner == FRAME_OWNED_BY_CSTACK) {
return;
}
- /* This dump_stack() operation is risky, since the repr() of some
- objects enters the interpreter recursively. It is also slow.
- So you might want to comment it out. */
dump_stack(frame, stack_pointer);
int oparg = next_instr->op.arg;
int opcode = next_instr->op.code;
@@ -729,6 +739,13 @@ resume_frame:
goto exit_unwind;
}
lltrace = r;
+ if (!lltrace) {
+ // When tracing executed uops, also trace bytecode
+ char *uop_debug = Py_GETENV("PYTHONUOPSDEBUG");
+ if (uop_debug != NULL && *uop_debug >= '0') {
+ lltrace = (*uop_debug - '0') >= 4; // TODO: Parse an int and all that
+ }
+ }
}
if (lltrace) {
lltrace_resume_frame(frame);
@@ -896,6 +913,11 @@ exception_unwind:
goto exception_unwind;
}
/* Resume normal execution */
+#ifdef LLTRACE
+ if (lltrace) {
+ lltrace_resume_frame(frame);
+ }
+#endif
DISPATCH();
}
}
diff --git a/Python/executor.c b/Python/executor.c
index 57525df..4a18618 100644
--- a/Python/executor.c
+++ b/Python/executor.c
@@ -41,7 +41,7 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
lltrace = *uop_debug - '0'; // TODO: Parse an int and all that
}
#define DPRINTF(level, ...) \
- if (lltrace >= (level)) { fprintf(stderr, __VA_ARGS__); }
+ if (lltrace >= (level)) { printf(__VA_ARGS__); }
#else
#define DPRINTF(level, ...)
#endif
diff --git a/Python/optimizer.c b/Python/optimizer.c
index d2ed8df..6c730aa 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -391,7 +391,7 @@ translate_bytecode_to_trace(
#ifdef Py_DEBUG
#define DPRINTF(level, ...) \
- if (lltrace >= (level)) { fprintf(stderr, __VA_ARGS__); }
+ if (lltrace >= (level)) { printf(__VA_ARGS__); }
#else
#define DPRINTF(level, ...)
#endif