@@ -462,6 +462,12 @@ dump_local_monitors(const char *prefix, _Py_LocalMonitors monitors, FILE*out)
462462 }
463463}
464464
465+ /** NOTE:
466+ * Do not use PyCode_Addr2Line to determine the line number in instrumentation,
467+ * as `PyCode_Addr2Line` uses the monitoring data if it is available.
468+ */
469+
470+
465471/* No error checking -- Don't use this for anything but experimental debugging */
466472static void
467473dump_instrumentation_data (PyCodeObject * code , int star , FILE * out )
@@ -479,14 +485,16 @@ dump_instrumentation_data(PyCodeObject *code, int star, FILE*out)
479485 dump_local_monitors ("Active" , data -> active_monitors , out );
480486 int code_len = (int )Py_SIZE (code );
481487 bool starred = false;
488+ PyCodeAddressRange range ;
489+ _PyCode_InitAddressRange (code , & range );
482490 for (int i = 0 ; i < code_len ; i += _PyInstruction_GetLength (code , i )) {
483491 _Py_CODEUNIT * instr = & _PyCode_CODE (code )[i ];
484492 int opcode = instr -> op .code ;
485493 if (i == star ) {
486494 fprintf (out , "** " );
487495 starred = true;
488496 }
489- fprintf (out , "Offset: %d, line: %d %s: " , i , PyCode_Addr2Line ( code , i * 2 ), _PyOpcode_OpName [opcode ]);
497+ fprintf (out , "Offset: %d, line: %d %s: " , i , _PyCode_CheckLineNumber ( i * 2 , & range ), _PyOpcode_OpName [opcode ]);
490498 dump_instrumentation_data_tools (code , data -> tools , i , out );
491499 dump_instrumentation_data_lines (code , data -> lines , i , out );
492500 dump_instrumentation_data_line_tools (code , data -> line_tools , i , out );
@@ -551,6 +559,8 @@ sanity_check_instrumentation(PyCodeObject *code)
551559 code -> _co_monitoring -> active_monitors ,
552560 active_monitors ));
553561 int code_len = (int )Py_SIZE (code );
562+ PyCodeAddressRange range ;
563+ _PyCode_InitAddressRange (co , & range );
554564 for (int i = 0 ; i < code_len ;) {
555565 _Py_CODEUNIT * instr = & _PyCode_CODE (code )[i ];
556566 int opcode = instr -> op .code ;
@@ -598,7 +608,7 @@ sanity_check_instrumentation(PyCodeObject *code)
598608 }
599609 if (data -> lines && get_original_opcode (data -> lines , i )) {
600610 int line1 = compute_line (code , get_line_delta (data -> lines , i ));
601- int line2 = PyCode_Addr2Line ( code , i * sizeof (_Py_CODEUNIT ));
611+ int line2 = _PyCode_CheckLineNumber ( i * sizeof (_Py_CODEUNIT ), & range );
602612 CHECK (line1 == line2 );
603613 }
604614 CHECK (valid_opcode (opcode ));
@@ -1284,7 +1294,6 @@ _Py_Instrumentation_GetLine(PyCodeObject *code, int index)
12841294 _PyCoMonitoringData * monitoring = code -> _co_monitoring ;
12851295 assert (monitoring != NULL );
12861296 assert (monitoring -> lines != NULL );
1287- assert (index >= code -> _co_firsttraceable );
12881297 assert (index < Py_SIZE (code ));
12891298 _PyCoLineInstrumentationData * line_data = monitoring -> lines ;
12901299 int line_delta = get_line_delta (line_data , index );
@@ -1513,41 +1522,42 @@ initialize_lines(PyCodeObject *code, int bytes_per_entry)
15131522 int code_len = (int )Py_SIZE (code );
15141523 PyCodeAddressRange range ;
15151524 _PyCode_InitAddressRange (code , & range );
1516- for (int i = 0 ; i < code -> _co_firsttraceable && i < code_len ; i ++ ) {
1517- set_original_opcode (line_data , i , 0 );
1518- set_line_delta (line_data , i , NO_LINE );
1519- }
15201525 int current_line = -1 ;
1521- for (int i = code -> _co_firsttraceable ; i < code_len ; ) {
1526+ for (int i = 0 ; i < code_len ; ) {
15221527 int opcode = _Py_GetBaseCodeUnit (code , i ).op .code ;
15231528 int line = _PyCode_CheckLineNumber (i * (int )sizeof (_Py_CODEUNIT ), & range );
15241529 set_line_delta (line_data , i , compute_line_delta (code , line ));
15251530 int length = _PyInstruction_GetLength (code , i );
1526- switch (opcode ) {
1527- case END_ASYNC_FOR :
1528- case END_FOR :
1529- case END_SEND :
1530- case RESUME :
1531- /* END_FOR cannot start a line, as it is skipped by FOR_ITER
1532- * END_SEND cannot start a line, as it is skipped by SEND
1533- * RESUME must not be instrumented with INSTRUMENT_LINE */
1534- set_original_opcode (line_data , i , 0 );
1535- break ;
1536- default :
1537- /* Set original_opcode to the opcode iff the instruction
1538- * starts a line, and thus should be instrumented.
1539- * This saves having to perform this check every time the
1540- * we turn instrumentation on or off, and serves as a sanity
1541- * check when debugging.
1542- */
1543- if (line != current_line && line >= 0 ) {
1544- set_original_opcode (line_data , i , opcode );
1545- CHECK (get_line_delta (line_data , i ) != NO_LINE );
1546- }
1547- else {
1531+ if (i < code -> _co_firsttraceable ) {
1532+ set_original_opcode (line_data , i , 0 );
1533+ }
1534+ else {
1535+ switch (opcode ) {
1536+ case END_ASYNC_FOR :
1537+ case END_FOR :
1538+ case END_SEND :
1539+ case RESUME :
1540+ /* END_FOR cannot start a line, as it is skipped by FOR_ITER
1541+ * END_SEND cannot start a line, as it is skipped by SEND
1542+ * RESUME must not be instrumented with INSTRUMENT_LINE */
15481543 set_original_opcode (line_data , i , 0 );
1549- }
1550- current_line = line ;
1544+ break ;
1545+ default :
1546+ /* Set original_opcode to the opcode iff the instruction
1547+ * starts a line, and thus should be instrumented.
1548+ * This saves having to perform this check every time the
1549+ * we turn instrumentation on or off, and serves as a sanity
1550+ * check when debugging.
1551+ */
1552+ if (line != current_line && line >= 0 ) {
1553+ set_original_opcode (line_data , i , opcode );
1554+ CHECK (get_line_delta (line_data , i ) != NO_LINE );
1555+ }
1556+ else {
1557+ set_original_opcode (line_data , i , 0 );
1558+ }
1559+ current_line = line ;
1560+ }
15511561 }
15521562 for (int j = 1 ; j < length ; j ++ ) {
15531563 set_original_opcode (line_data , i + j , 0 );
0 commit comments