diff --git a/hphp/tools/gdb/gdbutils.py b/hphp/tools/gdb/gdbutils.py index 015a75250e4e0..4ef11f460d335 100644 --- a/hphp/tools/gdb/gdbutils.py +++ b/hphp/tools/gdb/gdbutils.py @@ -126,7 +126,11 @@ def string_data_val(val, keep_case=True): else: data = val['m_data'] - s = data.string('utf-8', 'ignore', val['m_len']) + try: + s = data.string('utf-8', 'ignore', val['m_len']) + except: + s = "Unknown" + return s if keep_case else s.lower() @@ -300,3 +304,14 @@ def deref(val): return val.cast(rawtype(val.type)) else: return deref(p.referenced_value()) + + +def get_arch(self): + """Get gdb Architecture Object name""" + try: + return gdb.selected_frame().architecture().name() + except: + return re.search('\(currently (.*)\)', + gdb.execute('show architecture', to_string=True) + ).group(1) + diff --git a/hphp/tools/gdb/stack.py b/hphp/tools/gdb/stack.py index a9ab904fc8584..4144954bc7ff9 100644 --- a/hphp/tools/gdb/stack.py +++ b/hphp/tools/gdb/stack.py @@ -79,7 +79,10 @@ def invoke(self, args, from_tty): # Set fp = $rbp, rip = $rip. fp_type = T('uintptr_t').pointer() - fp = native_frame.read_register('rbp').cast(fp_type) + if get_arch(self) == 'aarch64': + fp = native_frame.read_register('x29').cast(fp_type) + else: + fp = native_frame.read_register('rbp').cast(fp_type) rip = native_frame.pc() if len(argv) == 1: @@ -196,8 +199,13 @@ def invoke(self, args, from_tty): return fp_type = T('uintptr_t').pointer() - fp = gdb.parse_and_eval('$rbp').cast(fp_type) - rip = gdb.parse_and_eval('$rip').cast(T('uintptr_t')) + if get_arch(self) == 'aarch64': + fp = gdb.parse_and_eval('x29').cast(fp_type) + rip = gdb.parse_and_eval('x30').cast(T('uintptr_t')) + else: + fp = gdb.parse_and_eval('$rbp').cast(fp_type) + rip = gdb.parse_and_eval('$rip').cast(T('uintptr_t')) + if len(argv) >= 1: fp = argv[0].cast(fp_type) diff --git a/hphp/tools/gdb/unwind.py b/hphp/tools/gdb/unwind.py index 513eab94ec0a8..97b8771f0dd0a 100644 --- a/hphp/tools/gdb/unwind.py +++ b/hphp/tools/gdb/unwind.py @@ -32,9 +32,14 @@ def __init__(self): super(HHVMUnwinder, self).__init__('hhvm_unwinder') def __call__(self, pending_frame): - fp = pending_frame.read_register('rbp') - sp = pending_frame.read_register('rsp') - ip = pending_frame.read_register('rip') + if get_arch(self) == 'aarch64': + fp = pending_frame.read_register('x29') + sp = pending_frame.read_register('x28') + ip = pending_frame.read_register('x30') + else: + fp = pending_frame.read_register('rbp') + sp = pending_frame.read_register('rsp') + ip = pending_frame.read_register('rip') if not frame.is_jitted(fp, ip): return None @@ -53,18 +58,28 @@ def __call__(self, pending_frame): # Restore the saved frame pointer and instruction pointer. fp = fp.cast(T('uintptr_t').pointer()) - unwind_info.add_saved_register('rbp', fp[0]) - unwind_info.add_saved_register('rip', fp[1]) + if get_arch(self) == 'aarch64': + unwind_info.add_saved_register('x29', fp[0]) + unwind_info.add_saved_register('x30', fp[1]) + else: + unwind_info.add_saved_register('rbp', fp[0]) + unwind_info.add_saved_register('rip', fp[1]) if frame.is_jitted(fp[0], fp[1]): # Our parent frame is jitted. Again, we are unable to track %rsp # properly in the TC, so just preserve its value (just as we do in # the TC's custom .eh_frame section). - unwind_info.add_saved_register('rsp', sp) + if get_arch(self) == 'aarch64': + unwind_info.add_saved_register('x28', sp) + else: + unwind_info.add_saved_register('rsp', sp) else: # Our parent frame is not jitted, so we're in enterTCHelper, and we # can restore our parent's %rsp as usual. - unwind_info.add_saved_register('rsp', fp + 16) + if get_arch(self) == 'aarch64': + unwind_info.add_saved_register('x28', fp + 16) + else: + unwind_info.add_saved_register('rsp', fp + 16) return unwind_info