diff options
Diffstat (limited to 'coverage/tracer.c')
-rw-r--r-- | coverage/tracer.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/coverage/tracer.c b/coverage/tracer.c index fdd89d8c..7cdb7727 100644 --- a/coverage/tracer.c +++ b/coverage/tracer.c @@ -22,6 +22,7 @@ #define MyText_Type PyUnicode_Type #define MyText_AS_BYTES(o) PyUnicode_AsASCIIString(o) +#define MyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) #define MyBytes_AS_STRING(o) PyBytes_AS_STRING(o) #define MyText_AsString(o) PyUnicode_AsUTF8(o) #define MyText_FromFormat PyUnicode_FromFormat @@ -34,6 +35,7 @@ #define MyText_Type PyString_Type #define MyText_AS_BYTES(o) (Py_INCREF(o), o) +#define MyBytes_GET_SIZE(o) PyString_GET_SIZE(o) #define MyBytes_AS_STRING(o) PyString_AS_STRING(o) #define MyText_AsString(o) PyString_AsString(o) #define MyText_FromFormat PyUnicode_FromFormat @@ -828,8 +830,18 @@ CTracer_handle_return(CTracer *self, PyFrameObject *frame) } if (self->pdata_stack->depth >= 0) { if (self->tracing_arcs && self->cur_entry.file_data) { - /* Need to distinguish between RETURN_VALUE and YIELD_VALUE. */ - int bytecode = MyBytes_AS_STRING(frame->f_code->co_code)[frame->f_lasti]; + /* Need to distinguish between RETURN_VALUE and YIELD_VALUE. Read + * the current bytecode to see what it is. In unusual circumstances + * (Cython code), co_code can be the empty string, so range-check + * f_lasti before reading the byte. + */ + int bytecode = RETURN_VALUE; + PyObject * pCode = frame->f_code->co_code; + int lasti = frame->f_lasti; + + if (lasti < MyBytes_GET_SIZE(pCode)) { + bytecode = MyBytes_AS_STRING(pCode)[lasti]; + } if (bytecode != YIELD_VALUE) { int first = frame->f_code->co_firstlineno; if (CTracer_record_pair(self, self->cur_entry.last_line, -first) < 0) { |