Created
May 24, 2017 22:06
-
-
Save aclements/e8b4b3d887ccc9fd2907e696a8b4b2a2 to your computer and use it in GitHub Desktop.
Failed attempt at using GDB unwinders for Go core files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
try: | |
from gdb.unwinder import Unwinder, register_unwinder | |
except ImportError: | |
Unwinder = None | |
if Unwinder is not None: | |
class FrameID(object): | |
def __init__(self, sp, pc): | |
self.sp = sp | |
self.pc = pc | |
class GoUnwinder(Unwinder): | |
def __init__(self): | |
super(GoUnwinder, self).__init__("go-unwinder") | |
self.enabled = False | |
def __call__(self, pending_frame): | |
# print("GoUnwinder.__call__", pending_frame, self.frame_id) | |
# This only applies to the first frame. | |
self.enabled = False | |
# Maybe they need to be the exact right types? | |
# Doesn't seem to help. | |
# pc = pending_frame.read_register('rip') | |
# sp = pending_frame.read_register('rsp') | |
# self.frame_id.pc = self.frame_id.pc.cast(pc.type) | |
# self.frame_id.sp = self.frame_id.sp.cast(sp.type) | |
# print(self.frame_id.pc, self.frame_id.sp) | |
# Ignore registers in pending_frame. Use stashed PC/SP. | |
unwind_info = pending_frame.create_unwind_info(self.frame_id) | |
# Maybe they need to also be saved registers? | |
# Doesn't seem to help. | |
# unwind_info.add_saved_register('rip', self.frame_id.pc) | |
# unwind_info.add_saved_register('rsp', self.frame_id.sp) | |
return unwind_info | |
goUnwinder = GoUnwinder() | |
register_unwinder(None, goUnwinder, replace=True) | |
def ngoroutine(self, arg, _from_tty): | |
goid, cmd = arg.split(None, 1) | |
goid = gdb.parse_and_eval(goid) | |
pc, sp = find_goroutine(int(goid)) | |
if not pc: | |
print("No such goroutine: ", goid) | |
return | |
try: | |
#python3 / newer versions of gdb | |
pc = int(pc) | |
except gdb.error: | |
pc = int(str(pc).split(None, 1)[0], 16) | |
goUnwinder.frame_id = FrameID(gdb.Value(sp), gdb.Value(pc)) | |
goUnwinder.enabled = True | |
try: | |
gdb.execute(cmd) | |
finally: | |
goUnwinder.enabled = False | |
GoroutineCmd.invoke = ngoroutine |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@BDHorn Have a look at this. golang/go#17575 (comment) This is not my final version but as i do not have authorization this is the extent of what i can contribute