diff options
-rw-r--r-- | gdb/arch-utils.c | 18 | ||||
-rw-r--r-- | gdb/arch-utils.h | 6 | ||||
-rw-r--r-- | gdb/infrun.c | 9 | ||||
-rw-r--r-- | gdb/symtab.c | 3 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/reread.exp | 226 |
5 files changed, 154 insertions, 108 deletions
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 2ae3413..0402eba 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -985,6 +985,24 @@ default_print_insn (bfd_vma memaddr, disassemble_info *info) return (*disassemble_fn) (memaddr, info); } +/* See arch-utils.h. */ + +CORE_ADDR +gdbarch_skip_prologue_noexcept (gdbarch *gdbarch, CORE_ADDR pc) noexcept +{ + CORE_ADDR new_pc = pc; + + TRY + { + new_pc = gdbarch_skip_prologue (gdbarch, pc); + } + CATCH (ex, RETURN_MASK_ALL) + {} + END_CATCH + + return new_pc; +} + /* -Wmissing-prototypes */ extern initialize_file_ftype _initialize_gdbarch_utils; diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 2aa9159..fa2908605 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -268,4 +268,10 @@ extern void default_guess_tracepoint_registers (struct gdbarch *gdbarch, extern int default_print_insn (bfd_vma memaddr, disassemble_info *info); +/* Wrapper to gdbarch_skip_prologue, but doesn't throw exception. Catch + exception thrown from gdbarch_skip_prologue, and return PC. */ + +extern CORE_ADDR gdbarch_skip_prologue_noexcept (gdbarch *gdbarch, + CORE_ADDR pc) noexcept; + #endif diff --git a/gdb/infrun.c b/gdb/infrun.c index a68da6a..37ff015 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -66,6 +66,7 @@ #include "common/enum-flags.h" #include "progspace-and-thread.h" #include "common/gdb_optional.h" +#include "arch-utils.h" /* Prototypes for local functions */ @@ -7317,8 +7318,8 @@ handle_step_into_function (struct gdbarch *gdbarch, cust = find_pc_compunit_symtab (stop_pc); if (cust != NULL && compunit_language (cust) != language_asm) - ecs->stop_func_start = gdbarch_skip_prologue (gdbarch, - ecs->stop_func_start); + ecs->stop_func_start + = gdbarch_skip_prologue_noexcept (gdbarch, ecs->stop_func_start); stop_func_sal = find_pc_line (ecs->stop_func_start, 0); /* Use the step_resume_break to step until the end of the prologue, @@ -7396,8 +7397,8 @@ handle_step_into_function_backward (struct gdbarch *gdbarch, cust = find_pc_compunit_symtab (stop_pc); if (cust != NULL && compunit_language (cust) != language_asm) - ecs->stop_func_start = gdbarch_skip_prologue (gdbarch, - ecs->stop_func_start); + ecs->stop_func_start + = gdbarch_skip_prologue_noexcept (gdbarch, ecs->stop_func_start); stop_func_sal = find_pc_line (stop_pc, 0); diff --git a/gdb/symtab.c b/gdb/symtab.c index d4e107a..ccf31cc 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -64,6 +64,7 @@ #include "progspace-and-thread.h" #include "common/gdb_optional.h" #include "filename-seen-cache.h" +#include "arch-utils.h" /* Forward declarations for local functions. */ @@ -3627,7 +3628,7 @@ skip_prologue_sal (struct symtab_and_line *sal) if (gdbarch_skip_entrypoint_p (gdbarch)) pc = gdbarch_skip_entrypoint (gdbarch, pc); if (skip) - pc = gdbarch_skip_prologue (gdbarch, pc); + pc = gdbarch_skip_prologue_noexcept (gdbarch, pc); /* For overlays, map pc back into its mapped VMA range. */ pc = overlay_mapped_address (pc, section); diff --git a/gdb/testsuite/gdb.base/reread.exp b/gdb/testsuite/gdb.base/reread.exp index cc0f577..4e611ce 100644 --- a/gdb/testsuite/gdb.base/reread.exp +++ b/gdb/testsuite/gdb.base/reread.exp @@ -15,111 +15,131 @@ set prototypes 1 -# build the first test case +# Build programs in PIE mode, to reproduce PR 21555. +foreach_with_prefix opts { + { "" "" } + { "-fPIE" "ldflags=-pie" } } { -set testfile1 "reread1" -set srcfile1 ${testfile1}.c -# Cygwin needs $EXEEXT. -set binfile1 [standard_output_file ${testfile1}$EXEEXT] - -if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable {debug nowarnings}] != "" } { - untested "failed to compile first testcase" - return -1 -} - -# build the second test case - -set testfile2 "reread2" -set srcfile2 ${testfile2}.c -set binfile2 [standard_output_file ${testfile2}$EXEEXT] - -if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug nowarnings}] != "" - && [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug nowarnings additional_flags=-DNO_SECTIONS}] != ""} { - untested "failed to compile second testcase" - return -1 -} - -# Start with a fresh gdb. - -set testfile "reread" -set binfile [standard_output_file ${testfile}$EXEEXT] - -gdb_start -gdb_reinitialize_dir $srcdir/$subdir - -# Load the first executable. - -gdb_rename_execfile ${binfile1} ${binfile} -gdb_load ${binfile} - -# Set a breakpoint at foo - -gdb_test "break foo" \ - "Breakpoint.*at.* file .*$srcfile1, line 14.*" \ - "breakpoint foo in first file" - - -# Run, should see "Breakpoint 1, foo () at hello1.c:14" - -gdb_run_cmd -gdb_test "" "Breakpoint.* foo .* at .*$srcfile1:14.*" "run to foo()" - -# Restore first executable to its original name, and move -# second executable into its place. Ensure that the new -# executable is at least a second newer than the old. - -gdb_rename_execfile ${binfile} ${binfile1} -gdb_rename_execfile ${binfile2} ${binfile} -gdb_test "shell sleep 1" ".*" "" -gdb_touch_execfile ${binfile} - -# Run a second time; GDB should detect that the executable has changed -# and reset the breakpoints correctly. -# Should see "Breakpoint 1, foo () at reread2.c:9" - -set test "run to foo() second time" -if [is_remote target] { - unsupported $test -} else { - gdb_run_cmd - gdb_test "" "Breakpoint.* foo .* at .*:9.*" $test -} - - -### Second pass: verify that GDB checks the executable file's -### timestamp when the program is *restarted*, not just when it exits. - -if [is_remote target] { - unsupported "second pass: GDB should check for changes before running" -} else { - - # Put the older executable back in place. - gdb_rename_execfile ${binfile} ${binfile2} - gdb_rename_execfile ${binfile1} ${binfile} - - # Restart GDB entirely. - clean_restart ${binfile} - - # Set a breakpoint on foo and run to it. - gdb_test "break foo" \ - "Breakpoint.*at.* file .*$srcfile1, line 14.*" \ - "second pass: breakpoint foo in first file" - gdb_run_cmd - gdb_test "" "Breakpoint.* foo .* at .*$srcfile1:14.*" "second pass: run to foo()" - - # This time, let the program run to completion. If GDB checks the - # executable file's timestamp now, it won't notice any change. - gdb_continue_to_end "second pass" - - # Now move the newer executable into place, and re-run. GDB - # should still notice that the executable file has changed, - # and still re-set the breakpoint appropriately. - gdb_rename_execfile ${binfile} ${binfile1} - gdb_rename_execfile ${binfile2} ${binfile} - gdb_run_cmd - gdb_test "" "Breakpoint.* foo .* at .*:9.*" "second pass: run to foo() second time" -} + # build the first test case + set testfile1 "reread1" + set srcfile1 ${testfile1}.c + # Cygwin needs $EXEEXT. + set binfile1 [standard_output_file ${testfile1}$EXEEXT] + + set testfile1_opt [list debug nowarnings \ + additional_flags=[lindex $opts 0] \ + [lindex $opts 1] ] + if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" \ + executable ${testfile1_opt}] != "" } { + untested "failed to compile first testcase" + return -1 + } + + # build the second test case + + set testfile2 "reread2" + set srcfile2 ${testfile2}.c + set binfile2 [standard_output_file ${testfile2}$EXEEXT] + + set testfile2_opt1 [list debug nowarnings \ + additional_flags=[lindex $opts 0] \ + [lindex $opts 1]] + set testfile2_op2 [list debug nowarnings \ + "additional_flags=-DNO_SECTIONS [lindex $opts 0]" \ + [lindex $opts 1]] + if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" \ + executable ${testfile2_opt1}] != "" + && [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" \ + executable ${testfile2_opt2}] != ""} { + untested "failed to compile second testcase" + return -1 + } + + # Start with a fresh gdb. + + set testfile "reread" + set binfile [standard_output_file ${testfile}$EXEEXT] + + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + + # Load the first executable. + + gdb_rename_execfile ${binfile1} ${binfile} + gdb_load ${binfile} + + # Set a breakpoint at foo + + gdb_test "break foo" \ + "Breakpoint.*at.* file .*$srcfile1, line 14.*" \ + "breakpoint foo in first file" + + + # Run, should see "Breakpoint 1, foo () at hello1.c:14" + + gdb_run_cmd + gdb_test "" "Breakpoint.* foo .* at .*$srcfile1:14.*" "run to foo()" + + # Restore first executable to its original name, and move + # second executable into its place. Ensure that the new + # executable is at least a second newer than the old. + + gdb_rename_execfile ${binfile} ${binfile1} + gdb_rename_execfile ${binfile2} ${binfile} + gdb_test "shell sleep 1" ".*" "" + gdb_touch_execfile ${binfile} + + # Run a second time; GDB should detect that the executable has changed + # and reset the breakpoints correctly. + # Should see "Breakpoint 1, foo () at reread2.c:9" + + set test "run to foo() second time" + if [is_remote target] { + unsupported $test + } else { + gdb_run_cmd + gdb_test "" "Breakpoint.* foo .* at .*:9.*" $test + } + + + ### Second pass: verify that GDB checks the executable file's + ### timestamp when the program is *restarted*, not just when it exits. + + if [is_remote target] { + unsupported "second pass: GDB should check for changes before running" + } else { + + # Put the older executable back in place. + gdb_rename_execfile ${binfile} ${binfile2} + gdb_rename_execfile ${binfile1} ${binfile} + + # Restart GDB entirely. + clean_restart ${binfile} + + # Set a breakpoint on foo and run to it. + gdb_test "break foo" \ + "Breakpoint.*at.* file .*$srcfile1, line 14.*" \ + "second pass: breakpoint foo in first file" + gdb_run_cmd + gdb_test "" "Breakpoint.* foo .* at .*$srcfile1:14.*" \ + "second pass: run to foo()" + + # This time, let the program run to completion. If GDB checks the + # executable file's timestamp now, it won't notice any change. + gdb_continue_to_end "second pass" + + # Now move the newer executable into place, and re-run. GDB + # should still notice that the executable file has changed, + # and still re-set the breakpoint appropriately. + gdb_rename_execfile ${binfile} ${binfile1} + gdb_rename_execfile ${binfile2} ${binfile} + gdb_run_cmd + gdb_test "" "Breakpoint.* foo .* at .*:9.*" \ + "second pass: run to foo() second time" + } + + } # End of tests. return 0 |