@@ -934,35 +934,50 @@ def current_line_num(self):
934934 if long (f_trace ) != 0 :
935935 # we have a non-NULL f_trace:
936936 return self .f_lineno
937- else :
938- # try:
937+
938+ try :
939939 return self .co .addr2line (self .f_lasti )
940- #except ValueError:
941- # return self.f_lineno
940+ except Exception :
941+ # bpo-34989: addr2line() is a complex function, it can fail in many
942+ # ways. For example, it fails with a TypeError on "FakeRepr" if
943+ # gdb fails to load debug symbols. Use a catch-all "except
944+ # Exception" to make the whole function safe. The caller has to
945+ # handle None anyway for optimized Python.
946+ return None
942947
943948 def current_line (self ):
944949 '''Get the text of the current source line as a string, with a trailing
945950 newline character'''
946951 if self .is_optimized_out ():
947952 return '(frame information optimized out)'
953+
954+ lineno = self .current_line_num ()
955+ if lineno is None :
956+ return '(failed to get frame line number)'
957+
948958 filename = self .filename ()
949959 try :
950- f = open (os_fsencode (filename ), 'r' )
960+ with open (os_fsencode (filename ), 'r' ) as fp :
961+ lines = fp .readlines ()
951962 except IOError :
952963 return None
953- with f :
954- all_lines = f .readlines ()
955- # Convert from 1-based current_line_num to 0-based list offset:
956- return all_lines [self .current_line_num ()- 1 ]
964+
965+ try :
966+ # Convert from 1-based current_line_num to 0-based list offset
967+ return lines [lineno - 1 ]
968+ except IndexError :
969+ return None
957970
958971 def write_repr (self , out , visited ):
959972 if self .is_optimized_out ():
960973 out .write ('(frame information optimized out)' )
961974 return
962- out .write ('Frame 0x%x, for file %s, line %i, in %s ('
975+ lineno = self .current_line_num ()
976+ lineno = str (lineno ) if lineno is not None else "?"
977+ out .write ('Frame 0x%x, for file %s, line %s, in %s ('
963978 % (self .as_address (),
964979 self .co_filename .proxyval (visited ),
965- self . current_line_num () ,
980+ lineno ,
966981 self .co_name .proxyval (visited )))
967982 first = True
968983 for pyop_name , pyop_value in self .iter_locals ():
@@ -981,9 +996,11 @@ def print_traceback(self):
981996 sys .stdout .write (' (frame information optimized out)\n ' )
982997 return
983998 visited = set ()
984- sys .stdout .write (' File "%s", line %i, in %s\n '
999+ lineno = self .current_line_num ()
1000+ lineno = str (lineno ) if lineno is not None else "?"
1001+ sys .stdout .write (' File "%s", line %s, in %s\n '
9851002 % (self .co_filename .proxyval (visited ),
986- self . current_line_num () ,
1003+ lineno ,
9871004 self .co_name .proxyval (visited )))
9881005
9891006class PySetObjectPtr (PyObjectPtr ):
@@ -1732,6 +1749,9 @@ def invoke(self, args, from_tty):
17321749
17331750 filename = pyop .filename ()
17341751 lineno = pyop .current_line_num ()
1752+ if lineno is None :
1753+ print ('Unable to read python frame line number' )
1754+ return
17351755
17361756 if start is None :
17371757 start = lineno - 5
0 commit comments