diff --git a/scylla-gdb.py b/scylla-gdb.py index 90d440e03b..9f7d3e2897 100644 --- a/scylla-gdb.py +++ b/scylla-gdb.py @@ -211,19 +211,26 @@ class scylla_memory(gdb.Command): front = int(span['link']['_next']) gdb.write('{index:5} {size:13} {total}\n'.format(index=index, size=(1<> shift) + value = value ^ canary + result[reg] = value + return result + + def is_switched_in(self): + jmpbuf_link_ptr = gdb.parse_and_eval('seastar::g_current_context') + if jmpbuf_link_ptr['thread'] == self.thread_ctx.address: + return True + return False + + def __init__(self, thread_ctx): + self.thread_ctx = thread_ctx + self.old_frame = gdb.selected_frame() + self.old_regs = self.save_regs() + self.old_gdb_thread = gdb.selected_thread() + self.gdb_thread = get_thread_owning_memory(thread_ctx.address) + self.new_regs = None + + def __enter__(self): + gdb.write('Switched to thread %d, (seastar::thread_context*) 0x%x\n' % (self.gdb_thread.num, self.thread_ctx.address)) + self.gdb_thread.switch() + if not self.is_switched_in(): + self.new_regs = self.regs_from_jmpbuf(self.thread_ctx['_context']['jmpbuf']) + self.restore_regs(self.new_regs) + + def __exit__(self, *_): + if self.new_regs: + self.gdb_thread.switch() + self.restore_regs(self.old_regs) + self.old_gdb_thread.switch() + self.old_frame.select() + gdb.write('Switched to thread %d\n' % self.old_gdb_thread.num) + +active_thread_context = None + +def exit_thread_context(): + global active_thread_context + if active_thread_context: + active_thread_context.__exit__() + active_thread_context = None + +class scylla_thread(gdb.Command): + def __init__(self): + gdb.Command.__init__(self, 'scylla thread', gdb.COMMAND_USER, + gdb.COMPLETE_COMMAND, True) + def invoke(self, arg, for_tty): + addr = gdb.parse_and_eval(arg) + ctx = addr.reinterpret_cast(gdb.lookup_type('seastar::thread_context').pointer()).dereference() + exit_thread_context() + global active_thread_context + active_thread_context = seastar_thread_context(ctx) + active_thread_context.__enter__() + +class scylla_unthread(gdb.Command): + def __init__(self): + gdb.Command.__init__(self, 'scylla unthread', gdb.COMMAND_USER, gdb.COMPLETE_NONE, True) + def invoke(self, arg, for_tty): + exit_thread_context() + scylla() scylla_databases() scylla_keyspaces() @@ -408,8 +556,11 @@ scylla_column_families() scylla_memory() scylla_ptr() scylla_mem_ranges() +scylla_mem_range() scylla_lsa() scylla_lsa_zones() scylla_timers() scylla_apply() scylla_shard() +scylla_thread() +scylla_unthread()