diff options
Diffstat (limited to 'gdb')
25 files changed, 486 insertions, 118 deletions
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 2f034af..08526d8 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -960,6 +960,11 @@ arm_linux_software_single_step (struct regcache *regcache) struct gdbarch *gdbarch = regcache->arch (); struct arm_get_next_pcs next_pcs_ctx; + /* If the target does have hardware single step, GDB doesn't have + to bother software single step. */ + if (target_can_do_single_step () == 1) + return {}; + arm_get_next_pcs_ctor (&next_pcs_ctx, &arm_linux_get_next_pcs_ops, gdbarch_byte_order (gdbarch), diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index f795d7b..d704ad1 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -13998,26 +13998,11 @@ insert_single_step_breakpoint (struct gdbarch *gdbarch, update_global_location_list (UGLL_INSERT); } -/* Try to setup for software single stepping. Return true if - target_resume() should use hardware single step. +/* Insert single step breakpoints according to the current state. */ - GDBARCH is the current gdbarch. */ - -bool -maybe_software_singlestep (struct gdbarch *gdbarch) +int +insert_single_step_breakpoints (struct gdbarch *gdbarch) { - if (execution_direction != EXEC_FORWARD) - return true; - - if (target_can_do_single_step () == 1) - { - /* The target definitely has hardware single step. */ - return true; - } - - if (!gdbarch_software_single_step_p (gdbarch)) - return true; - regcache *regcache = get_thread_regcache (inferior_thread ()); std::vector<CORE_ADDR> next_pcs; @@ -14031,10 +14016,10 @@ maybe_software_singlestep (struct gdbarch *gdbarch) for (CORE_ADDR pc : next_pcs) insert_single_step_breakpoint (gdbarch, aspace, pc); - return false; + return 1; } else - return true; + return 0; } /* See breakpoint.h. */ diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index e9201bc..9341112 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -1884,10 +1884,10 @@ extern void insert_single_step_breakpoint (struct gdbarch *, const address_space *, CORE_ADDR); -/* Try to setup for software single stepping. Return true if - target_resume() should use hardware single step. GDBARCH is the - current gdbarch. */ -extern bool maybe_software_singlestep (struct gdbarch *); +/* Insert all software single step breakpoints for the current frame. + Return true if any software single step breakpoints are inserted, + otherwise, return false. */ +extern int insert_single_step_breakpoints (struct gdbarch *); /* Check whether any hardware watchpoints have triggered or not, according to the target, and record it in each watchpoint's diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h index 1e51081..281b97b 100644 --- a/gdb/gdbarch-gen.h +++ b/gdb/gdbarch-gen.h @@ -776,10 +776,16 @@ extern void set_gdbarch_get_memtag (struct gdbarch *gdbarch, gdbarch_get_memtag_ extern CORE_ADDR gdbarch_memtag_granule_size (struct gdbarch *gdbarch); extern void set_gdbarch_memtag_granule_size (struct gdbarch *gdbarch, CORE_ADDR memtag_granule_size); -/* Return a vector of addresses at which the software single step - breakpoints should be inserted. An empty vector means software single - step is not used. +/* FIXME/cagney/2001-01-18: This should be split in two. A target method that + indicates if the target needs software single step. An ISA method to + implement it. + FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the + target can single step. If not, then implement single step using breakpoints. + + Return a vector of addresses on which the software single step + breakpoints should be inserted. NULL means software single step is + not used. Multiple breakpoints may be inserted for some instructions such as conditional branch. However, each implementation must always evaluate the condition and only put the breakpoint at the branch destination if diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py index 55df102..91c867e 100644 --- a/gdb/gdbarch_components.py +++ b/gdb/gdbarch_components.py @@ -1378,10 +1378,16 @@ For a non-zero value, this represents the number of bytes of memory per tag. Function( comment=""" -Return a vector of addresses at which the software single step -breakpoints should be inserted. An empty vector means software single -step is not used. +FIXME/cagney/2001-01-18: This should be split in two. A target method that +indicates if the target needs software single step. An ISA method to +implement it. +FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the +target can single step. If not, then implement single step using breakpoints. + +Return a vector of addresses on which the software single step +breakpoints should be inserted. NULL means software single step is +not used. Multiple breakpoints may be inserted for some instructions such as conditional branch. However, each implementation must always evaluate the condition and only put the breakpoint at the branch destination if diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index f97c98e..21a5a28 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -8977,41 +8977,12 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS; tdep->register_names = i386_register_names; - /* No upper YMM registers. */ - tdep->ymmh_register_names = NULL; - tdep->ymm0h_regnum = -1; - - /* No upper ZMM registers. */ - tdep->zmmh_register_names = NULL; - tdep->zmm0h_regnum = -1; - - /* No high XMM registers. */ - tdep->xmm_avx512_register_names = NULL; - tdep->xmm16_regnum = -1; - - /* No upper YMM16-31 registers. */ - tdep->ymm16h_register_names = NULL; - tdep->ymm16h_regnum = -1; - tdep->num_byte_regs = 8; tdep->num_word_regs = 8; tdep->num_dword_regs = 0; tdep->num_mmx_regs = 8; tdep->num_ymm_regs = 0; - /* No AVX512 registers. */ - tdep->k0_regnum = -1; - tdep->num_zmm_regs = 0; - tdep->num_ymm_avx512_regs = 0; - tdep->num_xmm_avx512_regs = 0; - - /* No PKEYS registers */ - tdep->pkru_regnum = -1; - tdep->num_pkeys_regs = 0; - - /* No segment base registers. */ - tdep->fsbase_regnum = -1; - tdesc_arch_data_up tdesc_data = tdesc_data_alloc (); set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index e849b33..e4895b1 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -69,56 +69,57 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base size_t sizeof_fpregset = 0; /* Register number for %st(0). The register numbers for the other - registers follow from this one. Set this to -1 to indicate the - absence of an FPU. */ - int st0_regnum = 0; + registers follow from this one. Set this to a value >= 0 if FPU is + present. */ + int st0_regnum = -1; /* Number of MMX registers. */ int num_mmx_regs = 0; - /* Register number for %mm0. Set this to -1 to indicate the absence - of MMX support. */ - int mm0_regnum = 0; + /* Register number for %mm0. Set this to a value >= 0 if MMX is + supported. */ + int mm0_regnum = -1; /* Number of pseudo YMM registers. */ int num_ymm_regs = 0; - /* Register number for %ymm0. Set this to -1 to indicate the absence - of pseudo YMM register support. */ - int ymm0_regnum = 0; + /* Register number for %ymm0. Set this to a value >= 0 if pseudo YMM + registers are supported. */ + int ymm0_regnum = -1; /* Number of AVX512 OpMask registers (K-registers) */ int num_k_regs = 0; - /* Register number for %k0. Set this to -1 to indicate the absence - of AVX512 OpMask register support. */ - int k0_regnum = 0; + /* Register number for %k0. Set this to a value >= 0 if AVX512 OpMask + is supported. */ + int k0_regnum = -1; /* Number of pseudo ZMM registers ($zmm0-$zmm31). */ int num_zmm_regs = 0; - /* Register number for %zmm0. Set this to -1 to indicate the absence - of pseudo ZMM register support. */ - int zmm0_regnum = 0; + /* Register number for %zmm0. Set this to a value >= 0 if pseudo ZMM + registers are supported. */ + int zmm0_regnum = -1; /* Number of byte registers. */ int num_byte_regs = 0; - /* Register pseudo number for %al. */ - int al_regnum = 0; + /* Register pseudo number for %al. If supported, set this to a + value >= 0. */ + int al_regnum = -1; /* Number of pseudo word registers. */ int num_word_regs = 0; - /* Register number for %ax. */ - int ax_regnum = 0; + /* Register number for %ax. If supported, set this to a value >= 0. */ + int ax_regnum = -1; /* Number of pseudo dword registers. */ int num_dword_regs = 0; - /* Register number for %eax. Set this to -1 to indicate the absence - of pseudo dword register support. */ - int eax_regnum = 0; + /* Register number for %eax. Set this to a value >= 0 if pseudo dword + registers are supported. */ + int eax_regnum = -1; /* Number of core registers. */ int num_core_regs = 0; @@ -129,14 +130,16 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base /* Number of SSE registers added in AVX512. */ int num_xmm_avx512_regs = 0; - /* Register number of XMM16, the first XMM register added in AVX512. */ - int xmm16_regnum = 0; + /* Register number of XMM16, the first XMM register added in AVX512. + Set this to a value >= 0 if XMM registers are supported. */ + int xmm16_regnum = -1; /* Number of YMM registers added in AVX512. */ int num_ymm_avx512_regs = 0; - /* Register number of YMM16, the first YMM register added in AVX512. */ - int ymm16_regnum = 0; + /* Register number of YMM16, the first YMM register added in AVX512. + Set this to a value >= 0 if YMM registers are supported. */ + int ymm16_regnum = -1; /* Bits of the extended control register 0 (the XFEATURE_ENABLED_MASK register), excluding the x87 bit, which are supported by this GDB. */ @@ -152,23 +155,23 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base /* Register names. */ const char * const *register_names = nullptr; - /* Register number for %ymm0h. Set this to -1 to indicate the absence - of upper YMM register support. */ - int ymm0h_regnum = 0; + /* Register number for %ymm0h. Set this to a value >= 0 if they are + supported. */ + int ymm0h_regnum = -1; /* Upper YMM register names. Only used for tdesc_numbered_register. */ const char * const *ymmh_register_names = nullptr; - /* Register number for %ymm16h. Set this to -1 to indicate the absence - of support for YMM16-31. */ - int ymm16h_regnum = 0; + /* Register number for %ymm16h. Set this to a value >= 0 if they are + supported. */ + int ymm16h_regnum = -1; /* YMM16-31 register names. Only used for tdesc_numbered_register. */ const char * const *ymm16h_register_names = nullptr; - /* Register number for %zmm0h. Set this to -1 to indicate the absence - of ZMM_HI256 register support. */ - int zmm0h_regnum = 0; + /* Register number for %zmm0h. Set this to a value >= 0 if ZMM_HI256 + registers are supported. */ + int zmm0h_regnum = -1; /* OpMask register names. */ const char * const *k_register_names = nullptr; @@ -185,15 +188,16 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base /* Number of PKEYS registers. */ int num_pkeys_regs = 0; - /* Register number for PKRU register. */ - int pkru_regnum = 0; + /* Register number for PKRU register. If supported, set this to a value + >= 0. */ + int pkru_regnum = -1; /* PKEYS register names. */ const char * const *pkeys_register_names = nullptr; - /* Register number for %fsbase. Set this to -1 to indicate the - absence of segment base registers. */ - int fsbase_regnum = 0; + /* Register number for %fsbase. If supported, set this to a value + >= 0. */ + int fsbase_regnum = -1; /* Target description. */ const struct target_desc *tdesc = nullptr; diff --git a/gdb/infrun.c b/gdb/infrun.c index e0e9ffa..9d3e1b7 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -93,6 +93,8 @@ static void insert_step_resume_breakpoint_at_caller (const frame_info_ptr &); static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR); +static bool maybe_software_singlestep (struct gdbarch *gdbarch); + static void resume (gdb_signal sig); static void wait_for_inferior (inferior *inf); @@ -2357,6 +2359,23 @@ set_schedlock_func (const char *args, int from_tty, struct cmd_list_element *c) process. */ bool sched_multi = false; +/* Try to setup for software single stepping. Return true if target_resume() + should use hardware single step. + + GDBARCH the current gdbarch. */ + +static bool +maybe_software_singlestep (struct gdbarch *gdbarch) +{ + bool hw_step = true; + + if (execution_direction == EXEC_FORWARD + && gdbarch_software_single_step_p (gdbarch)) + hw_step = !insert_single_step_breakpoints (gdbarch); + + return hw_step; +} + /* See infrun.h. */ ptid_t diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c index cae5aa6..f872f73 100644 --- a/gdb/ppc-sysv-tdep.c +++ b/gdb/ppc-sysv-tdep.c @@ -2060,10 +2060,12 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function, } /* Small character arrays are returned, right justified, in r3. */ - if (valtype->code () == TYPE_CODE_ARRAY + if (tdep->elf_abi == POWERPC_ELF_V1 + && valtype->code () == TYPE_CODE_ARRAY && !valtype->is_vector () && valtype->length () <= 8 - && valtype->target_type ()->code () == TYPE_CODE_INT + && (valtype->target_type ()->code () == TYPE_CODE_INT + || valtype->target_type ()->code () == TYPE_CODE_CHAR) && valtype->target_type ()->length () == 1) { int regnum = tdep->ppc_gp0_regnum + 3; diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 19fbc20..d1cf72d 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1290,7 +1290,9 @@ should_validate_memtags (gdbarch *gdbarch, struct value *value) return false; /* We do. Check whether it includes any tags. */ - return target_is_address_tagged (gdbarch, value_as_address (value)); + struct type *val_type = value->type (); + const gdb_byte *data = value->contents ().data (); + return target_is_address_tagged (gdbarch, unpack_pointer (val_type, data)); } /* Helper for parsing arguments for print_command_1. */ diff --git a/gdb/record-full.c b/gdb/record-full.c index 7d4ef87..7e3da27 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -1105,7 +1105,7 @@ record_full_target::resume (ptid_t ptid, int step, enum gdb_signal signal) record_full_resume_step = 1; } else - step = maybe_software_singlestep (gdbarch); + step = !insert_single_step_breakpoints (gdbarch); } } @@ -1277,7 +1277,7 @@ record_full_wait_1 (struct target_ops *ops, }; reinit_frame_cache (); - step = maybe_software_singlestep (gdbarch); + step = !insert_single_step_breakpoints (gdbarch); } if (record_debug) diff --git a/gdb/testsuite/gdb.ada/return-small-char-array.exp b/gdb/testsuite/gdb.ada/return-small-char-array.exp new file mode 100644 index 0000000..75c781e --- /dev/null +++ b/gdb/testsuite/gdb.ada/return-small-char-array.exp @@ -0,0 +1,40 @@ +# Copyright 2025 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 <http://www.gnu.org/licenses/>. + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile proc + +if { [gdb_compile_ada $srcfile $binfile executable debug] != "" } { + return -1 +} + +clean_restart $testfile + +set bp_location [gdb_get_line_number "STOP" $testdir/proc.adb] +runto "proc.adb:$bp_location" + +gdb_test "print Value.Name(My_Value)" \ + { = "abcd"} + +# Step into the function. +gdb_test "step 2" \ + "return Of_Value;" + +# and finish. +gdb_test "finish" \ + { = "abcd"} diff --git a/gdb/testsuite/gdb.ada/return-small-char-array/proc.adb b/gdb/testsuite/gdb.ada/return-small-char-array/proc.adb new file mode 100644 index 0000000..b18d9fe --- /dev/null +++ b/gdb/testsuite/gdb.ada/return-small-char-array/proc.adb @@ -0,0 +1,22 @@ +-- Copyright 2025 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 <http://www.gnu.org/licenses/>. + +with Value; +procedure Proc is + My_Value : Value.T := "abcd"; +begin + null; -- STOP + My_Value := Value.Name(My_Value); +end; diff --git a/gdb/testsuite/gdb.ada/return-small-char-array/value.adb b/gdb/testsuite/gdb.ada/return-small-char-array/value.adb new file mode 100644 index 0000000..2dd9faa --- /dev/null +++ b/gdb/testsuite/gdb.ada/return-small-char-array/value.adb @@ -0,0 +1,21 @@ +-- Copyright 2025 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 <http://www.gnu.org/licenses/>. + +package body Value is + function Name (Of_Value : T) return T is + begin + return Of_Value; + end Name; +end Value; diff --git a/gdb/testsuite/gdb.ada/return-small-char-array/value.ads b/gdb/testsuite/gdb.ada/return-small-char-array/value.ads new file mode 100644 index 0000000..16b171e --- /dev/null +++ b/gdb/testsuite/gdb.ada/return-small-char-array/value.ads @@ -0,0 +1,20 @@ +-- Copyright 2025 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 <http://www.gnu.org/licenses/>. + +package Value is + type T is new String (1 .. 4); + + function Name (Of_Value : T) return T; +end; diff --git a/gdb/testsuite/gdb.base/color-prompt.exp b/gdb/testsuite/gdb.base/color-prompt.exp new file mode 100644 index 0000000..c037185 --- /dev/null +++ b/gdb/testsuite/gdb.base/color-prompt.exp @@ -0,0 +1,29 @@ +# Copyright 2025 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 <http://www.gnu.org/licenses/>. + +# Check using a prompt with color in CLI. + +# Using tuiterm requires setting TERM on host. +require {!is_remote host} + +# We use a tuiterm, which allows us to determine cursor position. +tuiterm_env +Term::clean_restart 8 80 + +# We start with an empty screen, to generate a visible prompt. +Term::gen_prompt + +set tui 0 +source $srcdir/$subdir/../gdb.tui/color-prompt.exp.tcl diff --git a/gdb/testsuite/gdb.base/exprs.exp b/gdb/testsuite/gdb.base/exprs.exp index f703c18..81f6f19 100644 --- a/gdb/testsuite/gdb.base/exprs.exp +++ b/gdb/testsuite/gdb.base/exprs.exp @@ -285,11 +285,14 @@ gdb_test "print v_short + " \ gdb_test "print v_short =}{= 3" \ "A syntax error in expression, near `\\}\\{= 3'\\." +set hs {[^\r\n]} +set re_debug [string cat $hs* {[Ss]hift} $hs*] + gdb_test_no_output "set debug parse 1" set saw_start 0 set saw_val 0 gdb_test_multiple "print 23" "print with debugging" -lbl { - -re "\r\nStarting parse(?=\r\n)" { + -re "\r\n${re_debug}(?=\r\n)" { set saw_start 1 exp_continue } diff --git a/gdb/testsuite/gdb.cp/method-ref-return.cc b/gdb/testsuite/gdb.cp/method-ref-return.cc new file mode 100644 index 0000000..4169bfe --- /dev/null +++ b/gdb/testsuite/gdb.cp/method-ref-return.cc @@ -0,0 +1,42 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2025 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 <http://www.gnu.org/licenses/>. */ + +/* Test that we can access class method/data member via reference. */ + +struct foo +{ + foo () : m_a (42) {} + int get_a () const { return m_a; } + int m_a; +}; + +struct bar +{ + bar () : m_foo () {} + const foo &get_foo () const { return m_foo; } + foo m_foo; +}; + +int +main (int argc, char *argv[]) +{ + bar b; + const foo &ref = b.get_foo (); + int ret = ref.m_a; // breakpoint here + ret += ref.get_a (); + return ret; +}
\ No newline at end of file diff --git a/gdb/testsuite/gdb.cp/method-ref-return.exp b/gdb/testsuite/gdb.cp/method-ref-return.exp new file mode 100644 index 0000000..1ac5ac9 --- /dev/null +++ b/gdb/testsuite/gdb.cp/method-ref-return.exp @@ -0,0 +1,70 @@ +# Copyright 2025 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 <http://www.gnu.org/licenses/>. + +# Test calling methods and accessing members via reference. + +require allow_cplus_tests + +standard_testfile .cc + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +# Set a breakpoint after the bar object is created and the reference is obtained. +gdb_breakpoint [gdb_get_line_number "breakpoint here"] +gdb_continue_to_breakpoint "after reference assignment" + +# Test that we can call the method through reference and get the expected result. +gdb_test_multiple "print b.get_foo()" "print method call returning reference" { + -re "\\$\[0-9\]+ = \\(const foo &\\) @$hex: \\{m_a = 42\\}\r\n$gdb_prompt $" { + pass $gdb_test_name + } + -re "Could not validate memory tag: Value can't be converted to integer\\." { + fail "$gdb_test_name" + } +} + +# Test accessing the member through the reference. +gdb_test "print b.get_foo ().m_a" \ + "\\$\[0-9\]+ = 42" \ + "print member access through reference" + +# Test calling method on the referenced object. +gdb_test "print b.get_foo ().get_a()" \ + "\\$\[0-9\]+ = 42" \ + "print method call on referenced object" + +# Test that the stored reference works correctly. +gdb_test_multiple "print ref" "print stored reference" { + -re "\\$\[0-9\]+ = \\(const foo &\\) @$hex: \\{m_a = 42\\}\r\n$gdb_prompt $" { + pass $gdb_test_name + } + -re "Could not validate memory tag: Value can't be converted to integer\\." { + fail "$gdb_test_name" + } +} + +gdb_test "print ref.m_a" \ + "\\$\[0-9\]+ = 42" \ + "print member through stored reference" + +gdb_test "print ref.get_a()" \ + "\\$\[0-9\]+ = 42" \ + "print method call through stored reference"
\ No newline at end of file diff --git a/gdb/testsuite/gdb.tui/basic.exp b/gdb/testsuite/gdb.tui/basic.exp index 35c99bd..48b90da 100644 --- a/gdb/testsuite/gdb.tui/basic.exp +++ b/gdb/testsuite/gdb.tui/basic.exp @@ -112,5 +112,9 @@ set re_noattr "\[^<\]" set status_window_line 15 set status [Term::get_line_with_attrs $status_window_line] -gdb_assert { [regexp "^<reverse:1>$re_noattr*<reverse:0>$" $status] == 1} \ +verbose -log "status line: '$status'" + +# The status line uses standout, which may translate to different attributes +# depending on the terminal settings. Just check for at least one attribute. +gdb_assert { [regexp "^<.*>exec" $status] == 1 } \ "status window: reverse" diff --git a/gdb/testsuite/gdb.tui/color-prompt.exp b/gdb/testsuite/gdb.tui/color-prompt.exp index a95b24a..af6e467 100644 --- a/gdb/testsuite/gdb.tui/color-prompt.exp +++ b/gdb/testsuite/gdb.tui/color-prompt.exp @@ -15,18 +15,16 @@ # Check using a prompt with color in TUI. +require allow_tui_tests + tuiterm_env Term::clean_restart 24 80 -# Set colored prompt. if {![Term::enter_tui]} { unsupported "TUI not supported" return } -Term::command "set prompt \\033\[31m(gdb) \\033\[0m" - -set line [Term::get_line_with_attrs $Term::_cur_row] -gdb_assert { [regexp "^<fg:red>$gdb_prompt <fg:default> *$" $line] } \ - "prompt with color" +set tui 1 +source $srcdir/$subdir/color-prompt.exp.tcl diff --git a/gdb/testsuite/gdb.tui/color-prompt.exp.tcl b/gdb/testsuite/gdb.tui/color-prompt.exp.tcl new file mode 100644 index 0000000..e6f4d3b --- /dev/null +++ b/gdb/testsuite/gdb.tui/color-prompt.exp.tcl @@ -0,0 +1,80 @@ +# Copyright 2025 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 <http://www.gnu.org/licenses/>. + +# Check using a prompt with color in TUI ($tui == 0) or CLI ($tui == 0). + +set csi [string cat {\033} "\["] +set rl_prompt_start_ignore {\001} +set rl_prompt_end_ignore {\002} + +foreach_with_prefix rl_prompt_start_end_ignore { 0 1 } { + set color_on [string cat $csi 31m] + set color_off [string cat $csi 0m] + + if { $rl_prompt_start_end_ignore } { + set color_on \ + [string cat \ + $rl_prompt_start_ignore \ + $color_on \ + $rl_prompt_end_ignore] + set color_off \ + [string cat \ + $rl_prompt_start_ignore \ + $color_off \ + $rl_prompt_end_ignore] + } + + # Set prompt with color. + set prompt "${color_on}(gdb) $color_off" + Term::command "set prompt $prompt" + + # Check the color. + set line [Term::get_line_with_attrs $Term::_cur_row] + gdb_assert { [regexp "^<fg:red>$gdb_prompt <fg:default> *$" $line] } \ + "prompt with color" + + # Type a string. + set cmd "some long command" + send_gdb $cmd + Term::wait_for_line ^[string_to_regexp "(gdb) $cmd"] 23 + + # Send ^A, aka C-a, trigger beginning-of-line. + send_gdb "\001" + if { $tui || $rl_prompt_start_end_ignore } { + Term::wait_for_line ^[string_to_regexp "(gdb) $cmd"] 6 + } else { + # Without the markers, readline may get the cursor position wrong, so + # match less strict. + Term::wait_for_line ^[string_to_regexp "(gdb) $cmd"] + } + Term::dump_screen + + # Type something else to flush out the effect of the ^A. + set prefix "A" + send_gdb $prefix + if { $tui || $rl_prompt_start_end_ignore } { + Term::wait_for_line ^[string_to_regexp "(gdb) $prefix$cmd"] 7 + } else { + # Without the markers, readline may get the cursor position wrong, so + # match less strict. + Term::wait_for_line [string_to_regexp "$prefix"] + } + + # Abort command line editing, and regenerate prompt. + send_gdb "\003" + + # Reset prompt to default prompt. + Term::command "set prompt (gdb) " +} diff --git a/gdb/testsuite/gdb.tui/main-2.exp b/gdb/testsuite/gdb.tui/main-2.exp index 71ad03b..14a7cb1 100644 --- a/gdb/testsuite/gdb.tui/main-2.exp +++ b/gdb/testsuite/gdb.tui/main-2.exp @@ -41,7 +41,7 @@ if {![Term::enter_tui]} { set line " return 0;" set nr [gdb_get_line_number $line] -set screen_line [Term::get_string_with_attrs 6 1 79] +set screen_line [Term::get_string_with_attrs 6 11 79] verbose -log "screen line 6: '$screen_line'" -gdb_assert { [regexp "$nr <reverse:1>$line<reverse:0>" $screen_line] } \ +gdb_assert { [regexp "<reverse:1>$line<reverse:0>" $screen_line] } \ "highlighted line in middle of source window" diff --git a/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.exp b/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.exp index 51623e8..47482a2 100644 --- a/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.exp +++ b/gdb/testsuite/gdb.tui/tui-layout-asm-short-prog.exp @@ -20,9 +20,13 @@ tuiterm_env standard_testfile tui-layout-asm-short-prog.S -if {[build_executable "failed to prepare" ${testfile} ${srcfile} \ - {debug additional_flags=-nostdlib \ - additional_flags=-nostartfiles}] == -1} { +set opts {} +lappend opts debug +lappend opts additional_flags=-static +lappend opts additional_flags=-nostdlib +lappend opts additional_flags=-nostartfiles + +if { [build_executable "failed to prepare" $testfile $srcfile $opts] == -1 } { return -1 } diff --git a/gdb/testsuite/lib/tuiterm.exp b/gdb/testsuite/lib/tuiterm.exp index b83b8af..f4a8702 100644 --- a/gdb/testsuite/lib/tuiterm.exp +++ b/gdb/testsuite/lib/tuiterm.exp @@ -92,7 +92,9 @@ namespace eval Term { # Return 1 if tuiterm has the bw/auto_left_margin enabled. proc _have_bw {} { - return [string equal $Term::_TERM "ansiw"] + return [expr \ + [string equal $Term::_TERM "ansiw"] \ + || [string equal $Term::_TERM "ansis"]] } # Backspace. @@ -701,6 +703,14 @@ namespace eval Term { } } + # Request Terminal Parameters (DECREQTPARM) + # + # https://invisible-island.net/xterm/ctlseqs/ctlseqs.html + # https://vt100.net/docs/vt100-ug/chapter3.html + proc _csi_x {} { + # Ignore. + } + # Insert string at the cursor location. proc _insert {str} { _log_cur "Inserted string '$str'" { @@ -886,6 +896,31 @@ namespace eval Term { return 1 } + # Accept some output from gdb and update the screen. Wait for the current + # screen line to match REGEXP and cursor position POS, unless POS is empty. + # Return 0 on timeout, 1 on success. + proc wait_for_line { regexp {pos ""} } { + variable _cur_row + variable _cur_col + variable _cols + + while 1 { + if { [accept_gdb_output] == 0 } { + return 0 + } + + if { ![check_region_contents_p 0 $_cur_row $_cols 1 $regexp] } { + continue + } + + if { $pos == "" || $_cur_col == $pos } { + break + } + } + + return 1 + } + # Setup the terminal with dimensions ROWSxCOLS, TERM=ansi, and execute # BODY. proc with_tuiterm {rows cols body} { |