mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-26 11:30:36 +00:00
Useful for analyzing memory leaks:
(gdb) scylla memory
objsz spansz usedobj memory wst%
1 4096 0 0 0.0
1 4096 0 0 0.0
1 4096 0 0 0.0
1 4096 0 0 0.0
2 4096 0 0 0.0
2 4096 0 0 0.0
3 4096 0 0 0.0
3 4096 0 0 0.0
4 4096 0 0 0.0
5 4096 0 0 0.0
6 4096 0 0 0.0
7 4096 0 0 0.0
8 4096 422 8192 58.8
10 4096 0 0 0.0
12 4096 0 0 0.0
14 4096 0 8192 99.8
16 4096 409 8192 20.1
20 4096 0 0 0.0
24 4096 0 0 0.0
28 4096 653 24576 25.4
32 4096 1069 36864 7.2
40 4096 0 0 0.0
48 4096 0 0 0.0
56 4096 1228 73728 6.5
64 4096 616 40960 3.8
80 4096 0 0 0.0
96 4096 0 0 0.0
112 4096 919 110592 5.4
128 4096 141 24576 26.6
160 8192 0 0 0.0
192 8192 0 0 0.0
224 8192 128 49152 40.1
256 8192 72 40960 55.0
320 16384 0 0 0.0
384 16384 0 0 0.0
448 16384 60 49152 43.8
512 16384 29 49152 69.8
640 32768 0 0 0.0
768 32768 0 0 0.0
896 32768 47 98304 55.6
1024 32768 5 98304 94.8
1280 65536 0 0 0.0
1536 65536 0 0 0.0
1792 65536 31 196608 70.2
2048 65536 8 196608 91.7
2560 131072 0 0 0.0
3072 131072 0 0 0.0
3584 131072 34 393216 67.4
4096 131072 0 393216 100.0
5120 262144 0 0 0.0
6144 262144 0 0 0.0
7168 262144 33 786432 68.4
8192 262144 4 786432 95.8
10240 524288 0 0 0.0
12288 524288 0 0 0.0
14336 524288 33 1572864 68.4
16384 524288 0 1572864 100.0
127 lines
5.1 KiB
Python
127 lines
5.1 KiB
Python
import gdb, gdb.printing, uuid
|
|
|
|
def uint64_t(val):
|
|
val = int(val)
|
|
if val < 0:
|
|
val += 1 << 64
|
|
return val
|
|
|
|
class sstring_printer(gdb.printing.PrettyPrinter):
|
|
'print an sstring'
|
|
def __init__(self, val):
|
|
self.val = val
|
|
def to_string(self):
|
|
if self.val['u']['internal']['size'] >= 0:
|
|
array = self.val['u']['internal']['str']
|
|
len = int(self.val['u']['internal']['size'])
|
|
return ''.join([chr(array[x]) for x in range(len)])
|
|
else:
|
|
return self.val['u']['external']['str']
|
|
def display_hint(self):
|
|
return 'string'
|
|
|
|
class uuid_printer(gdb.printing.PrettyPrinter):
|
|
'print a uuid'
|
|
def __init__(self, val):
|
|
self.val = val
|
|
def to_string(self):
|
|
msb = uint64_t(self.val['most_sig_bits'])
|
|
lsb = uint64_t(self.val['least_sig_bits'])
|
|
return str(uuid.UUID(int=(msb << 64) | lsb))
|
|
def display_hint(self):
|
|
return 'string'
|
|
|
|
|
|
def build_pretty_printer():
|
|
pp = gdb.printing.RegexpCollectionPrettyPrinter('scylla')
|
|
pp.add_printer('sstring', r'^basic_sstring<char,.*>$', sstring_printer)
|
|
pp.add_printer('uuid', r'^utils::UUID$', uuid_printer)
|
|
return pp
|
|
|
|
gdb.printing.register_pretty_printer(gdb.current_objfile(), build_pretty_printer())
|
|
|
|
def cpus():
|
|
return int(gdb.parse_and_eval('smp::count'))
|
|
|
|
def find_db(shard):
|
|
return gdb.parse_and_eval('debug::db')['_instances']['_M_impl']['_M_start'][shard]
|
|
|
|
def find_dbs():
|
|
return [find_db(shard) for shard in range(cpus())]
|
|
|
|
def list_unordered_map(map):
|
|
kt = map.type.template_argument(0)
|
|
vt = map.type.template_argument(1)
|
|
value_type = gdb.lookup_type('std::pair<{} const, {}>'.format(kt.name, vt.name))
|
|
hashnode_ptr_type = gdb.lookup_type('std::__detail::_Hash_node<' + value_type.name + ', true>').pointer()
|
|
h = map['_M_h']
|
|
p = h['_M_before_begin']['_M_nxt']
|
|
while p:
|
|
pc = p.cast(hashnode_ptr_type)['_M_storage']['_M_storage']['__data'].cast(value_type.pointer())
|
|
yield (pc['first'], pc['second'].address)
|
|
p = p['_M_nxt']
|
|
raise StopIteration()
|
|
|
|
class scylla(gdb.Command):
|
|
def __init__(self):
|
|
gdb.Command.__init__(self, 'scylla', gdb.COMMAND_USER, gdb.COMPLETE_COMMAND, True)
|
|
|
|
class scylla_databases(gdb.Command):
|
|
def __init__(self):
|
|
gdb.Command.__init__(self, 'scylla databases', gdb.COMMAND_USER, gdb.COMPLETE_COMMAND)
|
|
def invoke(self, arg, from_tty):
|
|
for shard in range(cpus()):
|
|
db = find_db(shard)
|
|
gdb.write('{:5} (database*){}\n'.format(shard, db))
|
|
|
|
class scylla_keyspaces(gdb.Command):
|
|
def __init__(self):
|
|
gdb.Command.__init__(self, 'scylla keyspaces', gdb.COMMAND_USER, gdb.COMPLETE_COMMAND)
|
|
def invoke(self, arg, from_tty):
|
|
for shard in range(cpus()):
|
|
db = find_db(shard)
|
|
keyspaces = db['_keyspaces']
|
|
for (key, value) in list_unordered_map(keyspaces):
|
|
gdb.write('{:5} {:20} (keyspace*){}\n'.format(shard, key, value))
|
|
|
|
class scylla_column_families(gdb.Command):
|
|
def __init__(self):
|
|
gdb.Command.__init__(self, 'scylla column_families', gdb.COMMAND_USER, gdb.COMPLETE_COMMAND)
|
|
def invoke(self, arg, from_tty):
|
|
for shard in range(cpus()):
|
|
db = find_db(shard)
|
|
cfs = db['_column_families']
|
|
for (key, value) in list_unordered_map(cfs):
|
|
value = value['_p']['_value'] # it's a lw_shared_ptr
|
|
schema = value['_schema']['_p']['_value']
|
|
name = str(schema['_raw']['_ks_name']) + '/' + str(schema['_raw']['_cf_name'])
|
|
gdb.write('{:5} {} {:45} (column_family*){}\n'.format(shard, key, name, value.address))
|
|
|
|
class scylla_memory(gdb.Command):
|
|
def __init__(self):
|
|
gdb.Command.__init__(self, 'scylla memory', gdb.COMMAND_USER, gdb.COMPLETE_COMMAND)
|
|
def invoke(self, arg, from_tty):
|
|
cpu_mem = gdb.parse_and_eval('memory::cpu_mem')
|
|
small_pools = cpu_mem['small_pools']
|
|
nr = small_pools['nr_small_pools']
|
|
page_size = int(gdb.parse_and_eval('memory::page_size'))
|
|
gdb.write('{objsize:>5} {span_size:>6} {use_count:>10} {memory:>12} {wasted_percent:>5}\n'
|
|
.format(objsize='objsz', span_size='spansz', use_count='usedobj', memory='memory', wasted_percent='wst%'))
|
|
for i in range(int(nr)):
|
|
sp = small_pools['_u']['a'][i]
|
|
object_size = int(sp['_object_size'])
|
|
span_size = int(sp['_span_size']) * page_size
|
|
free_count = int(sp['_free_count'])
|
|
spans_in_use = int(sp['_spans_in_use'])
|
|
memory = spans_in_use * span_size
|
|
use_count = spans_in_use * int(span_size / object_size) - free_count
|
|
wasted = free_count * object_size
|
|
wasted_percent = wasted * 100.0 / memory if memory else 0
|
|
gdb.write('{objsize:5} {span_size:6} {use_count:10} {memory:12} {wasted_percent:5.1f}\n'
|
|
.format(objsize=object_size, span_size=span_size, use_count=use_count, memory=memory, wasted_percent=wasted_percent))
|
|
|
|
scylla()
|
|
scylla_databases()
|
|
scylla_keyspaces()
|
|
scylla_column_families()
|
|
scylla_memory() |