summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/modsys.c3
-rw-r--r--py/mpconfig.h7
-rw-r--r--py/mpstate.h3
-rw-r--r--py/objexcept.c10
-rw-r--r--py/runtime.c4
5 files changed, 26 insertions, 1 deletions
diff --git a/py/modsys.c b/py/modsys.c
index a05709f8e..c44c7ed45 100644
--- a/py/modsys.c
+++ b/py/modsys.c
@@ -185,6 +185,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_sys_settrace_obj, mp_sys_settrace);
#if MICROPY_PY_SYS_ATTR_DELEGATION
STATIC const uint16_t sys_mutable_keys[] = {
+ #if MICROPY_PY_SYS_TRACEBACKLIMIT
+ MP_QSTR_tracebacklimit,
+ #endif
MP_QSTRnull,
};
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 617e89708..be967e698 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -1377,10 +1377,15 @@ typedef double mp_float_t;
#define MICROPY_PY_SYS_STDIO_BUFFER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES)
#endif
+// Whether to provide sys.tracebacklimit mutable attribute
+#ifndef MICROPY_PY_SYS_TRACEBACKLIMIT
+#define MICROPY_PY_SYS_TRACEBACKLIMIT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING)
+#endif
+
// Whether the sys module supports attribute delegation
// This is enabled automatically when needed by other features
#ifndef MICROPY_PY_SYS_ATTR_DELEGATION
-#define MICROPY_PY_SYS_ATTR_DELEGATION (0)
+#define MICROPY_PY_SYS_ATTR_DELEGATION (MICROPY_PY_SYS_TRACEBACKLIMIT)
#endif
// Whether to provide "uerrno" module
diff --git a/py/mpstate.h b/py/mpstate.h
index f29e6be50..499d86351 100644
--- a/py/mpstate.h
+++ b/py/mpstate.h
@@ -41,6 +41,9 @@
// variable, but in the future it is hoped that the state can become local.
enum {
+ #if MICROPY_PY_SYS_TRACEBACKLIMIT
+ MP_SYS_MUTABLE_TRACEBACKLIMIT,
+ #endif
MP_SYS_MUTABLE_NUM,
};
diff --git a/py/objexcept.c b/py/objexcept.c
index 7a86c3647..dca287bb6 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -575,6 +575,16 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs
// append this traceback info to traceback data
// if memory allocation fails (eg because gc is locked), just return
+ #if MICROPY_PY_SYS_TRACEBACKLIMIT
+ mp_int_t max_traceback = MP_OBJ_SMALL_INT_VALUE(MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_TRACEBACKLIMIT]));
+ if (max_traceback <= 0) {
+ return;
+ } else if (self->traceback_data != NULL && self->traceback_len >= max_traceback * TRACEBACK_ENTRY_LEN) {
+ self->traceback_len -= TRACEBACK_ENTRY_LEN;
+ memmove(self->traceback_data, self->traceback_data + TRACEBACK_ENTRY_LEN, self->traceback_len * sizeof(self->traceback_data[0]));
+ }
+ #endif
+
if (self->traceback_data == NULL) {
self->traceback_data = m_new_maybe(size_t, TRACEBACK_ENTRY_LEN);
if (self->traceback_data == NULL) {
diff --git a/py/runtime.c b/py/runtime.c
index 8c93f539e..665c9f220 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -141,6 +141,10 @@ void mp_init(void) {
MP_STATE_THREAD(current_code_state) = NULL;
#endif
+ #if MICROPY_PY_SYS_TRACEBACKLIMIT
+ MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_TRACEBACKLIMIT]) = MP_OBJ_NEW_SMALL_INT(1000);
+ #endif
+
#if MICROPY_PY_BLUETOOTH
MP_STATE_VM(bluetooth) = MP_OBJ_NULL;
#endif