@@ -109,6 +109,10 @@ class Symbolizer:
109
109
self .__html = False
110
110
self .__last_access_address = None
111
111
self .__last_access_tag = None
112
+ self .__tag_dump = []
113
+ self .__tag_dump_match_idx = None
114
+ self .__matched_stack_uas = False
115
+ self .__offsets = []
112
116
113
117
def enable_html (self , enable ):
114
118
self .__html = enable
@@ -311,6 +315,34 @@ class Symbolizer:
311
315
if match :
312
316
self .__last_access_tag = int (match .group (2 ), 16 )
313
317
318
+ def process_tag_dump_line (self , line , ignore_tags = False ):
319
+ m = re .match (r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16 , line )
320
+ if m is None :
321
+ return False
322
+ addr = m .group (1 )
323
+ tags = m .group (* range (2 , 18 ))
324
+ fault = [i for i , x in enumerate (tags ) if '[' in x ]
325
+ if fault :
326
+ self .__tag_dump_match_idx = len (self .__tag_dump ) + fault [0 ]
327
+ self .__tag_dump .extend (int (x .strip (' [' ).rstrip ('] ' ), 16 ) for x in tags )
328
+ return True
329
+
330
+ def finish_tag_dump (self ):
331
+ if self .__matched_stack_uas or self .__tag_dump_match_idx is None :
332
+ return
333
+ for offset , size , local in sorted (self .__offsets , key = lambda x : abs (x [0 ])):
334
+ idx = self .__tag_dump_match_idx - offset // 16
335
+ if idx < 0 or idx > len (self .__tag_dump ):
336
+ continue
337
+ if self .__tag_dump [idx ] == self .__last_access_tag :
338
+ self .print ('' )
339
+ self .print ('Potentially referenced stack object:' )
340
+ if offset > 0 :
341
+ self .print (' %d bytes after a variable "%s" in stack frame of function "%s"' % (offset - size , local [2 ], local [0 ]))
342
+ if offset < 0 :
343
+ self .print (' %d bytes before a variable "%s" in stack frame of function "%s"' % (- offset , local [2 ], local [0 ]))
344
+ self .print (' at %s' % (local [1 ],))
345
+
314
346
def process_stack_history (self , line , ignore_tags = False ):
315
347
if self .__last_access_address is None or self .__last_access_tag is None :
316
348
return
@@ -336,16 +368,18 @@ class Symbolizer:
336
368
size = local [4 ]
337
369
if frame_offset is None or size is None :
338
370
continue
339
- obj_offset = (self .__last_access_address - fp - frame_offset ) & fp_mask
340
- if obj_offset >= size :
341
- continue
371
+ obj_offset = (self .__last_access_address & fp_mask ) - ((fp & fp_mask ) + frame_offset )
342
372
tag_offset = local [5 ]
343
373
if not ignore_tags and (tag_offset is None or base_tag ^ tag_offset != self .__last_access_tag ):
344
374
continue
375
+ if obj_offset < 0 or obj_offset >= size :
376
+ self .__offsets .append ((obj_offset , size , local ))
377
+ continue
345
378
self .print ('' )
346
379
self .print ('Potentially referenced stack object:' )
347
380
self .print (' %d bytes inside a variable "%s" in stack frame of function "%s"' % (obj_offset , local [2 ], local [0 ]))
348
381
self .print (' at %s' % (local [1 ],))
382
+ self .__matched_stack_uas = True
349
383
return True
350
384
return False
351
385
@@ -456,9 +490,18 @@ def main():
456
490
sys .exit (1 )
457
491
symbolizer .read_linkify (args .linkify )
458
492
493
+ tag_dump = False
459
494
for line in sys .stdin :
460
495
if sys .version_info .major < 3 :
461
496
line = line .decode ('utf-8' )
497
+ if tag_dump :
498
+ tag_dump = symbolizer .process_tag_dump_line (line )
499
+ if tag_dump :
500
+ continue
501
+ symbolizer .finish_tag_dump ()
502
+ if 'Memory tags around the buggy address' in line :
503
+ tag_dump = True
504
+
462
505
symbolizer .save_access_address (line )
463
506
if symbolizer .process_stack_history (line , ignore_tags = args .ignore_tags ):
464
507
continue
0 commit comments