From a9d37f0e20cc2bb1d47c6001afd16c73dfbd068a Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 26 Jul 2015 18:52:57 +0300 Subject: [PATCH 1/4] debug: store database pointer in a static variable This makes it easily accessible to a debugger --- debug.hh | 17 +++++++++++++++++ main.cc | 8 ++++++++ 2 files changed, 25 insertions(+) create mode 100644 debug.hh diff --git a/debug.hh b/debug.hh new file mode 100644 index 0000000000..25aded8742 --- /dev/null +++ b/debug.hh @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2015 Cloudius Systems, Ltd. + */ + +#pragma once + +#include + +class database; + +namespace debug { + +extern seastar::sharded* db; + + +} + diff --git a/main.cc b/main.cc index 1c78434426..b66fabb621 100644 --- a/main.cc +++ b/main.cc @@ -18,6 +18,7 @@ #include "utils/runtime.hh" #include "dns.hh" #include "log.hh" +#include "debug.hh" #include namespace bpo = boost::program_options; @@ -67,6 +68,7 @@ int main(int ac, char** av) { ; distributed db; + debug::db = &db; distributed qp; auto& proxy = service::get_storage_proxy(); api::http_context ctx(db, proxy); @@ -168,3 +170,9 @@ int main(int ac, char** av) { }); }); } + +namespace debug { + +seastar::sharded* db; + +} From 53856bf2d13153f2cdcfd8850919bcd1e2ea4941 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 26 Jul 2015 16:25:19 +0300 Subject: [PATCH 2/4] Add gdb pretty-printing script --- scylla-gdb.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 scylla-gdb.py diff --git a/scylla-gdb.py b/scylla-gdb.py new file mode 100644 index 0000000000..b1355e1c7e --- /dev/null +++ b/scylla-gdb.py @@ -0,0 +1,22 @@ +import gdb, gdb.printing + +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 = 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' + +def build_pretty_printer(): + pp = gdb.printing.RegexpCollectionPrettyPrinter('scylla') + pp.add_printer('sstring', r'^basic_sstring$', sstring_printer) + return pp + +gdb.printing.register_pretty_printer(gdb.current_objfile(), build_pretty_printer()) From e8dbfdb56b2eee4d80204b450f3934022abe0a40 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 26 Jul 2015 18:50:23 +0300 Subject: [PATCH 3/4] gdb: pretty-print uuids --- scylla-gdb.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/scylla-gdb.py b/scylla-gdb.py index b1355e1c7e..db9aef9311 100644 --- a/scylla-gdb.py +++ b/scylla-gdb.py @@ -1,4 +1,10 @@ -import gdb, gdb.printing +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' @@ -14,9 +20,22 @@ class sstring_printer(gdb.printing.PrettyPrinter): 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$', sstring_printer) + pp.add_printer('uuid', r'^utils::UUID$', uuid_printer) return pp gdb.printing.register_pretty_printer(gdb.current_objfile(), build_pretty_printer()) From 72cc2c0115b6771560fa8159ec2d595265098160 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 26 Jul 2015 18:50:44 +0300 Subject: [PATCH 4/4] gdb: list database, keyspace, column_family (gdb) scylla databases 0 (database*)0x60000009c900 1 (database*)0x60100011bf00 (gdb) scylla keyspaces 0 "system" (keyspace*)0x6000000cacf8 1 "system" (keyspace*)0x601000114018 (gdb) scylla column_families 0 "5a1ff267-ace0-3f12-8563-cfae6103c65e" "system"/"sstable_activity" (column_family*)0x60000010bf88 0 "b4dbb7b4-dc49-3fb5-b3bf-ce6e434832ca" "system"/"compaction_history" (column_family*)0x60000010c148 0 "55d76438-4e55-3f8b-9f6e-676d4af3976d" "system"/"range_xfers" (column_family*)0x60000010c4c8 0 "59dfeaea-8db2-3341-91ef-109974d81484" "system"/"peer_events" (column_family*)0x60000010c688 0 "37f71aca-7dc2-383b-a706-72528af04d4f" "system"/"peers" (column_family*)0x60000010c848 0 "7ad54392-bcdd-35a6-8417-4e047860b377" "system"/"local" (column_family*)0x60000010ca08 0 "b7b7f0c2-fd0a-3410-8c05-3ef614bb7c2d" "system"/"paxos" (column_family*)0x60000010cbc8 0 "d1b675fe-2b50-3ca4-8e49-c0f81989dcad" "system"/"schema_functions" (column_family*)0x60000010d488 0 "296e9c04-9bec-3085-827d-c17d3df2122a" "system"/"schema_columns" (column_family*)0x60000010d9c8 0 "9f5c6374-d485-3229-9a0a-5094af9ad1e3" "system"/"IndexInfo" (column_family*)0x60000010d108 0 "0359bc71-7123-3ee1-9a4a-b9dfb11fc125" "system"/"schema_triggers" (column_family*)0x60000010d808 0 "0290003c-977e-397c-ac3e-fdfdc01d626b" "system"/"batchlog" (column_family*)0x60000010cd88 0 "3aa75225-4f82-350b-8d5c-430fa221fa0a" "system"/"schema_usertypes" (column_family*)0x60000010d648 0 "55080ab0-5d9c-3886-90a4-acb25fe1f77b" "system"/"compactions_in_progress" (column_family*)0x60000010c308 0 "b0f22357-4458-3cdb-9631-c43e59ce3676" "system"/"schema_keyspaces" (column_family*)0x60000010db88 0 "45f5b360-24bc-3f83-a363-1034ea4fa697" "system"/"schema_columnfamilies" (column_family*)0x60000010e008 0 "a5fc57fc-9d6c-3bfd-a3fc-01ad54686fea" "system"/"schema_aggregates" (column_family*)0x60000010d2c8 0 "2666e205-73ef-38b3-90fe-fecf96e8f0c7" "system"/"hints" (column_family*)0x60000010cf48 1 "5a1ff267-ace0-3f12-8563-cfae6103c65e" "system"/"sstable_activity" (column_family*)0x601000121f88 1 "b4dbb7b4-dc49-3fb5-b3bf-ce6e434832ca" "system"/"compaction_history" (column_family*)0x601000122148 1 "55d76438-4e55-3f8b-9f6e-676d4af3976d" "system"/"range_xfers" (column_family*)0x6010001224c8 1 "59dfeaea-8db2-3341-91ef-109974d81484" "system"/"peer_events" (column_family*)0x601000122688 1 "37f71aca-7dc2-383b-a706-72528af04d4f" "system"/"peers" (column_family*)0x601000122848 1 "7ad54392-bcdd-35a6-8417-4e047860b377" "system"/"local" (column_family*)0x601000122a08 1 "b7b7f0c2-fd0a-3410-8c05-3ef614bb7c2d" "system"/"paxos" (column_family*)0x601000122bc8 1 "d1b675fe-2b50-3ca4-8e49-c0f81989dcad" "system"/"schema_functions" (column_family*)0x601000123488 1 "296e9c04-9bec-3085-827d-c17d3df2122a" "system"/"schema_columns" (column_family*)0x6010001239c8 1 "9f5c6374-d485-3229-9a0a-5094af9ad1e3" "system"/"IndexInfo" (column_family*)0x601000123108 1 "0359bc71-7123-3ee1-9a4a-b9dfb11fc125" "system"/"schema_triggers" (column_family*)0x601000123808 1 "0290003c-977e-397c-ac3e-fdfdc01d626b" "system"/"batchlog" (column_family*)0x601000122d88 1 "3aa75225-4f82-350b-8d5c-430fa221fa0a" "system"/"schema_usertypes" (column_family*)0x601000123648 1 "55080ab0-5d9c-3886-90a4-acb25fe1f77b" "system"/"compactions_in_progress" (column_family*)0x601000122308 1 "b0f22357-4458-3cdb-9631-c43e59ce3676" "system"/"schema_keyspaces" (column_family*)0x601000123b88 1 "45f5b360-24bc-3f83-a363-1034ea4fa697" "system"/"schema_columnfamilies" (column_family*)0x601000124008 1 "a5fc57fc-9d6c-3bfd-a3fc-01ad54686fea" "system"/"schema_aggregates" (column_family*)0x6010001232c8 1 "2666e205-73ef-38b3-90fe-fecf96e8f0c7" "system"/"hints" (column_family*)0x601000122f48 --- scylla-gdb.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/scylla-gdb.py b/scylla-gdb.py index db9aef9311..cd3a24dbd1 100644 --- a/scylla-gdb.py +++ b/scylla-gdb.py @@ -39,3 +39,65 @@ def build_pretty_printer(): return pp gdb.printing.register_pretty_printer(gdb.current_objfile(), build_pretty_printer()) + +def cpus(): + return 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)) + +scylla() +scylla_databases() +scylla_keyspaces() +scylla_column_families()