1# Copyright (C) 2021-2023 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16# This dummy unwinder will break GDB's backtrce at the function called 17# 'break_bt_here'. 18 19import gdb 20from gdb.unwinder import Unwinder 21 22 23class FrameId(object): 24 def __init__(self, sp, pc): 25 self._sp = sp 26 self._pc = pc 27 28 @property 29 def sp(self): 30 return self._sp 31 32 @property 33 def pc(self): 34 return self._pc 35 36 37class TestUnwinder(Unwinder): 38 def __init__(self): 39 Unwinder.__init__(self, "break unwinding") 40 41 def __call__(self, pending_frame): 42 pc_desc = pending_frame.architecture().registers().find("pc") 43 pc = pending_frame.read_register(pc_desc) 44 45 sp_desc = pending_frame.architecture().registers().find("sp") 46 sp = pending_frame.read_register(sp_desc) 47 48 block = gdb.block_for_pc(int(pc)) 49 if block is None: 50 return None 51 func = block.function 52 if func is None: 53 return None 54 if str(func) != "break_bt_here": 55 return None 56 fid = FrameId(pc, sp) 57 return pending_frame.create_unwind_info(fid) 58 59 60gdb.unwinder.register_unwinder(None, TestUnwinder(), True) 61