Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
sheap.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 #
3 # File: GdbUtils/python/sheap.py
4 # Created: A while ago, sss
5 # Purpose: Dump out malloc heap regions.
6 #
7 
8 import gdb
9 
10 def sheap_read_word (inf, addr):
11  mv = inf.read_memory (addr, 8)
12  return mv.cast('L')[0]
13 
14 def sheap_looks_free (inf, addr):
15  head = sheap_read_word (inf, addr+8)
16  if head > 128*1024*1024 or head < 8: return False
17  #print (hex(addr), hex(head))
18  head = head & ~1
19  if head & 2: return False
20  foot = sheap_read_word (inf, addr+head)
21  if head != foot: return False
22  nexthead = sheap_read_word (inf, addr+head+8)
23  if nexthead & 1: return False
24  #print ('found', hex(addr), hex(head), hex(foot), hex(nexthead))
25  return True
26 
27 def sheap_scan_2 (inf, addr):
28  head = sheap_read_word (inf, addr+8)
29  if head > 128*1024*1024 or head < 8:
30  return addr+8, False
31  head = head & ~1
32  if head & 2:
33  return addr+8, False
34  nexthead = sheap_read_word (inf, addr+head+8)
35  if nexthead & 1:
36  type = ' USED '
37  else:
38  if not sheap_looks_free (inf, addr):
39  return addr+8, False
40  type = ' FREE '
41  #print('sheap_scan_2' ,hex(addr), hex(head), hex(nexthead), type)
42  s = f'{int(addr):016x}:{type}{int(head):08x}\n'
43  gdb.write (s)
44  return addr+head, True
45 
46 def sheap_scan_1 (addr1, addr2, forced):
47  inf = gdb.selected_inferior()
48  addr1 = (addr1 + 7) & ~7 # Align
49  if not forced:
50  while addr1 < addr2 and not sheap_looks_free (inf, addr1):
51  addr1 += 8
52  while addr1 < addr2:
53  addr1, ok = sheap_scan_2 (inf, addr1)
54  if not ok: break
55  return addr1
56 
57 def sheap_scan (addr1, addr2, forced):
58  addr1 -= 8
59  while addr1 < addr2:
60  addr1 = sheap_scan_1 (addr1, addr2, forced)
61  forced = False
62  gdb.flush()
63  return
64 
65 
66 def sheap (arg, forced):
67  args = arg.split()
68  if not args:
69  raise gdb.GdbError ('Missing start address')
70  start_arg = gdb.parse_and_eval (args[0])
71  end_arg = gdb.parse_and_eval (args[1]) if len(args) > 1 else start_arg + 1024
72  return sheap_scan (start_arg, end_arg, forced)
73 
74 
75 class SHeap (gdb.Command):
76  """Dump out malloc heap in a range of addresses, showed allocated/free blocks.
77 
78  sheap START-ADDR [END-ADDR]
79  will dump out free and allocated malloc blocks within the given address
80  range. If not given, END-ADDR is taken to be 1024 bytes after START-ADDR.
81 
82  Caveats: It is not possible to reliably identify allocated memory blocks.
83  Dumping will start at the first free block found within
84  the given range, if any.
85 
86  This only works with the GNU libc malloc, not with any
87  alternative allocators (tcmalloc, etc).
88  """
89  def __init__ (self):
90  super (SHeap, self).__init__ ("sheap", gdb.COMMAND_DATA)
91  return
92 
93  def invoke (self, arg, from_tty):
94  return sheap (arg, False)
95 
96 
97 SHeap()
python.sheap.sheap_scan
def sheap_scan(addr1, addr2, forced)
Definition: sheap.py:57
python.sheap.SHeap.__init__
def __init__(self)
Definition: sheap.py:89
python.sheap.sheap_read_word
def sheap_read_word(inf, addr)
Definition: sheap.py:10
python.sheap.SHeap.invoke
def invoke(self, arg, from_tty)
Definition: sheap.py:93
python.sheap.sheap
def sheap(arg, forced)
Definition: sheap.py:66
python.sheap.sheap_scan_1
def sheap_scan_1(addr1, addr2, forced)
Definition: sheap.py:46
python.sheap.sheap_looks_free
def sheap_looks_free(inf, addr)
Definition: sheap.py:14
python.sheap.SHeap
Definition: sheap.py:75
python.sheap.sheap_scan_2
def sheap_scan_2(inf, addr)
Definition: sheap.py:27