In digging around the code, I asked claude what it would take to emit RPython file/linenumbers instead of the more cryptic generated C file/linenumbers in fatal error tracebacks. Here was the answer:
The change requires three files:
-
rpython/translator/exceptiontransform.py
- Import offset2lineno from rpython.tool.error
- In
gen_exc_check, after identifying spaceop = block.operations[-1], derive the RPython source location:
- filename from
graph.func.__code__.co_filename (with a fallback for graphs without a func)
- lineno from
offset2lineno(graph.func.__code__, spaceop.offset) if spaceop.offset >= 0, else graph.func.__code__.co_firstlineno
- Attach both as extra attributes on the
debug_record_traceback SpaceOperation (e.g. op.rpy_filename, op.rpy_lineno)
- Same for the second creation site in the except block handler (line ~358), where the relevant location is the graph's first line rather than a specific op offset
-
rpython/translator/c/funcgen.py
- In
OP_DEBUG_RECORD_TRACEBACK and OP_DEBUG_CATCH_EXCEPTION, read rpy_filename/rpy_lineno from op (with fallback to current behaviour if absent)
- Emit the RPython filename and lineno as string/integer literals rather than
PYPY_FILE_NAME/__LINE__
-
rpython/translator/c/src/debug_traceback.h
- Change
PYPY_DEBUG_RECORD_TRACEBACK(funcname) and PYPY_DEBUG_CATCH_EXCEPTION(funcname, etype, is_fatal) to accept explicit filename and lineno parameters instead of using PYPY_FILE_NAME and
__LINE__
- The static struct
pypydtpos_s loc initializer changes from { PYPY_FILE_NAME, funcname, __LINE__ } to { filename, funcname, lineno }
PYPY_FILE_NAME can then be removed since nothing references it
The result: crash tracebacks show e.g. File "pypy/interpreter/pyframe.py", line 345, in execute_frame instead of File "pypy_interpreter_1.c", line 52934, in execute_frame.
In digging around the code, I asked claude what it would take to emit RPython file/linenumbers instead of the more cryptic generated C file/linenumbers in fatal error tracebacks. Here was the answer:
The change requires three files:
rpython/translator/exceptiontransform.py
gen_exc_check, after identifyingspaceop = block.operations[-1], derive the RPython source location:graph.func.__code__.co_filename(with a fallback for graphs without a func)offset2lineno(graph.func.__code__, spaceop.offset)ifspaceop.offset >= 0, elsegraph.func.__code__.co_firstlinenodebug_record_tracebackSpaceOperation (e.g.op.rpy_filename,op.rpy_lineno)rpython/translator/c/funcgen.py
OP_DEBUG_RECORD_TRACEBACKandOP_DEBUG_CATCH_EXCEPTION, readrpy_filename/rpy_linenofromop(with fallback to current behaviour if absent)PYPY_FILE_NAME/__LINE__rpython/translator/c/src/debug_traceback.h
PYPY_DEBUG_RECORD_TRACEBACK(funcname)andPYPY_DEBUG_CATCH_EXCEPTION(funcname, etype, is_fatal)to accept explicit filename and lineno parameters instead of usingPYPY_FILE_NAMEand__LINE__pypydtpos_sloc initializer changes from{ PYPY_FILE_NAME, funcname, __LINE__ }to{ filename, funcname, lineno }PYPY_FILE_NAMEcan then be removed since nothing references itThe result: crash tracebacks show e.g. File "pypy/interpreter/pyframe.py", line 345, in execute_frame instead of File "pypy_interpreter_1.c", line 52934, in execute_frame.