116 lines
3.4 KiB
Diff
116 lines
3.4 KiB
Diff
|
http://sourceware.org/ml/gdb-patches/2012-03/msg00357.html
|
||
|
Subject: [patch 1/2] Fix gdb.cp/gdb2495.exp regression with gcc-4.7 #5
|
||
|
|
||
|
Hi,
|
||
|
|
||
|
posted as a new thread.
|
||
|
|
||
|
As described in
|
||
|
cancel: [patch] Fix gdb.cp/gdb2495.exp regression with gcc-4.7 #4 [Re: [revert] Regression on PowerPC]
|
||
|
http://sourceware.org/ml/gdb-patches/2012-03/msg00322.html
|
||
|
just ON_STACK had some regressions.
|
||
|
|
||
|
The expectations in that mail were wrong (at least that cleanup/fix is not
|
||
|
required for gdb.cp/gdb2495.exp).
|
||
|
|
||
|
The problem is that the inferior call return pad breakpoint instruction is
|
||
|
never removed even after inferior call finishes. It is even still visible in
|
||
|
"maintenance info breakpoints". This does not matter much for AT_ENTRY_POINT
|
||
|
but for ON_STACK it just corrupts stack.
|
||
|
|
||
|
No regressions on
|
||
|
{x86_64,x86_64-m32,i686}-fedora(15-rawhide)/rhel(5-6)-linux-gnu and for
|
||
|
gdbsever non-extended mode.
|
||
|
|
||
|
|
||
|
Thanks,
|
||
|
Jan
|
||
|
|
||
|
|
||
|
gdb/
|
||
|
2012-03-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
|
||
|
Remove momentary breakpoints for completed inferior calls.
|
||
|
* dummy-frame.c: Include gdbthread.h.
|
||
|
(pop_dummy_frame_bpt): New function.
|
||
|
(pop_dummy_frame): Initialie DUMMY earlier. Call pop_dummy_frame_bpt.
|
||
|
|
||
|
gdb/testsuite/
|
||
|
2012-03-09 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
|
||
|
Remove momentary breakpoints for completed inferior calls.
|
||
|
* gdb.base/call-signal-resume.exp (maintenance print dummy-frames)
|
||
|
(maintenance info breakpoints): New tests.
|
||
|
|
||
|
--- a/gdb/dummy-frame.c
|
||
|
+++ b/gdb/dummy-frame.c
|
||
|
@@ -29,6 +29,7 @@
|
||
|
#include "gdbcmd.h"
|
||
|
#include "gdb_string.h"
|
||
|
#include "observer.h"
|
||
|
+#include "gdbthread.h"
|
||
|
|
||
|
/* Dummy frame. This saves the processor state just prior to setting
|
||
|
up the inferior function call. Older targets save the registers
|
||
|
@@ -108,19 +109,36 @@ remove_dummy_frame (struct dummy_frame **dummy_ptr)
|
||
|
xfree (dummy);
|
||
|
}
|
||
|
|
||
|
+/* Delete any breakpoint B which is a momentary breakpoint for return from
|
||
|
+ inferior call matching DUMMY_VOIDP. */
|
||
|
+
|
||
|
+static int
|
||
|
+pop_dummy_frame_bpt (struct breakpoint *b, void *dummy_voidp)
|
||
|
+{
|
||
|
+ struct dummy_frame *dummy = dummy_voidp;
|
||
|
+
|
||
|
+ if (b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id)
|
||
|
+ && b->thread == pid_to_thread_id (inferior_ptid))
|
||
|
+ delete_breakpoint (b);
|
||
|
+
|
||
|
+ /* Continue the traversal. */
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
/* Pop *DUMMY_PTR, restoring program state to that before the
|
||
|
frame was created. */
|
||
|
|
||
|
static void
|
||
|
pop_dummy_frame (struct dummy_frame **dummy_ptr)
|
||
|
{
|
||
|
- struct dummy_frame *dummy;
|
||
|
+ struct dummy_frame *dummy = *dummy_ptr;
|
||
|
+
|
||
|
+ restore_infcall_suspend_state (dummy->caller_state);
|
||
|
|
||
|
- restore_infcall_suspend_state ((*dummy_ptr)->caller_state);
|
||
|
+ iterate_over_breakpoints (pop_dummy_frame_bpt, dummy);
|
||
|
|
||
|
/* restore_infcall_control_state frees inf_state,
|
||
|
all that remains is to pop *dummy_ptr. */
|
||
|
- dummy = *dummy_ptr;
|
||
|
*dummy_ptr = dummy->next;
|
||
|
xfree (dummy);
|
||
|
|
||
|
--- a/gdb/testsuite/gdb.base/call-signal-resume.exp
|
||
|
+++ b/gdb/testsuite/gdb.base/call-signal-resume.exp
|
||
|
@@ -101,6 +101,18 @@ gdb_test "frame $frame_number" ".*"
|
||
|
gdb_test_no_output "set confirm off"
|
||
|
gdb_test_no_output "return"
|
||
|
|
||
|
+# Verify there are no remains of the dummy frame.
|
||
|
+gdb_test_no_output "maintenance print dummy-frames"
|
||
|
+set test "maintenance info breakpoints"
|
||
|
+gdb_test_multiple $test $test {
|
||
|
+ -re "call dummy.*\r\n$gdb_prompt $" {
|
||
|
+ fail $test
|
||
|
+ }
|
||
|
+ -re "\r\n$gdb_prompt $" {
|
||
|
+ pass $test
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
# Resume execution, the program should continue without any signal.
|
||
|
|
||
|
gdb_test "break stop_two" "Breakpoint \[0-9\]* at .*"
|