From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from sonic311-31.consmr.mail.ir2.yahoo.com (sonic311-31.consmr.mail.ir2.yahoo.com [77.238.176.163]) by sourceware.org (Postfix) with ESMTPS id BA02C389367E for ; Sat, 6 Mar 2021 17:35:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org BA02C389367E X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1615052123; bh=Q2KAsjGtu8cdVY9W6v2EWbO2OmYXLVYu+Mj9tJ6eysY=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=seE6ldeLZTp45UB1RGYx+m5IUMDYYSe7+N4Ygy/chKhx8CshrdF/BYHwL4fgB4Hb3Fd2SfYY8oDo0rt0xpF/TjQ5A/NaczrqvEdOeEywuwA0SXIYjdy05dZeXGo6mHxRcdICIfJ9WfgAy6J7Bz0ZlTwID3mkQyRE96Z1zPR3oowpeiSZrNuwCybMNseWrEKXaW6cFprFJAFPqS4Qs+9Zf45DVrNz+UniDDG50PHsznTbQJpQuvF0qXWYzXRzKQWUB3mPf3LSwIf5K00e9+pmysSUJUy1Ur/dcFnUihNElkSfgJpjEe4sChoZspjGMLgUocQNVKDWm7n57UJvzVkzHg== X-YMail-OSG: J6u8ehYVM1m.2qbTVZKomYDaLpDQ.sAVzv3A4rR.VczSGx2CuedzQvTf47JUR5t ae2SKhAilsrkRcXXCuCIfHcpfOSfb.e3LuxeqT4qm73cphkf8AW0d3k.5ADNadIVF5IYGScZVumt brQTW_ht.OhVS49vrMtIJ7W7MlE4dks5RdlGhABjFZ1v1jGNYVB0v5mzVLlhaTg3WwM1hca6fKra XfYYXoQTc3YNGz2gnKmTQ7wX8R1wX_jUJiPEp1m28GlIaHyeVgfpB.QcDjevNgI8lwP7bxiMx3m8 X.qG4mkmgmCtQPLBq3suEDR69_ewcgSwHb7dabS_Q95gmoYifryJCq4na9N61icUvVEiVw.ZSOwy RNqZaDErsqhJf3kgT8KHSame29P3fCzM1q5UT23DZqMXYVz4XO1G6CsJN0oExFnbKAt1NKhpJo90 J6rFZg_ogS_IWtpVc_ARgSFCmlGrQ5reJoclEvus_fQ2cjrcZPrBDACz1qOBDhJBfV_2kY_lq5LP 3_lW1lD9T21x6u.5slDOHotY3BkGP0MguWNl62QSRA7Td.blNR20_vI8yBPTN5eJZP6EXeNYEgok .lTwxhL19Li.2L3lVkQJ0EeQmFyC4JDgIEvRyHYnZD8B8jwiUG1.VcqvVY4I2omlVDdLElEgo73f r6.aUx.DuVYtcoVcY.PUJ9hcbioNXLAYIc_q2dfMedPzcQrFuy0aBxvHQC7zjCaskftnsaVHX4Z5 8iNGfnwtZPPAJISK8Ce8v84WUYequ9GQEeB_rxC2lKrOoK4Hc2.4pXsVw4nYDSV0MD3y1hi1hqMa q_ddk0H8sePMXc7U.1vXuC.GC4G.3_f__w8Hsatr_077yt8ozz0g7fkmzgtT1j2BubHmPyN.5h69 3T5xI8IDB1YJGjOSrUj8y4gr2Q8uJuexyLp0Bs5jNwjCiEK7XQm5_bcUgcoeEuP3ngGD9Pw72Moi FQJOgVSwjtXw3pZ17F812H40I9Xnoeqg6EfRR_QLeODK_abZanvyHLerYq6o30NZiLJ1I.u3CVVa fLGZLgVzTDQ8DbY2CmEtkCcIbxUG2GAAESVYXoXwwioOob7rkl2FdQbA9ioIuCynPsHuPUljmzB_ 8DEPkflTWIa_14D1L52NVqEBAu1_nPWeaBfpQAWQWs3DwA_AR.AGzY8lGKyt5GHLRF2mp1_zGTvm WXOJw_gFQfbJ2xhzun0FunmD1J74bU5tVgTHTN41p6Yo13E4jWHWxG2t.S1d6uuhZG.iCrVig0Nf 9Rync8.eA7cjF4o7vFzJhYTVCrZ1ZzwDfX3P_9WRxlg9AN166UhIzRrdSwrUnVufhr0X7JNwW652 e2lyIMb1186.91SztelITWRTfYe5ATU.8qDbimnSiVArw__QWgVDIU1W63pryj0Ejll3xnwflvjH YltbmksycZpJHi6VVM0zsCFKSA_DRNReDRpTwzOZBcEDD88uFvfb4qqt6X2LTk6dAq.rCVLxoOeY Mc5kL.oq7OiC_pTrSW_zZjKmYSkOP8Lk58yLuKCJRgj6q4OohQewQDqAXuZ0ftLp8vbeFQsKQDg. RlFMTzAb0TbZfl.hFxTY.ZT25nD2FEwuv5gKIX1YbsvgCuJxcd4sml.22EsXzk2Qnm39fQ5IHU3D BOQXThfh_qySW6WT0RwPkTfZw.UHybTmccZzmzxk0JAGYZ16NbAvfRCfp066R8KEejNKFDvcaptB oZsW2CglWmeTtxtamQ64LyWjQ0Gz37cNc8DJEl0DNIVV2961iZGK3p1PH7jXfj1JAvXmfkfVjxxW rp.rOfvP.9j9SBNLJdnirp87r5kT3yQTzSdN_tzjQGclGrLXrF6wUctZzRwwa52VZmsTYGxM5FMb ZONR.3mED216CwkPj230ay6xnNZ5OQF_Ke63GDS7anS2n4GNCP5pVzXIaZpvvS3hlsiWYIODBctx R_.U1eWzH6bJmaCuNrMByPt8Upv1qXVdGRe455zDrH6QJnvKa44EDcGjzBw5G3o9KbMqQuj7F3G_ EzzLlM_0VaMaJSUsAZmnQE7UHPrSGtG0OGjn_2tVHw_DQdfLNu2ZzcU39CWLBNBzE3UGP.cnr0Kn tQETzGH.Qwoe4me6JinUXAUTSb83S3Pmkouhqj.Fc8VAdjkRnktaOjUGZJhvoPa7OKPyF1dT7LVJ RtEW.k4TAg1Fh0Gn6WNEsWweO4rlANSX6teFI7ZcbUjPhK88QzPat5YZFGrQPFH.303tGm6oSYTf JgfDn0xnJi1D.hDWgp1iRxGutMv1dERwXv1jc699XWjmWEJv_f1qjluAwlFTJQwhfkXvmoQASG3r mY6F42D0VGrRdS2WMtQfm9tBs76sAWjvdOlPg.ASB5mSZqlfFG0SQIPaJvYX2P6UtymXKE5V5PGG yyEHcTuo.7W.V9KCDWTkut1DSFA2AD.w1q11HEIMhzFqEOoTkHTnbF15pC_yogOZZH9ma9UNFpt5 4Vz0Rl2MGxvNGx1hg0R8- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ir2.yahoo.com with HTTP; Sat, 6 Mar 2021 17:35:23 +0000 Received: by smtp401.mail.ir2.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 6a363949cca5081319e57edf8d5c0acc; Sat, 06 Mar 2021 17:35:22 +0000 (UTC) From: Hannes Domani To: gdb-patches@sourceware.org Subject: [PATCH 05/22] Implement locals TUI window Date: Sat, 6 Mar 2021 18:34:00 +0100 Message-Id: <20210306173417.21528-6-ssbssa@yahoo.de> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210306173417.21528-1-ssbssa@yahoo.de> References: <20210306173417.21528-1-ssbssa@yahoo.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Antivirus: Avast (VPS 210306-0, 03/06/2021), Outbound message X-Antivirus-Status: Clean X-Spam-Status: No, score=-10.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Mar 2021 17:35:27 -0000 PR tui/17849 --- gdb/data-directory/Makefile.in | 1 + gdb/python/lib/gdb/command/tui_windows.py | 562 ++++++++++++++++++++++ 2 files changed, 563 insertions(+) create mode 100644 gdb/python/lib/gdb/command/tui_windows.py diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index 8b65790cdd9..b8383ea7808 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -82,6 +82,7 @@ PYTHON_FILE_LIST = \ gdb/command/frame_filters.py \ gdb/command/pretty_printers.py \ gdb/command/prompt.py \ + gdb/command/tui_windows.py \ gdb/command/type_printers.py \ gdb/command/unwinders.py \ gdb/command/xmethods.py \ diff --git a/gdb/python/lib/gdb/command/tui_windows.py b/gdb/python/lib/gdb/command/tui_windows.py new file mode 100644 index 00000000000..cda43743cf1 --- /dev/null +++ b/gdb/python/lib/gdb/command/tui_windows.py @@ -0,0 +1,562 @@ +# Additional TUI windows. +# Copyright 2021 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import gdb +import sys +import re + +PY3 = sys.version_info[0] == 3 + +custom_windows = {} + + +col_esc_seq_re = re.compile('(\033\[[0-9;]*m)') +def escaped_substr(s, n, c): + col_esc_seq = False + init_col_esc_seq = None + last_col_esc_seq = None + sub = "" + for p in col_esc_seq_re.split(s): + t = "" + if n > 0: + if col_esc_seq: + init_col_esc_seq = p + else: + l = len(p) + if l <= n: + n -= l + else: + if init_col_esc_seq: + sub += init_col_esc_seq + t = p[n:] + n = 0 + else: + t = p + if c > 0: + if col_esc_seq: + sub += t + else: + l = len(t) + if l <= c: + sub += t + c -= l + else: + sub += t[:c] + c = 0 + elif col_esc_seq: + last_col_esc_seq = p + col_esc_seq = not col_esc_seq + if c > 0: + sub += ' ' * c + if last_col_esc_seq: + sub += last_col_esc_seq + return sub + +class TextWindow(object): + def __init__(self, win, title): + self.win = win + self.line_ofs = 0 + self.col_ofs = 0 + self.lines = [] + win.title = title + global custom_windows + custom_windows[title] = self + + def close(self): + global custom_windows + del custom_windows[self.win.title] + + def render(self): + self.line_ofs = 0 + self.col_ofs = 0 + + def hscroll(self, num): + prev_col_ofs = self.col_ofs + self.col_ofs = self.col_ofs + num + if self.col_ofs < 0: + self.col_ofs = 0 + if self.col_ofs != prev_col_ofs: + self.redraw() + + def vscroll(self, num): + prev_line_ofs = self.line_ofs + self.line_ofs = self.line_ofs + num + l = len(self.lines) + if self.line_ofs >= l: + self.line_ofs = l - 1 + if self.line_ofs < 0: + self.line_ofs = 0 + if self.line_ofs != prev_line_ofs: + self.redraw() + + def redraw(self): + l = len(self.lines) + if self.line_ofs > 0 and self.line_ofs + self.win.height > l: + self.line_ofs = l - self.win.height + if self.line_ofs < 0: + self.line_ofs = 0 + start = self.line_ofs + stop = self.line_ofs + self.win.height + if stop > l: + stop = l + self.win.erase() + if stop > start: + self.win.write("".join([escaped_substr(l, self.col_ofs, self.win.width) for l in self.lines[start:stop]])) + + +def is_string_instance(s): + if PY3: + return isinstance(s, str) + else: + return isinstance(s, basestring) + +def val_cmp_color(prev, cur): + if prev is None: + return ("\033[1;32m", "\033[0m", "", "") + elif prev != cur: + return ("", "", "\033[1;31m", "\033[0m") + return ("", "", "", "") + +def octal_escape(s): + return "".join(c if ord(c) < 128 else "\\%03o" % ord(c) for c in s) + +def value_string(valstr, hint): + if hint == "string": + is_lazy = type(valstr).__name__ == "LazyString" + if is_lazy: + l = valstr.length + elif not is_string_instance(valstr): + l = 1 + else: + l = len(valstr) + if l == 0: + if is_lazy and str(valstr.type) == "wchar_t *": + valstr = "L\"\"" + else: + valstr = "\"\"" + else: + valstr = gdb.Value(valstr).format_string(symbols=False, address=False) + if isinstance(valstr, gdb.Value): + valstr = valstr.format_string(symbols=False, address=False) + elif not type(valstr) is str: + valstr = str(valstr) + return valstr + +def is_typedef_of(valtype, name): + if valtype.name == name: + return True + while valtype.code == gdb.TYPE_CODE_TYPEDEF: + valtype = valtype.target() + if valtype.name == name: + return True + return False + + +class VariableWindow(TextWindow): + def __init__(self, win, title, convenience_name): + super(VariableWindow, self).__init__(win, title) + self.prev_vals = {} + self.line_names = [] + self.convenience_name = convenience_name + + def click(self, x, y, button): + line = y + self.line_ofs + if button == 1 and line < len(self.line_names): + name = self.line_names[line] + if name: + prev = self.prev_vals[name] + if prev is not None and prev[0] is not None: + prev[0] = not prev[0] + self.refill(True) + elif button == 3 and line < len(self.line_names): + name = self.line_names[line] + if name: + prev = self.prev_vals[name] + if prev is not None and prev[3] is not None: + gdb.set_convenience_variable(self.convenience_name, prev[3]) + self.refill(True) + + def refill(self, keep_prev=False): + if not self.win.is_valid(): + return + self.lines = [] + self.line_names = [] + cur_vals = {} + for v in self.variables(): + name = v.symbol() + value = v.value() + sym_not_init = False + num = 0 + fmt = None + error = None + if hasattr(v, "undeclared"): + sym_not_init = v.undeclared() + if hasattr(v, "number"): + num = v.number() + if hasattr(v, "format"): + fmt = v.format() + if hasattr(v, "error"): + error = v.error() + self.add_val(name, name, value, 0, num, cur_vals, keep_prev, False, sym_not_init, fmt, True, error) + self.prev_vals = cur_vals + self.redraw() + + def add_val(self, n, fn, v, inset, num, cur_vals, keep_prev, def_expand, sym_not_init, fmt, dyn_type, error): + n2 = fn + if inset == 0: + if num == 0: + count = 1 + while n2 in cur_vals: + count += 1 + n2 = "%s:%d" % (n, count) + else: + n2 = "%d:%s" % (num, n) + + cur_entry = [None, False, None, None] + cur_vals[n2] = cur_entry + expand = None + prev_val = None + if n2 in self.prev_vals: + pv = self.prev_vals[n2] + expand = pv[0] + if keep_prev: + prev_val = pv[2] + else: + prev_val = pv[1] + cur_entry[0] = expand + cur_entry[2] = prev_val + + spaces = " " * inset + if num > 0: + numstr = "%d: " % num + else: + numstr = "" + + if v is None: + if error is None: + var_col_s, var_col_e = "\033[1;30m", "\033[0m" + if sym_not_init: + var_col_s, var_col_e = "\033[33m", "\033[0m" + self.lines.append(spaces + numstr + " " + var_col_s + n + var_col_e) + else: + var_col_s, var_col_e = "", "" + if sym_not_init: + var_col_s, var_col_e = "\033[33m", "\033[0m" + self.lines.append(spaces + numstr + " " + var_col_s + n + var_col_e + " = \033[1;30m<" + error + ">\033[0m") + self.line_names.append(n2) + return + + if is_string_instance(v): + (var_col_s, var_col_e, val_col_s, val_col_e) = val_cmp_color(prev_val, v) + if sym_not_init: + var_col_s, var_col_e = "\033[33m", "\033[0m" + self.lines.append(spaces + numstr + " " + var_col_s + n + var_col_e + " = " + val_col_s + v + val_col_e) + self.line_names.append(n2) + cur_entry[1] = v + return + + if isinstance(v, gdb.Value): + if v.type.code in [gdb.TYPE_CODE_REF, gdb.TYPE_CODE_RVALUE_REF]: + v = v.referenced_value() + + is_optimized_out = False + try: + is_optimized_out = v.is_optimized_out + except: + self.add_val(n, fn, None, inset, num, cur_vals, keep_prev, False, sym_not_init, fmt, False, str(sys.exc_info()[1])) + return + + if is_optimized_out and v.type.strip_typedefs().code not in [gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION]: + self.add_val(n, fn, None, inset, num, cur_vals, keep_prev, False, sym_not_init, fmt, False, "optimized out") + return + + v_addr = v.address + else: + v = gdb.Value(v) + + cv_str = "" + if v_addr is not None: + v_addr = v_addr.dereference().reference_value() + cur_entry[3] = v_addr + cv = gdb.convenience_variable(self.convenience_name) + if cv is not None and cv.address == v_addr.address and cv.type == v_addr.type: + cv_str = " = \033[1;36m$" + self.convenience_name + "\033[0m" + + try: + pp = gdb.default_visualizer(v) + except: + pp = None + if pp: + valstr = None + try: + if expand is None and hasattr(pp, "children"): + expand = def_expand + cur_entry[0] = expand + expand_str = " " + if expand is not None: + if expand: + expand_str = "- " + else: + expand_str = "+ " + numstr += expand_str + + if hasattr(pp, "to_string"): + valstr = pp.to_string() + hint = None + if hasattr(pp, "display_hint"): + hint = pp.display_hint() + if valstr is not None: + valstr = value_string(valstr, hint) + valstr = octal_escape(valstr) + sp = valstr.split("\n") + (var_col_s, var_col_e, val_col_s, val_col_e) = val_cmp_color(prev_val, valstr) + if sym_not_init: + var_col_s, var_col_e = "\033[33m", "\033[0m" + self.lines.append(spaces + numstr + var_col_s + n + var_col_e + " = " + val_col_s + sp.pop(0) + val_col_e + cv_str) + self.line_names.append(n2) + for extra in sp: + self.lines.append(spaces + " " + extra) + self.line_names.append(None) + cur_entry[1] = valstr + else: + (var_col_s, var_col_e, val_col_s, val_col_e) = val_cmp_color(prev_val, False) + if sym_not_init: + var_col_s, var_col_e = "\033[33m", "\033[0m" + self.lines.append(spaces + numstr + var_col_s + n + var_col_e + cv_str) + self.line_names.append(n2) + + if expand: + childs = None + if hasattr(pp, "children"): + childs = pp.children() + if childs: + if hint == "map": + count = 0 + key_prev = None + for c in childs: + (nc, vc) = c + count += 1 + fnc = ":".join([n2, nc]) + if (count % 2) == 1: + key_prev = None + if is_string_instance(vc): + key_prev = vc + else: + vc_check = vc + if vc_check.type.code in [gdb.TYPE_CODE_REF, gdb.TYPE_CODE_RVALUE_REF]: + vc_check = vc_check.referenced_value() + key_pp = gdb.default_visualizer(vc_check) + if key_pp: + if hasattr(key_pp, "to_string") and not hasattr(key_pp, "children"): + vc_check = key_pp.to_string() + if vc_check is not None: + hint = None + if hasattr(key_pp, "display_hint"): + hint = key_pp.display_hint() + key_prev = value_string(vc_check, hint) + else: + t_check = vc_check.type.strip_typedefs() + if t_check.code in [gdb.TYPE_CODE_ENUM, gdb.TYPE_CODE_INT, gdb.TYPE_CODE_FLT, + gdb.TYPE_CODE_BOOL, gdb.TYPE_CODE_COMPLEX, gdb.TYPE_CODE_DECFLOAT]: + if fmt: + key_prev = vc_check.format_string(symbols=False, raw=True, format=fmt) + else: + key_prev = vc_check.format_string(symbols=False, raw=True) + if key_prev is not None and "\n" in key_prev: + key_prev = None + if key_prev is None: + self.add_val("key", fnc, vc, inset + 1, 0, cur_vals, keep_prev, False, False, fmt, True, None) + else: + if key_prev is not None: + self.add_val("[" + str(key_prev) + "]", fnc, vc, inset + 1, 0, cur_vals, keep_prev, False, False, fmt, True, None) + else: + self.add_val("value", fnc, vc, inset + 1, 0, cur_vals, keep_prev, False, False, fmt, True, None) + else: + for c in childs: + (nc, vc) = c + fnc = ":".join([n2, nc]) + self.add_val(nc, fnc, vc, inset + 1, 0, cur_vals, keep_prev, False, False, fmt, True, None) + except: + self.add_val(n, fn, None, inset, num, cur_vals, keep_prev, False, sym_not_init, fmt, False, str(sys.exc_info()[1])) + return + + t = v.type.strip_typedefs() + + is_string = False + if t.code in [gdb.TYPE_CODE_ARRAY, gdb.TYPE_CODE_PTR]: + target_type = t.target().strip_typedefs() + if target_type.code == gdb.TYPE_CODE_INT and (target_type.name == "char" or is_typedef_of(t.target(), "wchar_t")): + is_string = True + is_array = t.code in [gdb.TYPE_CODE_ARRAY, gdb.TYPE_CODE_RANGE] + is_ptr = t.code == gdb.TYPE_CODE_PTR and not target_type.code in [gdb.TYPE_CODE_FUNC, gdb.TYPE_CODE_METHOD] + name_add = "" + if dyn_type and v.type.code == gdb.TYPE_CODE_STRUCT: + try: + if v.type != v.dynamic_type: + v = v.cast(v.dynamic_type) + name_add = " <" + v.type.name + ">" + except: + pass + expand_str = " " + if is_ptr or is_array or t.code in [gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION]: + if expand is None: + expand = def_expand + cur_entry[0] = expand + if expand is not None: + if expand: + expand_str = "- " + else: + expand_str = "+ " + numstr += expand_str + + if is_string or t.code in [gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_ENUM, gdb.TYPE_CODE_FUNC, gdb.TYPE_CODE_INT, + gdb.TYPE_CODE_FLT, gdb.TYPE_CODE_STRING, gdb.TYPE_CODE_METHOD, gdb.TYPE_CODE_METHODPTR, + gdb.TYPE_CODE_MEMBERPTR, gdb.TYPE_CODE_CHAR, gdb.TYPE_CODE_BOOL, gdb.TYPE_CODE_COMPLEX, gdb.TYPE_CODE_DECFLOAT]: + try: + if fmt and not is_string: + valstr = v.format_string(symbols=False, raw=True, address=True, format=fmt) + else: + valstr = v.format_string(symbols=False, raw=True, address=True) + valstr = octal_escape(valstr) + (var_col_s, var_col_e, val_col_s, val_col_e) = val_cmp_color(prev_val, valstr) + if sym_not_init: + var_col_s, var_col_e = "\033[33m", "\033[0m" + self.lines.append(spaces + numstr + var_col_s + n + var_col_e + " = " + val_col_s + valstr + val_col_e + cv_str) + self.line_names.append(n2) + cur_entry[1] = valstr + except: + self.add_val(n, fn, None, inset, num, cur_vals, keep_prev, False, sym_not_init, fmt, False, str(sys.exc_info()[1])) + return + else: + (var_col_s, var_col_e, val_col_s, val_col_e) = val_cmp_color(prev_val, False) + if sym_not_init: + var_col_s, var_col_e = "\033[33m", "\033[0m" + self.lines.append(spaces + numstr + var_col_s + n + var_col_e + name_add + cv_str) + self.line_names.append(n2) + if t.code == gdb.TYPE_CODE_ENUM: + return + + if not expand: + return + + if is_array: + (low, high) = t.range() + for i in range(low, high + 1): + nc = "[%d]" % i + fnc = ":".join([n2, nc]) + self.add_val(nc, fnc, v[i], inset + 1, 0, cur_vals, keep_prev, False, False, fmt, True, None) + return + + if is_ptr: + nc = "[0]" + fnc = ":".join([n2, nc]) + try: + v = v.dereference() + except: + v = None + self.add_val(nc, fnc, v, inset + 1, 0, cur_vals, keep_prev, target_type.code != gdb.TYPE_CODE_PTR, False, fmt, True, None) + return + + fields = None + if t.code in [gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION]: + try: + fields = v.type.fields() + except: + pass + if fields: + num = 1 + for f in fields: + if not hasattr(f, "bitpos"): + continue + try: + n = f.name + except: + n = None + if not n: + n = "" + elif f.is_base_class: + n = "<" + n + ">" + vf = v[f] + fnc = ":".join([n2, n, "%d" % num]) + num += 1 + self.add_val(n, fnc, vf, inset + 1, 0, cur_vals, keep_prev, False, False, fmt, False, None) + +class VarNameValue(object): + def __init__(self, sym, val, undecl, num, fmt, err): + self.sym = sym + self.val = val + self.undecl = undecl + self.num = num + self.fmt = fmt + self.err = err + + def symbol(self): + return self.sym + + def value(self): + return self.val + + def undeclared(self): + return self.undecl + + def number(self): + return self.num + + def format(self): + return self.fmt + + def error(self): + return self.err + +class LocalsWindow(VariableWindow): + def __init__(self, win): + super(LocalsWindow, self).__init__(win, "locals", "lv") + + def variables(self): + thread = gdb.selected_thread() + thread_valid = thread and thread.is_valid() + if thread_valid: + frame = gdb.selected_frame() + cur_line = frame.find_sal().line + try: + block = frame.block() + except: + block = None + while block: + if not block.is_global: + for symbol in block: + if symbol.is_argument or symbol.is_variable: + sym_not_init = symbol.is_variable and symbol.line > 0 and cur_line <= symbol.line + yield VarNameValue(symbol.name, symbol.value(frame), sym_not_init, 0, None, None) + if block.function: + break + block = block.superblock + + +gdb.register_window_type("locals", LocalsWindow) + + +def var_change_handler(event=None): + global custom_windows + for key, value in custom_windows.items(): + value.refill() + +gdb.events.before_prompt.connect(var_change_handler) + + +gdb.execute("tui new-layout locals {-horizontal src 2 locals 1} 2 status 0 cmd 1") + +gdb.execute("alias ll = layout locals") -- 2.30.1