Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle errors in tracing functions #210

Draft
wants to merge 2 commits into
base: develop/3.9
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Tests/test_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ def test_f():

self.assertIn("Hit exception", f.getvalue())

def test_raising_tracer(self):
def custom_trace(frame, event, args):
raise TypeError("uh oh!")

def test_f():
return 100

f = io.StringIO()
with contextlib.redirect_stdout(f):
sys.settrace(custom_trace)
with self.assertRaises(TypeError):
test_f()
sys.settrace(None)


class ProfilingTestCase(unittest.TestCase):

Expand Down
1 change: 1 addition & 0 deletions src/pyjion/absint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,7 @@ AbstactInterpreterCompileResult AbstractInterpreter::compileWorker(PgcStatus pgc
if (!canSkipLastiUpdate(curByte)) {
if (mTracingEnabled){
m_comp->emit_trace_line(mTracingInstrLowerBound, mTracingInstrUpperBound, mTracingLastInstr);
intErrorCheck("trace line failed");
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/pyjion/intrins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2614,7 +2614,7 @@ inline int trace(PyThreadState *tstate, PyFrameObject *f, int ty, PyObject *args
return result;
}

void PyJit_TraceLine(PyFrameObject* f, int* instr_lb, int* instr_ub, int* instr_prev){
int PyJit_TraceLine(PyFrameObject* f, int* instr_lb, int* instr_ub, int* instr_prev){
auto tstate = PyThreadState_GET();
if (tstate->c_tracefunc != nullptr && !tstate->tracing) {
int result = 0;
Expand All @@ -2638,22 +2638,24 @@ void PyJit_TraceLine(PyFrameObject* f, int* instr_lb, int* instr_ub, int* instr_
f->f_lineno = line;
if (f->f_trace_lines) {
if (tstate->tracing)
return;
return 0;
result = trace(tstate, f, PyTrace_LINE, Py_None, tstate->c_tracefunc, tstate->c_traceobj);
}
}
/* Always emit an opcode event if we're tracing all opcodes. */
if (f->f_trace_opcodes) {
if (tstate->tracing)
return;
return 0;
result = trace(tstate, f, PyTrace_OPCODE, Py_None, tstate->c_tracefunc, tstate->c_traceobj);
}
*instr_prev = f->f_lasti;

// TODO : Handle possible change of instruction address
// should lookup jump address and branch (f->f_lasti);
// TODO : Handle error in call trace function
return result;
}

return 0;
}

inline int protected_trace(PyThreadState* tstate, PyFrameObject* f, int ty, PyObject* arg, Py_tracefunc func, PyObject* tracearg){
Expand Down
2 changes: 1 addition & 1 deletion src/pyjion/intrins.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ int PyJit_IsNot_Bool(PyObject* lhs, PyObject* rhs);
inline int trace(PyThreadState *tstate, PyFrameObject *f, int ty, PyObject *args, Py_tracefunc func, PyObject* tracearg);
inline int protected_trace(PyThreadState* tstate, PyFrameObject* f, int ty, PyObject* arg, Py_tracefunc func, PyObject* tracearg);

void PyJit_TraceLine(PyFrameObject* f, int* instr_lb, int* instr_ub, int* instr_prev);
int PyJit_TraceLine(PyFrameObject* f, int* instr_lb, int* instr_ub, int* instr_prev);
void PyJit_TraceFrameEntry(PyFrameObject* f);
void PyJit_TraceFrameExit(PyFrameObject* f);
void PyJit_ProfileFrameEntry(PyFrameObject* f);
Expand Down
2 changes: 1 addition & 1 deletion src/pyjion/pycomp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2104,7 +2104,7 @@ GLOBAL_METHOD(METHOD_LOAD_ASSERTION_ERROR, &PyJit_LoadAssertionError, CORINFO_TY
GLOBAL_METHOD(METHOD_DEALLOC_OBJECT, &_Py_Dealloc, CORINFO_TYPE_VOID, Parameter(CORINFO_TYPE_NATIVEINT));


GLOBAL_METHOD(METHOD_TRACE_LINE, &PyJit_TraceLine, CORINFO_TYPE_VOID, Parameter(CORINFO_TYPE_NATIVEINT), Parameter(CORINFO_TYPE_NATIVEINT), Parameter(CORINFO_TYPE_NATIVEINT), Parameter(CORINFO_TYPE_NATIVEINT));
GLOBAL_METHOD(METHOD_TRACE_LINE, &PyJit_TraceLine, CORINFO_TYPE_INT, Parameter(CORINFO_TYPE_NATIVEINT), Parameter(CORINFO_TYPE_NATIVEINT), Parameter(CORINFO_TYPE_NATIVEINT), Parameter(CORINFO_TYPE_NATIVEINT));
GLOBAL_METHOD(METHOD_TRACE_FRAME_ENTRY, &PyJit_TraceFrameEntry, CORINFO_TYPE_VOID, Parameter(CORINFO_TYPE_NATIVEINT), );
GLOBAL_METHOD(METHOD_TRACE_FRAME_EXIT, &PyJit_TraceFrameExit, CORINFO_TYPE_VOID, Parameter(CORINFO_TYPE_NATIVEINT), );
GLOBAL_METHOD(METHOD_TRACE_EXCEPTION, &PyJit_TraceFrameException, CORINFO_TYPE_VOID, Parameter(CORINFO_TYPE_NATIVEINT), );
Expand Down