* [PATCH] gdb/testsuite: Work around clang fails in gdb.base/watchpoint.exp @ 2023-10-26 9:04 Guinevere Larsen 2023-10-27 13:56 ` Andrew Burgess 2023-11-02 9:50 ` [PATCH v2] gdb: register frame_destroyed function for amd64 gdbarch Guinevere Larsen 0 siblings, 2 replies; 8+ messages in thread From: Guinevere Larsen @ 2023-10-26 9:04 UTC (permalink / raw) To: gdb-patches; +Cc: Guinevere Larsen as mentioned in commit def86538a46f7ce6fbb215cfb184e23015b5d538, clang doesn't use the CFA information for variable locations, making it so software watchpoints get false hits when exiting a function. Differently to that commit, however, gdb.base/watchpoint.exp also needs to be explicitly continued so the inferior will remain in sync with what the exp file expects, so this commit uses gdb_test_multiple to identify that situation. I also chose to keep the test passing in that scenario because the GDB feature being tested, software watchpoints, is working as expected. --- gdb/testsuite/gdb.base/watchpoint.exp | 82 +++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 6 deletions(-) diff --git a/gdb/testsuite/gdb.base/watchpoint.exp b/gdb/testsuite/gdb.base/watchpoint.exp index 70864655c6d..5d8d6b9cb31 100644 --- a/gdb/testsuite/gdb.base/watchpoint.exp +++ b/gdb/testsuite/gdb.base/watchpoint.exp @@ -30,6 +30,11 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb return -1 } +set using_clang 0 +if {[test_compiler_info "clang-*"]} { + set using_clang 1 +} + # True if we're forcing no hardware watchpoints. set no_hw 0 @@ -486,6 +491,20 @@ proc test_complex_watchpoint {} { } fail $test } + -re -wrap ".*Continuing.*\[Ww\]atchpoint.*" { + global no_hw + global using_clang + # Clang doesn't use the CFA, so software watchpoints get one + # false hit here. Detect if we're in that situation and + # ignore the false hit. For more info, see: + # https://github.com/llvm/llvm-project/issues/64390 + if {$using_clang == 1 && $no_hw == 1} { + send_gdb "cont\n" + exp_continue + } else { + fail $gdb_test_name + } + } } gdb_continue_to_breakpoint "func2 breakpoint here, second time" @@ -501,8 +520,25 @@ proc test_complex_watchpoint {} { "trigger1 partially local watch" gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_a . ival5.*" \ "trigger2 partially local watch" - gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \ - "self-delete partially local watch" + gdb_test_multiple "cont" "self-delete partially local watch" { + -re -wrap "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" { + pass $gdb_test_name + } + -re -wrap ".*Continuing.*\[Ww\]atchpoint.*" { + global no_hw + global using_clang + # Clang doesn't use the CFA, so software watchpoints get one + # false hit here. Detect if we're in that situation and + # ignore the false hit. For more info, see: + # https://github.com/llvm/llvm-project/issues/64390 + if {$using_clang == 1 && $no_hw == 1} { + send_gdb "cont\n" + exp_continue + } else { + fail $gdb_test_name + } + } + } # We should be in "func2" again now. Test a watch of a # static (non-stack-based) local. Since this has scope @@ -535,8 +571,25 @@ proc test_complex_watchpoint {} { "set local watch in recursive call" gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_x.*New value = 2.*" \ "trigger local watch in recursive call" - gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \ - "self-delete local watch in recursive call" + gdb_test_multiple "cont" "self-delete local watch in recursive call" { + -re -wrap "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" { + pass $gdb_test_name + } + -re -wrap ".*Continuing.*\[Ww\]atchpoint.*" { + global no_hw + global using_clang + # Clang doesn't use the CFA, so software watchpoints get one + # false hit here. Detect if we're in that situation and + # ignore the false hit. For more info, see: + # https://github.com/llvm/llvm-project/issues/64390 + if {$using_clang == 1 && $no_hw == 1} { + send_gdb "cont\n" + exp_continue + } else { + fail $gdb_test_name + } + } + } } # Repeat the preceding test, but this time use "recurser::local_x" as @@ -551,8 +604,25 @@ proc test_complex_watchpoint {} { "set local watch in recursive call with explicit scope" gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: recurser::local_x.*New value = 2.*" \ "trigger local watch with explicit scope in recursive call" - gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \ - "self-delete local watch with explicit scope in recursive call (2)" + gdb_test_multiple "cont" "self-delete local watch with explicit scope in recursive call (2)" { + -re -wrap "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" { + pass $gdb_test_name + } + -re -wrap ".*Continuing.*\[Ww\]atchpoint.*" { + global no_hw + global using_clang + # Clang doesn't use the CFA, so software watchpoints get one + # false hit here. Detect if we're in that situation and + # ignore the false hit. For more info, see: + # https://github.com/llvm/llvm-project/issues/64390 + if {$using_clang == 1 && $no_hw == 1} { + send_gdb "cont\n" + exp_continue + } else { + fail $gdb_test_name + } + } + } } # Disable everything so we can finish the program at full speed -- 2.41.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] gdb/testsuite: Work around clang fails in gdb.base/watchpoint.exp 2023-10-26 9:04 [PATCH] gdb/testsuite: Work around clang fails in gdb.base/watchpoint.exp Guinevere Larsen @ 2023-10-27 13:56 ` Andrew Burgess 2023-11-02 9:50 ` [PATCH v2] gdb: register frame_destroyed function for amd64 gdbarch Guinevere Larsen 1 sibling, 0 replies; 8+ messages in thread From: Andrew Burgess @ 2023-10-27 13:56 UTC (permalink / raw) To: Guinevere Larsen, gdb-patches; +Cc: Guinevere Larsen Guinevere Larsen <blarsen@redhat.com> writes: > as mentioned in commit def86538a46f7ce6fbb215cfb184e23015b5d538, clang > doesn't use the CFA information for variable locations, making it so > software watchpoints get false hits when exiting a function. Differently > to that commit, however, gdb.base/watchpoint.exp also needs to be > explicitly continued so the inferior will remain in sync with what the > exp file expects, so this commit uses gdb_test_multiple to identify that > situation. > > I also chose to keep the test passing in that scenario because the GDB > feature being tested, software watchpoints, is working as expected. I'm not sure I 100% agree with this conclusion. The test is placing on a watchpoint that isn't expected to change ... yet we see the watchpoint trigger. I'd say the test is failing. I wonder if we could just set a flag when we see an unexpected stop, and then xfail rather than pass once the watchpoint goes out of scope? I think the right fix would be to implement the gdbarch_stack_frame_destroyed_p method for amd64. Looking in amd64-tdep.c I noticed we actually already have amd64_stack_frame_destroyed_p, we just don't register it with the gdbarch ... I guess there's some history here. Anyway, the patch below (untested except for watchpoint.exp) seems to remove the need for any changes to watchpoint.exp, what are your thoughts? > --- > gdb/testsuite/gdb.base/watchpoint.exp | 82 +++++++++++++++++++++++++-- > 1 file changed, 76 insertions(+), 6 deletions(-) > > diff --git a/gdb/testsuite/gdb.base/watchpoint.exp b/gdb/testsuite/gdb.base/watchpoint.exp > index 70864655c6d..5d8d6b9cb31 100644 > --- a/gdb/testsuite/gdb.base/watchpoint.exp > +++ b/gdb/testsuite/gdb.base/watchpoint.exp > @@ -30,6 +30,11 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb > return -1 > } > > +set using_clang 0 > +if {[test_compiler_info "clang-*"]} { > + set using_clang 1 > +} You can actually use 'true' and 'false' here, given this is a boolean. > + > # True if we're forcing no hardware watchpoints. > set no_hw 0 > > @@ -486,6 +491,20 @@ proc test_complex_watchpoint {} { > } > fail $test > } > + -re -wrap ".*Continuing.*\[Ww\]atchpoint.*" { > + global no_hw > + global using_clang > + # Clang doesn't use the CFA, so software watchpoints get one > + # false hit here. Detect if we're in that situation and > + # ignore the false hit. For more info, see: > + # https://github.com/llvm/llvm-project/issues/64390 > + if {$using_clang == 1 && $no_hw == 1} { And here (and elsewhere) you can write: if {$using_clang && $no_hw} { which better reflects the boolean nature of these flags. > + send_gdb "cont\n" > + exp_continue > + } else { > + fail $gdb_test_name > + } > + } > } > > gdb_continue_to_breakpoint "func2 breakpoint here, second time" > @@ -501,8 +520,25 @@ proc test_complex_watchpoint {} { > "trigger1 partially local watch" > gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_a . ival5.*" \ > "trigger2 partially local watch" > - gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \ > - "self-delete partially local watch" > + gdb_test_multiple "cont" "self-delete partially local watch" { > + -re -wrap "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" { > + pass $gdb_test_name > + } > + -re -wrap ".*Continuing.*\[Ww\]atchpoint.*" { > + global no_hw > + global using_clang > + # Clang doesn't use the CFA, so software watchpoints get one > + # false hit here. Detect if we're in that situation and > + # ignore the false hit. For more info, see: > + # https://github.com/llvm/llvm-project/issues/64390 > + if {$using_clang == 1 && $no_hw == 1} { > + send_gdb "cont\n" > + exp_continue > + } else { > + fail $gdb_test_name > + } > + } > + } > > # We should be in "func2" again now. Test a watch of a > # static (non-stack-based) local. Since this has scope > @@ -535,8 +571,25 @@ proc test_complex_watchpoint {} { > "set local watch in recursive call" > gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_x.*New value = 2.*" \ > "trigger local watch in recursive call" > - gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \ > - "self-delete local watch in recursive call" > + gdb_test_multiple "cont" "self-delete local watch in recursive call" { > + -re -wrap "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" { > + pass $gdb_test_name > + } > + -re -wrap ".*Continuing.*\[Ww\]atchpoint.*" { > + global no_hw > + global using_clang > + # Clang doesn't use the CFA, so software watchpoints get one > + # false hit here. Detect if we're in that situation and > + # ignore the false hit. For more info, see: > + # https://github.com/llvm/llvm-project/issues/64390 > + if {$using_clang == 1 && $no_hw == 1} { > + send_gdb "cont\n" > + exp_continue > + } else { > + fail $gdb_test_name > + } > + } > + } > } > > # Repeat the preceding test, but this time use "recurser::local_x" as > @@ -551,8 +604,25 @@ proc test_complex_watchpoint {} { > "set local watch in recursive call with explicit scope" > gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: recurser::local_x.*New value = 2.*" \ > "trigger local watch with explicit scope in recursive call" > - gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \ > - "self-delete local watch with explicit scope in recursive call (2)" > + gdb_test_multiple "cont" "self-delete local watch with explicit scope in recursive call (2)" { > + -re -wrap "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" { > + pass $gdb_test_name > + } > + -re -wrap ".*Continuing.*\[Ww\]atchpoint.*" { > + global no_hw > + global using_clang > + # Clang doesn't use the CFA, so software watchpoints get one > + # false hit here. Detect if we're in that situation and > + # ignore the false hit. For more info, see: > + # https://github.com/llvm/llvm-project/issues/64390 > + if {$using_clang == 1 && $no_hw == 1} { > + send_gdb "cont\n" > + exp_continue > + } else { > + fail $gdb_test_name > + } > + } > + } > } > > # Disable everything so we can finish the program at full speed > -- > 2.41.0 Thanks, Andrew --- diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index e6feee677b3..15120d55976 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -2888,7 +2888,7 @@ static const struct frame_base amd64_frame_base = /* Normal frames, but in a function epilogue. */ -/* Implement the stack_frame_destroyed_p gdbarch method. +/* Implement core of the stack_frame_destroyed_p gdbarch method. The epilogue is defined here as the 'ret' instruction, which will follow any instruction such as 'leave' or 'pop %ebp' that destroys @@ -2908,6 +2908,33 @@ amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) return 1; } +/* Implement the gdbarch_stack_frame_destroyed_p method. + + This wrapper delegates to amd64_stack_frame_destroyed_p_1 for compilers + that we know get the debug information for stack local variables wrong + (i.e. Clang) during the function epilogue. + + For other compilers (i.e. not Clang) we trust the debug information. */ + +static int +amd64_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + struct compunit_symtab *cust = find_pc_compunit_symtab (pc); + + /* LLVM backend (Clang/Flang) doesn't use CFA based locations for stack + local variables. As a consequence, when we enter the function + epilogue GDB will calculate the wrong location for stack local + variables, and watchpoints will trigger. */ + if (cust != nullptr + && cust->producer () != nullptr + && producer_is_llvm (cust->producer ())) + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); + + /* For other producers, trust the debug information. */ + return 0; +} + + static int amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, frame_info_ptr this_frame, @@ -2938,7 +2965,7 @@ amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, } /* Check whether we're in an epilogue. */ - return amd64_stack_frame_destroyed_p (gdbarch, pc); + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); } static int @@ -3310,6 +3337,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address); + set_gdbarch_stack_frame_destroyed_p (gdbarch, amd64_stack_frame_destroyed_p); + /* SystemTap variables and functions. */ set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] gdb: register frame_destroyed function for amd64 gdbarch 2023-10-26 9:04 [PATCH] gdb/testsuite: Work around clang fails in gdb.base/watchpoint.exp Guinevere Larsen 2023-10-27 13:56 ` Andrew Burgess @ 2023-11-02 9:50 ` Guinevere Larsen 2023-11-07 15:38 ` Andrew Burgess 2023-11-08 14:24 ` [PATCH v3] " Guinevere Larsen 1 sibling, 2 replies; 8+ messages in thread From: Guinevere Larsen @ 2023-11-02 9:50 UTC (permalink / raw) To: gdb-patches; +Cc: Guinevere Larsen, Andrew Burgess gdbarches usually register functions to check when a frame is destroyed which is used with software watchpoints, since the expression of the watchpoint is no longer vlaid at this point. On amd64, this wasn't done anymore because GCC started using CFA for variable locations instead. However, clang doesn't use the CFA and instead relies on specifying when an epilogue has started, meaning software watchpoints get a spurious hit when a frame is destroyed. This patch re-adds the code to register the function that detects when a frame is destroyed, but only uses this when the producer is LLVM, so gcc code isn't affected. This can also remove the XFAIL added to gdb.python/pq-watchpoint tests that handled this exact flaw in clang Co-Authored-By: Andrew Burgess <aburgess@redhat.com> --- gdb/amd64-tdep.c | 16 +++++++++++++++- gdb/testsuite/gdb.python/py-watchpoint.exp | 17 +---------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index e6feee677b3..362151f227c 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -2908,6 +2908,18 @@ amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) return 1; } +static int +amd64_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + struct compunit_symtab *cust = find_pc_compunit_symtab (pc); + + if (cust != nullptr && cust->producer () != nullptr + && producer_is_llvm (cust->producer ())) + return amd64_stack_frame_destroyed_p (gdbarch, pc); + + return 0; +} + static int amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, frame_info_ptr this_frame, @@ -2938,7 +2950,7 @@ amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, } /* Check whether we're in an epilogue. */ - return amd64_stack_frame_destroyed_p (gdbarch, pc); + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); } static int @@ -3310,6 +3322,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address); + set_gdbarch_stack_frame_destroyed_p (gdbarch, amd64_stack_frame_destroyed_p_1); + /* SystemTap variables and functions. */ set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); diff --git a/gdb/testsuite/gdb.python/py-watchpoint.exp b/gdb/testsuite/gdb.python/py-watchpoint.exp index 5ff61285979..9a6ef447572 100644 --- a/gdb/testsuite/gdb.python/py-watchpoint.exp +++ b/gdb/testsuite/gdb.python/py-watchpoint.exp @@ -42,20 +42,5 @@ gdb_test "source $pyfile" ".*Python script imported.*" \ "import python scripts" gdb_test "python print(len(gdb.breakpoints()))" "2" "check modified BP count" gdb_test "continue" ".*" "run until program stops" -# Clang doesn't use CFA location information for variables (despite generating -# them), meaning when the instruction "pop rbp" happens, we get a false hit -# on the watchpoint. for more details, see: -# https://github.com/llvm/llvm-project/issues/64390 -gdb_test_multiple "python print(bpt.n)" "check watchpoint hits" { - -re -wrap "5" { - pass $gdb_test_name - } - -re -wrap "6" { - if {[test_compiler_info "clang-*"]} { - xfail "$gdb_test_name (clang issue 64390)" - } else { - fail $gdb_test_name - } - } -} +gdb_test "python print(bpt.n)" "5" "check watchpoint hits" gdb_test "python print(len(gdb.breakpoints()))" "1" "check BP count" -- 2.41.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] gdb: register frame_destroyed function for amd64 gdbarch 2023-11-02 9:50 ` [PATCH v2] gdb: register frame_destroyed function for amd64 gdbarch Guinevere Larsen @ 2023-11-07 15:38 ` Andrew Burgess 2023-11-08 14:24 ` [PATCH v3] " Guinevere Larsen 1 sibling, 0 replies; 8+ messages in thread From: Andrew Burgess @ 2023-11-07 15:38 UTC (permalink / raw) To: Guinevere Larsen, gdb-patches; +Cc: Guinevere Larsen Guinevere Larsen <blarsen@redhat.com> writes: > gdbarches usually register functions to check when a frame is destroyed > which is used with software watchpoints, since the expression of the > watchpoint is no longer vlaid at this point. On amd64, this wasn't done > anymore because GCC started using CFA for variable locations instead. > > However, clang doesn't use the CFA and instead relies on specifying when > an epilogue has started, meaning software watchpoints get a spurious hit > when a frame is destroyed. This patch re-adds the code to register the > function that detects when a frame is destroyed, but only uses this when > the producer is LLVM, so gcc code isn't affected. > > This can also remove the XFAIL added to gdb.python/pq-watchpoint tests > that handled this exact flaw in clang > > Co-Authored-By: Andrew Burgess <aburgess@redhat.com> > --- > gdb/amd64-tdep.c | 16 +++++++++++++++- > gdb/testsuite/gdb.python/py-watchpoint.exp | 17 +---------------- > 2 files changed, 16 insertions(+), 17 deletions(-) > > diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c > index e6feee677b3..362151f227c 100644 > --- a/gdb/amd64-tdep.c > +++ b/gdb/amd64-tdep.c > @@ -2908,6 +2908,18 @@ amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) > return 1; > } > > +static int > +amd64_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc) > +{ > + struct compunit_symtab *cust = find_pc_compunit_symtab (pc); > + > + if (cust != nullptr && cust->producer () != nullptr > + && producer_is_llvm (cust->producer ())) > + return amd64_stack_frame_destroyed_p (gdbarch, pc); > + > + return 0; > +} > + > static int > amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, > frame_info_ptr this_frame, > @@ -2938,7 +2950,7 @@ amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, > } > > /* Check whether we're in an epilogue. */ > - return amd64_stack_frame_destroyed_p (gdbarch, pc); > + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); Hi Gwen! I can see you took this change from the patch I posted, so it's not really your fault .... but this isn't really correct. Previously amd64_epilogue_frame_sniffer_1 was calling amd64_stack_frame_destroyed_p, which unconditionally did the instruction check. Now, we only do the instruction check for llvm. I don't think this is a good change. Here's what I think I meant, but got wrong... 1. The existing amd64_stack_frame_destroyed_p should be renamed to amd64_stack_frame_destroyed_p_1, this is the "inner" helper function, 2. amd64_epilogue_frame_sniffer_1 should indeed be updated to call amd64_stack_frame_destroyed_p_1, but this is now the unconditional instruction check, thus amd64_epilogue_frame_sniffer_1 is unchanged (in functionality), 3. The new function being added, which is amd64_stack_frame_destroyed_p_1 in your (and my original) patch, should actually be called amd64_stack_frame_destroyed_p, 4. And the set_gdbarch_stack_frame_destroyed_p call below should be registering amd64_stack_frame_destroyed_p, not the _1 version. Also, the new static function (amd64_stack_frame_destroyed_p in the new plan) will need a comment. I'm biased, but I can recommend the comment from my original patch, but whatever you feel is appropriate. Thanks, Andrew > } > > static int > @@ -3310,6 +3322,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, > > set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address); > > + set_gdbarch_stack_frame_destroyed_p (gdbarch, amd64_stack_frame_destroyed_p_1); > + > /* SystemTap variables and functions. */ > set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); > set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); > diff --git a/gdb/testsuite/gdb.python/py-watchpoint.exp b/gdb/testsuite/gdb.python/py-watchpoint.exp > index 5ff61285979..9a6ef447572 100644 > --- a/gdb/testsuite/gdb.python/py-watchpoint.exp > +++ b/gdb/testsuite/gdb.python/py-watchpoint.exp > @@ -42,20 +42,5 @@ gdb_test "source $pyfile" ".*Python script imported.*" \ > "import python scripts" > gdb_test "python print(len(gdb.breakpoints()))" "2" "check modified BP count" > gdb_test "continue" ".*" "run until program stops" > -# Clang doesn't use CFA location information for variables (despite generating > -# them), meaning when the instruction "pop rbp" happens, we get a false hit > -# on the watchpoint. for more details, see: > -# https://github.com/llvm/llvm-project/issues/64390 > -gdb_test_multiple "python print(bpt.n)" "check watchpoint hits" { > - -re -wrap "5" { > - pass $gdb_test_name > - } > - -re -wrap "6" { > - if {[test_compiler_info "clang-*"]} { > - xfail "$gdb_test_name (clang issue 64390)" > - } else { > - fail $gdb_test_name > - } > - } > -} > +gdb_test "python print(bpt.n)" "5" "check watchpoint hits" > gdb_test "python print(len(gdb.breakpoints()))" "1" "check BP count" > -- > 2.41.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3] gdb: register frame_destroyed function for amd64 gdbarch 2023-11-02 9:50 ` [PATCH v2] gdb: register frame_destroyed function for amd64 gdbarch Guinevere Larsen 2023-11-07 15:38 ` Andrew Burgess @ 2023-11-08 14:24 ` Guinevere Larsen 2023-12-07 17:36 ` [PING][PATCH " Guinevere Larsen 2023-12-19 11:51 ` [PATCH " Andrew Burgess 1 sibling, 2 replies; 8+ messages in thread From: Guinevere Larsen @ 2023-11-08 14:24 UTC (permalink / raw) To: gdb-patches; +Cc: Guinevere Larsen, Andrew Burgess gdbarches usually register functions to check when a frame is destroyed which is used with software watchpoints, since the expression of the watchpoint is no longer vlaid at this point. On amd64, this wasn't done anymore because GCC started using CFA for variable locations instead. However, clang doesn't use the CFA and instead relies on specifying when an epilogue has started, meaning software watchpoints get a spurious hit when a frame is destroyed. This patch re-adds the code to register the function that detects when a frame is destroyed, but only uses this when the producer is LLVM, so gcc code isn't affected. The logic that identifies the epilogue has been factored out into the new function amd64_stack_frame_destroyed_p_1, so the frame sniffer can call it directly, and its behavior isn't changed. This can also remove the XFAIL added to gdb.python/pq-watchpoint tests that handled this exact flaw in clang Co-Authored-By: Andrew Burgess <aburgess@redhat.com> --- gdb/amd64-tdep.c | 32 ++++++++++++++++------ gdb/testsuite/gdb.python/py-watchpoint.exp | 17 +----------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index e6feee677b3..2e101b4fca1 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -2886,6 +2886,22 @@ static const struct frame_base amd64_frame_base = amd64_frame_base_address }; +/* Implement core of the stack_frame_destroyed_p gdbarch method. */ + +static int +amd64_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + gdb_byte insn; + + if (target_read_memory (pc, &insn, 1)) + return 0; /* Can't read memory at pc. */ + + if (insn != 0xc3) /* 'ret' instruction. */ + return 0; + + return 1; +} + /* Normal frames, but in a function epilogue. */ /* Implement the stack_frame_destroyed_p gdbarch method. @@ -2897,15 +2913,13 @@ static const struct frame_base amd64_frame_base = static int amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) { - gdb_byte insn; + struct compunit_symtab *cust = find_pc_compunit_symtab (pc); - if (target_read_memory (pc, &insn, 1)) - return 0; /* Can't read memory at pc. */ + if (cust != nullptr && cust->producer () != nullptr + && producer_is_llvm (cust->producer ())) + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); - if (insn != 0xc3) /* 'ret' instruction. */ - return 0; - - return 1; + return 0; } static int @@ -2938,7 +2952,7 @@ amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, } /* Check whether we're in an epilogue. */ - return amd64_stack_frame_destroyed_p (gdbarch, pc); + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); } static int @@ -3310,6 +3324,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address); + set_gdbarch_stack_frame_destroyed_p (gdbarch, amd64_stack_frame_destroyed_p); + /* SystemTap variables and functions. */ set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); diff --git a/gdb/testsuite/gdb.python/py-watchpoint.exp b/gdb/testsuite/gdb.python/py-watchpoint.exp index 5ff61285979..9a6ef447572 100644 --- a/gdb/testsuite/gdb.python/py-watchpoint.exp +++ b/gdb/testsuite/gdb.python/py-watchpoint.exp @@ -42,20 +42,5 @@ gdb_test "source $pyfile" ".*Python script imported.*" \ "import python scripts" gdb_test "python print(len(gdb.breakpoints()))" "2" "check modified BP count" gdb_test "continue" ".*" "run until program stops" -# Clang doesn't use CFA location information for variables (despite generating -# them), meaning when the instruction "pop rbp" happens, we get a false hit -# on the watchpoint. for more details, see: -# https://github.com/llvm/llvm-project/issues/64390 -gdb_test_multiple "python print(bpt.n)" "check watchpoint hits" { - -re -wrap "5" { - pass $gdb_test_name - } - -re -wrap "6" { - if {[test_compiler_info "clang-*"]} { - xfail "$gdb_test_name (clang issue 64390)" - } else { - fail $gdb_test_name - } - } -} +gdb_test "python print(bpt.n)" "5" "check watchpoint hits" gdb_test "python print(len(gdb.breakpoints()))" "1" "check BP count" -- 2.41.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PING][PATCH v3] gdb: register frame_destroyed function for amd64 gdbarch 2023-11-08 14:24 ` [PATCH v3] " Guinevere Larsen @ 2023-12-07 17:36 ` Guinevere Larsen 2023-12-18 10:24 ` [PINGv2][PATCH " Guinevere Larsen 2023-12-19 11:51 ` [PATCH " Andrew Burgess 1 sibling, 1 reply; 8+ messages in thread From: Guinevere Larsen @ 2023-12-07 17:36 UTC (permalink / raw) To: gdb-patches, Guinevere Larsen; +Cc: Andrew Burgess Ping! -- Cheers, Guinevere Larsen She/Her/Hers On 08/11/2023 15:24, Guinevere Larsen wrote: > gdbarches usually register functions to check when a frame is destroyed > which is used with software watchpoints, since the expression of the > watchpoint is no longer vlaid at this point. On amd64, this wasn't done > anymore because GCC started using CFA for variable locations instead. > > However, clang doesn't use the CFA and instead relies on specifying when > an epilogue has started, meaning software watchpoints get a spurious hit > when a frame is destroyed. This patch re-adds the code to register the > function that detects when a frame is destroyed, but only uses this when > the producer is LLVM, so gcc code isn't affected. The logic that > identifies the epilogue has been factored out into the new function > amd64_stack_frame_destroyed_p_1, so the frame sniffer can call it > directly, and its behavior isn't changed. > > This can also remove the XFAIL added to gdb.python/pq-watchpoint tests > that handled this exact flaw in clang > > Co-Authored-By: Andrew Burgess <aburgess@redhat.com> > --- > gdb/amd64-tdep.c | 32 ++++++++++++++++------ > gdb/testsuite/gdb.python/py-watchpoint.exp | 17 +----------- > 2 files changed, 25 insertions(+), 24 deletions(-) > > diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c > index e6feee677b3..2e101b4fca1 100644 > --- a/gdb/amd64-tdep.c > +++ b/gdb/amd64-tdep.c > @@ -2886,6 +2886,22 @@ static const struct frame_base amd64_frame_base = > amd64_frame_base_address > }; > > +/* Implement core of the stack_frame_destroyed_p gdbarch method. */ > + > +static int > +amd64_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc) > +{ > + gdb_byte insn; > + > + if (target_read_memory (pc, &insn, 1)) > + return 0; /* Can't read memory at pc. */ > + > + if (insn != 0xc3) /* 'ret' instruction. */ > + return 0; > + > + return 1; > +} > + > /* Normal frames, but in a function epilogue. */ > > /* Implement the stack_frame_destroyed_p gdbarch method. > @@ -2897,15 +2913,13 @@ static const struct frame_base amd64_frame_base = > static int > amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) > { > - gdb_byte insn; > + struct compunit_symtab *cust = find_pc_compunit_symtab (pc); > > - if (target_read_memory (pc, &insn, 1)) > - return 0; /* Can't read memory at pc. */ > + if (cust != nullptr && cust->producer () != nullptr > + && producer_is_llvm (cust->producer ())) > + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); > > - if (insn != 0xc3) /* 'ret' instruction. */ > - return 0; > - > - return 1; > + return 0; > } > > static int > @@ -2938,7 +2952,7 @@ amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, > } > > /* Check whether we're in an epilogue. */ > - return amd64_stack_frame_destroyed_p (gdbarch, pc); > + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); > } > > static int > @@ -3310,6 +3324,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, > > set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address); > > + set_gdbarch_stack_frame_destroyed_p (gdbarch, amd64_stack_frame_destroyed_p); > + > /* SystemTap variables and functions. */ > set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); > set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); > diff --git a/gdb/testsuite/gdb.python/py-watchpoint.exp b/gdb/testsuite/gdb.python/py-watchpoint.exp > index 5ff61285979..9a6ef447572 100644 > --- a/gdb/testsuite/gdb.python/py-watchpoint.exp > +++ b/gdb/testsuite/gdb.python/py-watchpoint.exp > @@ -42,20 +42,5 @@ gdb_test "source $pyfile" ".*Python script imported.*" \ > "import python scripts" > gdb_test "python print(len(gdb.breakpoints()))" "2" "check modified BP count" > gdb_test "continue" ".*" "run until program stops" > -# Clang doesn't use CFA location information for variables (despite generating > -# them), meaning when the instruction "pop rbp" happens, we get a false hit > -# on the watchpoint. for more details, see: > -# https://github.com/llvm/llvm-project/issues/64390 > -gdb_test_multiple "python print(bpt.n)" "check watchpoint hits" { > - -re -wrap "5" { > - pass $gdb_test_name > - } > - -re -wrap "6" { > - if {[test_compiler_info "clang-*"]} { > - xfail "$gdb_test_name (clang issue 64390)" > - } else { > - fail $gdb_test_name > - } > - } > -} > +gdb_test "python print(bpt.n)" "5" "check watchpoint hits" > gdb_test "python print(len(gdb.breakpoints()))" "1" "check BP count" ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PINGv2][PATCH v3] gdb: register frame_destroyed function for amd64 gdbarch 2023-12-07 17:36 ` [PING][PATCH " Guinevere Larsen @ 2023-12-18 10:24 ` Guinevere Larsen 0 siblings, 0 replies; 8+ messages in thread From: Guinevere Larsen @ 2023-12-18 10:24 UTC (permalink / raw) To: gdb-patches; +Cc: Andrew Burgess Ping! On 07/12/2023 18:36, Guinevere Larsen wrote: > Ping! > > -- > Cheers, > Guinevere Larsen > She/Her/Hers > > On 08/11/2023 15:24, Guinevere Larsen wrote: >> gdbarches usually register functions to check when a frame is destroyed >> which is used with software watchpoints, since the expression of the >> watchpoint is no longer vlaid at this point. On amd64, this wasn't done >> anymore because GCC started using CFA for variable locations instead. >> >> However, clang doesn't use the CFA and instead relies on specifying when >> an epilogue has started, meaning software watchpoints get a spurious hit >> when a frame is destroyed. This patch re-adds the code to register the >> function that detects when a frame is destroyed, but only uses this when >> the producer is LLVM, so gcc code isn't affected. The logic that >> identifies the epilogue has been factored out into the new function >> amd64_stack_frame_destroyed_p_1, so the frame sniffer can call it >> directly, and its behavior isn't changed. >> >> This can also remove the XFAIL added to gdb.python/pq-watchpoint tests >> that handled this exact flaw in clang >> >> Co-Authored-By: Andrew Burgess <aburgess@redhat.com> >> --- >> gdb/amd64-tdep.c | 32 ++++++++++++++++------ >> gdb/testsuite/gdb.python/py-watchpoint.exp | 17 +----------- >> 2 files changed, 25 insertions(+), 24 deletions(-) >> >> diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c >> index e6feee677b3..2e101b4fca1 100644 >> --- a/gdb/amd64-tdep.c >> +++ b/gdb/amd64-tdep.c >> @@ -2886,6 +2886,22 @@ static const struct frame_base amd64_frame_base = >> amd64_frame_base_address >> }; >> +/* Implement core of the stack_frame_destroyed_p gdbarch method. */ >> + >> +static int >> +amd64_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc) >> +{ >> + gdb_byte insn; >> + >> + if (target_read_memory (pc, &insn, 1)) >> + return 0; /* Can't read memory at pc. */ >> + >> + if (insn != 0xc3) /* 'ret' instruction. */ >> + return 0; >> + >> + return 1; >> +} >> + >> /* Normal frames, but in a function epilogue. */ >> /* Implement the stack_frame_destroyed_p gdbarch method. >> @@ -2897,15 +2913,13 @@ static const struct frame_base >> amd64_frame_base = >> static int >> amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) >> { >> - gdb_byte insn; >> + struct compunit_symtab *cust = find_pc_compunit_symtab (pc); >> - if (target_read_memory (pc, &insn, 1)) >> - return 0; /* Can't read memory at pc. */ >> + if (cust != nullptr && cust->producer () != nullptr >> + && producer_is_llvm (cust->producer ())) >> + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); >> - if (insn != 0xc3) /* 'ret' instruction. */ >> - return 0; >> - >> - return 1; >> + return 0; >> } >> static int >> @@ -2938,7 +2952,7 @@ amd64_epilogue_frame_sniffer_1 (const struct >> frame_unwind *self, >> } >> /* Check whether we're in an epilogue. */ >> - return amd64_stack_frame_destroyed_p (gdbarch, pc); >> + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); >> } >> static int >> @@ -3310,6 +3324,8 @@ amd64_init_abi (struct gdbarch_info info, >> struct gdbarch *gdbarch, >> set_gdbarch_gen_return_address (gdbarch, >> amd64_gen_return_address); >> + set_gdbarch_stack_frame_destroyed_p (gdbarch, >> amd64_stack_frame_destroyed_p); >> + >> /* SystemTap variables and functions. */ >> set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); >> set_gdbarch_stap_register_prefixes (gdbarch, >> stap_register_prefixes); >> diff --git a/gdb/testsuite/gdb.python/py-watchpoint.exp >> b/gdb/testsuite/gdb.python/py-watchpoint.exp >> index 5ff61285979..9a6ef447572 100644 >> --- a/gdb/testsuite/gdb.python/py-watchpoint.exp >> +++ b/gdb/testsuite/gdb.python/py-watchpoint.exp >> @@ -42,20 +42,5 @@ gdb_test "source $pyfile" ".*Python script >> imported.*" \ >> "import python scripts" >> gdb_test "python print(len(gdb.breakpoints()))" "2" "check modified >> BP count" >> gdb_test "continue" ".*" "run until program stops" >> -# Clang doesn't use CFA location information for variables (despite >> generating >> -# them), meaning when the instruction "pop rbp" happens, we get a >> false hit >> -# on the watchpoint. for more details, see: >> -# https://github.com/llvm/llvm-project/issues/64390 >> -gdb_test_multiple "python print(bpt.n)" "check watchpoint hits" { >> - -re -wrap "5" { >> - pass $gdb_test_name >> - } >> - -re -wrap "6" { >> - if {[test_compiler_info "clang-*"]} { >> - xfail "$gdb_test_name (clang issue 64390)" >> - } else { >> - fail $gdb_test_name >> - } >> - } >> -} >> +gdb_test "python print(bpt.n)" "5" "check watchpoint hits" >> gdb_test "python print(len(gdb.breakpoints()))" "1" "check BP count" -- Cheers, Guinevere Larsen She/Her/Hers ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] gdb: register frame_destroyed function for amd64 gdbarch 2023-11-08 14:24 ` [PATCH v3] " Guinevere Larsen 2023-12-07 17:36 ` [PING][PATCH " Guinevere Larsen @ 2023-12-19 11:51 ` Andrew Burgess 1 sibling, 0 replies; 8+ messages in thread From: Andrew Burgess @ 2023-12-19 11:51 UTC (permalink / raw) To: Guinevere Larsen, gdb-patches; +Cc: Guinevere Larsen Guinevere Larsen <blarsen@redhat.com> writes: > gdbarches usually register functions to check when a frame is destroyed > which is used with software watchpoints, since the expression of the > watchpoint is no longer vlaid at this point. On amd64, this wasn't done > anymore because GCC started using CFA for variable locations instead. > > However, clang doesn't use the CFA and instead relies on specifying when > an epilogue has started, meaning software watchpoints get a spurious hit > when a frame is destroyed. This patch re-adds the code to register the > function that detects when a frame is destroyed, but only uses this when > the producer is LLVM, so gcc code isn't affected. The logic that > identifies the epilogue has been factored out into the new function > amd64_stack_frame_destroyed_p_1, so the frame sniffer can call it > directly, and its behavior isn't changed. > > This can also remove the XFAIL added to gdb.python/pq-watchpoint tests > that handled this exact flaw in clang Missing a '.' on the last sentence of your commit message :) Approved-By: Andrew Burgess <aburgess@redhat.com> Thanks for fixing this. Andrew > > Co-Authored-By: Andrew Burgess <aburgess@redhat.com> > --- > gdb/amd64-tdep.c | 32 ++++++++++++++++------ > gdb/testsuite/gdb.python/py-watchpoint.exp | 17 +----------- > 2 files changed, 25 insertions(+), 24 deletions(-) > > diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c > index e6feee677b3..2e101b4fca1 100644 > --- a/gdb/amd64-tdep.c > +++ b/gdb/amd64-tdep.c > @@ -2886,6 +2886,22 @@ static const struct frame_base amd64_frame_base = > amd64_frame_base_address > }; > > +/* Implement core of the stack_frame_destroyed_p gdbarch method. */ > + > +static int > +amd64_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc) > +{ > + gdb_byte insn; > + > + if (target_read_memory (pc, &insn, 1)) > + return 0; /* Can't read memory at pc. */ > + > + if (insn != 0xc3) /* 'ret' instruction. */ > + return 0; > + > + return 1; > +} > + > /* Normal frames, but in a function epilogue. */ > > /* Implement the stack_frame_destroyed_p gdbarch method. > @@ -2897,15 +2913,13 @@ static const struct frame_base amd64_frame_base = > static int > amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) > { > - gdb_byte insn; > + struct compunit_symtab *cust = find_pc_compunit_symtab (pc); > > - if (target_read_memory (pc, &insn, 1)) > - return 0; /* Can't read memory at pc. */ > + if (cust != nullptr && cust->producer () != nullptr > + && producer_is_llvm (cust->producer ())) > + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); > > - if (insn != 0xc3) /* 'ret' instruction. */ > - return 0; > - > - return 1; > + return 0; > } > > static int > @@ -2938,7 +2952,7 @@ amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self, > } > > /* Check whether we're in an epilogue. */ > - return amd64_stack_frame_destroyed_p (gdbarch, pc); > + return amd64_stack_frame_destroyed_p_1 (gdbarch, pc); > } > > static int > @@ -3310,6 +3324,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, > > set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address); > > + set_gdbarch_stack_frame_destroyed_p (gdbarch, amd64_stack_frame_destroyed_p); > + > /* SystemTap variables and functions. */ > set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes); > set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); > diff --git a/gdb/testsuite/gdb.python/py-watchpoint.exp b/gdb/testsuite/gdb.python/py-watchpoint.exp > index 5ff61285979..9a6ef447572 100644 > --- a/gdb/testsuite/gdb.python/py-watchpoint.exp > +++ b/gdb/testsuite/gdb.python/py-watchpoint.exp > @@ -42,20 +42,5 @@ gdb_test "source $pyfile" ".*Python script imported.*" \ > "import python scripts" > gdb_test "python print(len(gdb.breakpoints()))" "2" "check modified BP count" > gdb_test "continue" ".*" "run until program stops" > -# Clang doesn't use CFA location information for variables (despite generating > -# them), meaning when the instruction "pop rbp" happens, we get a false hit > -# on the watchpoint. for more details, see: > -# https://github.com/llvm/llvm-project/issues/64390 > -gdb_test_multiple "python print(bpt.n)" "check watchpoint hits" { > - -re -wrap "5" { > - pass $gdb_test_name > - } > - -re -wrap "6" { > - if {[test_compiler_info "clang-*"]} { > - xfail "$gdb_test_name (clang issue 64390)" > - } else { > - fail $gdb_test_name > - } > - } > -} > +gdb_test "python print(bpt.n)" "5" "check watchpoint hits" > gdb_test "python print(len(gdb.breakpoints()))" "1" "check BP count" > -- > 2.41.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-12-19 11:51 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-10-26 9:04 [PATCH] gdb/testsuite: Work around clang fails in gdb.base/watchpoint.exp Guinevere Larsen 2023-10-27 13:56 ` Andrew Burgess 2023-11-02 9:50 ` [PATCH v2] gdb: register frame_destroyed function for amd64 gdbarch Guinevere Larsen 2023-11-07 15:38 ` Andrew Burgess 2023-11-08 14:24 ` [PATCH v3] " Guinevere Larsen 2023-12-07 17:36 ` [PING][PATCH " Guinevere Larsen 2023-12-18 10:24 ` [PINGv2][PATCH " Guinevere Larsen 2023-12-19 11:51 ` [PATCH " Andrew Burgess
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).