@@ -934,35 +934,50 @@ def current_line_num(self):
934
934
if long (f_trace ) != 0 :
935
935
# we have a non-NULL f_trace:
936
936
return self .f_lineno
937
- else :
938
- # try:
937
+
938
+ try :
939
939
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
942
947
943
948
def current_line (self ):
944
949
'''Get the text of the current source line as a string, with a trailing
945
950
newline character'''
946
951
if self .is_optimized_out ():
947
952
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
+
948
958
filename = self .filename ()
949
959
try :
950
- f = open (os_fsencode (filename ), 'r' )
960
+ with open (os_fsencode (filename ), 'r' ) as fp :
961
+ lines = fp .readlines ()
951
962
except IOError :
952
963
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
957
970
958
971
def write_repr (self , out , visited ):
959
972
if self .is_optimized_out ():
960
973
out .write ('(frame information optimized out)' )
961
974
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 ('
963
978
% (self .as_address (),
964
979
self .co_filename .proxyval (visited ),
965
- self . current_line_num () ,
980
+ lineno ,
966
981
self .co_name .proxyval (visited )))
967
982
first = True
968
983
for pyop_name , pyop_value in self .iter_locals ():
@@ -981,9 +996,11 @@ def print_traceback(self):
981
996
sys .stdout .write (' (frame information optimized out)\n ' )
982
997
return
983
998
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 '
985
1002
% (self .co_filename .proxyval (visited ),
986
- self . current_line_num () ,
1003
+ lineno ,
987
1004
self .co_name .proxyval (visited )))
988
1005
989
1006
class PySetObjectPtr (PyObjectPtr ):
@@ -1732,6 +1749,9 @@ def invoke(self, args, from_tty):
1732
1749
1733
1750
filename = pyop .filename ()
1734
1751
lineno = pyop .current_line_num ()
1752
+ if lineno is None :
1753
+ print ('Unable to read python frame line number' )
1754
+ return
1735
1755
1736
1756
if start is None :
1737
1757
start = lineno - 5
0 commit comments