This commit is contained in:
committed by
Git OBS Bridge
parent
58512d16aa
commit
37f0f3cc41
677
gdb-6.8-inlining-addon.patch
Normal file
677
gdb-6.8-inlining-addon.patch
Normal file
@@ -0,0 +1,677 @@
|
||||
infcall.c <unwind_on_signal_p>:
|
||||
Revert the change of: gdb-6.8-inlining.patch
|
||||
causing: FAIL: gdb.base/unwindonsignal.exp: unwindonsignal, stack unwound
|
||||
|
||||
resume() -> target_resume() move of clear_inline_frame_state() is for:
|
||||
gdb.mi/mi-nsmoribund.exp
|
||||
|
||||
Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-bt.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-bt.c 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-bt.c 2009-02-09 13:28:49.000000000 +0100
|
||||
@@ -13,10 +13,16 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
-int x, y;
|
||||
+/* VOLATILE forces all the inlining to happen as otherwise the whole program
|
||||
+ gets optimized by CSE to just simple assignments of the results. */
|
||||
+volatile int x, y;
|
||||
volatile int result;
|
||||
|
||||
-void bar(void);
|
||||
+inline void bar(void)
|
||||
+{
|
||||
+ x += y; /* set breakpoint 1 here */
|
||||
+}
|
||||
+
|
||||
|
||||
inline int func1(void)
|
||||
{
|
||||
Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-bt.exp
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-bt.exp 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-bt.exp 2009-02-09 13:28:49.000000000 +0100
|
||||
@@ -41,18 +41,19 @@ if { [skip_inline_frame_tests] } {
|
||||
return
|
||||
}
|
||||
|
||||
-set line1 [gdb_get_line_number "set breakpoint 1 here" ${fullsrcfile2}]
|
||||
-gdb_breakpoint $srcfile2:$line1
|
||||
+set line1 [gdb_get_line_number "set breakpoint 1 here" ${srcfile}]
|
||||
+gdb_breakpoint $srcfile:$line1
|
||||
|
||||
gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)"
|
||||
gdb_test "backtrace" "#0 bar.*#1 .*main.*" "backtrace from bar (1)"
|
||||
-gdb_test "info frame" ".*called by frame.*" "bar not inlined"
|
||||
+gdb_test "info frame" ".*inlined into frame.*" "bar inlined"
|
||||
|
||||
-gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (2)"
|
||||
-gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*main.*" \
|
||||
- "backtrace from bar (2)"
|
||||
-gdb_test "up" "#1 .*func1.*" "up from bar (2)"
|
||||
-gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (2)"
|
||||
+# gcc-4.3.1 omits the line number information for (2).
|
||||
+#gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (2)"
|
||||
+#gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*main.*" \
|
||||
+# "backtrace from bar (2)"
|
||||
+#gdb_test "up" "#1 .*func1.*" "up from bar (2)"
|
||||
+#gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (2)"
|
||||
|
||||
gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (3)"
|
||||
gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*func2.*#3 .*main.*" \
|
||||
Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-cmds.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-cmds.c 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-cmds.c 2009-02-09 13:28:49.000000000 +0100
|
||||
@@ -13,13 +13,19 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
-int x, y;
|
||||
+/* VOLATILE forces all the inlining to happen as otherwise the whole program
|
||||
+ gets optimized by CSE to just simple assignments of the results. */
|
||||
+volatile int x, y;
|
||||
volatile int result;
|
||||
|
||||
-void bar(void);
|
||||
void marker(void);
|
||||
void noinline(void);
|
||||
|
||||
+inline void bar(void)
|
||||
+{
|
||||
+ x += y; /* set breakpoint 1 here */
|
||||
+}
|
||||
+
|
||||
inline int func1(void)
|
||||
{
|
||||
bar ();
|
||||
Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-cmds.exp
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-cmds.exp 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-cmds.exp 2009-02-09 13:30:16.000000000 +0100
|
||||
@@ -45,28 +45,28 @@ if { [skip_inline_frame_tests] } {
|
||||
|
||||
# First, check that the things we expected to be inlined really were,
|
||||
# and those that shouldn't be weren't.
|
||||
-set line1 [gdb_get_line_number "set breakpoint 1 here" ${fullsrcfile2}]
|
||||
+set line1 [gdb_get_line_number "set breakpoint 1 here" ${srcfile2}]
|
||||
gdb_breakpoint $srcfile2:$line1
|
||||
-set line2 [gdb_get_line_number "set breakpoint 2 here" ${fullsrcfile2}]
|
||||
+set line2 [gdb_get_line_number "set breakpoint 2 here" ${srcfile2}]
|
||||
gdb_breakpoint $srcfile2:$line2
|
||||
|
||||
-gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)"
|
||||
+gdb_test "continue" "set breakpoint 1 here.*" "continue to bar (1)"
|
||||
gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*main.*" \
|
||||
"backtrace from bar (1)"
|
||||
gdb_test "up" "#1 .*func1.*" "up from bar (1)"
|
||||
-gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (1)"
|
||||
+gdb_test "info frame" "inlined into frame.*" "func1 inlined (1)"
|
||||
|
||||
-gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (2)"
|
||||
+gdb_test "continue" "set breakpoint 1 here.*" "continue to bar (2)"
|
||||
gdb_test "backtrace" "#0 bar.*#1 .*func1.*#2 .*func2.*#3 .*main.*" \
|
||||
"backtrace from bar (2)"
|
||||
gdb_test "up" "#1 .*func1.*" "up from bar (2)"
|
||||
-gdb_test "info frame" ".*inlined into frame.*" "func1 inlined (2)"
|
||||
+gdb_test "info frame" "inlined into frame.*" "func1 inlined (2)"
|
||||
gdb_test "up" "#2 .*func2.*" "up from func1 (2)"
|
||||
-gdb_test "info frame" ".*inlined into frame.*" "func2 inlined (2)"
|
||||
+gdb_test "info frame" "inlined into frame.*" "func2 inlined (2)"
|
||||
|
||||
-gdb_test "continue" ".*set breakpoint 2 here.*" "continue to marker"
|
||||
+gdb_test "continue" "set breakpoint 2 here.*" "continue to marker"
|
||||
gdb_test "backtrace" "#0 marker.*#1 .*main.*" "backtrace from marker"
|
||||
-gdb_test "info frame" ".*called by frame.*" "marker not inlined"
|
||||
+gdb_test "info frame" "\n called by frame.*" "marker not inlined"
|
||||
|
||||
# Next, check that we can next over inlined functions. We should not end up
|
||||
# inside any of them.
|
||||
@@ -201,7 +201,7 @@ set line3 [gdb_get_line_number "set brea
|
||||
gdb_breakpoint $line3
|
||||
gdb_continue_to_breakpoint "consecutive func1"
|
||||
|
||||
-gdb_test "next" ".*func1 .*first call.*" "next to first func1"
|
||||
+gdb_test "next" "func1 .*first call.*" "next to first func1"
|
||||
set msg "next to second func1"
|
||||
gdb_test_multiple "next" $msg {
|
||||
-re ".*func1 .*second call.*$gdb_prompt $" {
|
||||
@@ -224,16 +224,16 @@ set line4 [gdb_get_line_number "set brea
|
||||
gdb_breakpoint $line4
|
||||
gdb_continue_to_breakpoint "func1 then func3"
|
||||
|
||||
-gdb_test "next" ".*func1 \\\(\\\);" "next to func1 before func3"
|
||||
-gdb_test "next" ".*func3 \\\(\\\);" "next to func3"
|
||||
+gdb_test "next" "func1 \\\(\\\);" "next to func1 before func3"
|
||||
+gdb_test "next" "func3 \\\(\\\);" "next to func3"
|
||||
|
||||
# Test finishing out of one thing and into another.
|
||||
set line5 [gdb_get_line_number "set breakpoint 5 here"]
|
||||
gdb_breakpoint $line5
|
||||
gdb_continue_to_breakpoint "finish into func1"
|
||||
|
||||
-gdb_test "next" ".*marker \\\(\\\);" "next to finish marker"
|
||||
-gdb_test "step" ".*set breakpoint 2 here.*" "step into finish marker"
|
||||
+gdb_test "next" "marker \\\(\\\);" "next to finish marker"
|
||||
+gdb_test "step" "set breakpoint 2 here.*" "step into finish marker"
|
||||
gdb_test "finish" "func1 \\\(\\\);" "finish from marker to func1"
|
||||
|
||||
gdb_test "step" "bar \\\(\\\);" "step into func1 for finish"
|
||||
@@ -268,12 +268,12 @@ gdb_test "step" "noinline \\\(\\\) at .*
|
||||
gdb_test "bt" "#0 noinline.*#1 .*outer_inline1.*#2 .*outer_inline2.*#3 main.*" "backtrace at noinline from outer_inline1"
|
||||
gdb_test "step" "inlined_fn \\\(\\\) at .*" "enter inlined_fn from noinline"
|
||||
gdb_test "bt" "#0 inlined_fn.*#1 noinline.*#2 .*outer_inline1.*#3 .*outer_inline2.*#4 main.*" "backtrace at inlined_fn from noinline"
|
||||
-gdb_test "info frame" ".*inlined into frame.*" "inlined_fn from noinline inlined"
|
||||
-gdb_test "up" "#1 noinline.*" "up to noinline"
|
||||
-gdb_test "info frame" ".*\n called by frame.*" "noinline from outer_inline1 not inlined"
|
||||
-gdb_test "up" "#2 .*outer_inline1.*" "up to outer_inline1"
|
||||
-gdb_test "info frame" ".*inlined into frame.*" "outer_inline1 inlined"
|
||||
-gdb_test "up" "#3 .*outer_inline2.*" "up to outer_inline2"
|
||||
-gdb_test "info frame" ".*inlined into frame.*" "outer_inline2 inlined"
|
||||
-gdb_test "up" "#4 main.*" "up from outer_inline2"
|
||||
-gdb_test "info frame" ".*\n caller of frame.*" "main not inlined"
|
||||
+gdb_test "info frame" "inlined into frame.*" "inlined_fn from noinline inlined"
|
||||
+gdb_test "fini" "" "up to noinline"
|
||||
+gdb_test "info frame" "\n called by frame.*" "noinline from outer_inline1 not inlined"
|
||||
+gdb_test "fini" "" "up to outer_inline1"
|
||||
+gdb_test "info frame" "inlined into frame.*" "outer_inline1 inlined"
|
||||
+gdb_test "fini" "" "up to outer_inline2"
|
||||
+gdb_test "info frame" "inlined into frame.*" "outer_inline2 inlined"
|
||||
+gdb_test "fini" "" "up from outer_inline2"
|
||||
+gdb_test "info frame" " in main \[^\n\]*\n source language.*" "main not inlined"
|
||||
Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-locals.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-locals.c 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-locals.c 2009-02-09 13:28:49.000000000 +0100
|
||||
@@ -13,11 +13,16 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
-int x, y;
|
||||
+/* VOLATILE forces all the inlining to happen as otherwise the whole program
|
||||
+ gets optimized by CSE to just simple assignments of the results. */
|
||||
+volatile int x, y;
|
||||
volatile int result;
|
||||
volatile int *array_p;
|
||||
|
||||
-void bar(void);
|
||||
+inline void bar(void)
|
||||
+{
|
||||
+ x += y; /* set breakpoint 1 here */
|
||||
+}
|
||||
|
||||
inline int func1(int arg1)
|
||||
{
|
||||
Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-locals.exp
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-locals.exp 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-locals.exp 2009-02-09 13:28:49.000000000 +0100
|
||||
@@ -43,8 +43,8 @@ if { [skip_inline_var_tests] } {
|
||||
|
||||
set no_frames [skip_inline_frame_tests]
|
||||
|
||||
-set line1 [gdb_get_line_number "set breakpoint 1 here" ${fullsrcfile2}]
|
||||
-gdb_breakpoint $srcfile2:$line1
|
||||
+set line1 [gdb_get_line_number "set breakpoint 1 here" ${srcfile}]
|
||||
+gdb_breakpoint $srcfile:$line1
|
||||
|
||||
gdb_test "continue" ".*set breakpoint 1 here.*" "continue to bar (1)"
|
||||
|
||||
@@ -77,6 +77,9 @@ if { ! $no_frames } {
|
||||
|
||||
# Make sure that locals on the stack are found. This is an array to
|
||||
# prevent it from living in a register.
|
||||
+if [test_compiler_info "gcc-4-3-*"] {
|
||||
+ setup_kfail *-*-* "gcc/debug.optimization"
|
||||
+}
|
||||
gdb_test "print array\[0\]" "\\\$$decimal = 0" "print local (2)"
|
||||
|
||||
if { ! $no_frames } {
|
||||
@@ -115,4 +118,7 @@ if { ! $no_frames } {
|
||||
gdb_test "info locals" ".*arg2 = 184.*" "info locals above bar (3b)"
|
||||
}
|
||||
|
||||
+if [test_compiler_info "gcc-4-3-*"] {
|
||||
+ setup_kfail *-*-* "gcc/debug.optimization"
|
||||
+}
|
||||
gdb_test "print array\[0\]" "\\\$$decimal = 184" "print local (3)"
|
||||
Index: gdb-6.8.50.20081214/gdb/frame.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/frame.c 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/frame.c 2009-02-09 13:30:16.000000000 +0100
|
||||
@@ -269,7 +269,7 @@ fprint_frame (struct ui_file *file, stru
|
||||
static struct frame_info *
|
||||
skip_inlined_frames (struct frame_info *frame)
|
||||
{
|
||||
- while (get_frame_type (frame) == INLINE_FRAME)
|
||||
+ while (frame && get_frame_type (frame) == INLINE_FRAME)
|
||||
frame = get_prev_frame (frame);
|
||||
|
||||
return frame;
|
||||
@@ -1697,6 +1697,7 @@ get_frame_address_in_block (struct frame
|
||||
{
|
||||
/* A draft address. */
|
||||
CORE_ADDR pc = get_frame_pc (this_frame);
|
||||
+ struct thread_info *tp = inferior_thread ();
|
||||
|
||||
struct frame_info *next_frame = this_frame->next;
|
||||
|
||||
@@ -1739,6 +1740,9 @@ get_frame_address_in_block (struct frame
|
||||
while in an inlined function, then the code address of the
|
||||
"calling" normal function should not be adjusted either. */
|
||||
|
||||
+ if (tp->current_pc_is_notcurrent)
|
||||
+ return pc - 1;
|
||||
+
|
||||
while (get_frame_type (next_frame) == INLINE_FRAME)
|
||||
next_frame = next_frame->next;
|
||||
|
||||
@@ -1770,7 +1774,7 @@ find_frame_sal (struct frame_info *frame
|
||||
sym = inline_skipped_symbol (inferior_ptid);
|
||||
|
||||
init_sal (sal);
|
||||
- if (SYMBOL_LINE (sym) != 0)
|
||||
+ if (sym != NULL && SYMBOL_LINE (sym) != 0)
|
||||
{
|
||||
sal->symtab = SYMBOL_SYMTAB (sym);
|
||||
sal->line = SYMBOL_LINE (sym);
|
||||
Index: gdb-6.8.50.20081214/gdb/breakpoint.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/breakpoint.c 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/breakpoint.c 2009-02-09 13:30:16.000000000 +0100
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "top.h"
|
||||
#include "wrapper.h"
|
||||
#include "valprint.h"
|
||||
+#include "inline-frame.h"
|
||||
|
||||
#include "mi/mi-common.h"
|
||||
|
||||
@@ -2833,10 +2834,24 @@ bpstat_check_breakpoint_conditions (bpst
|
||||
const struct bp_location *bl = bs->breakpoint_at;
|
||||
struct breakpoint *b = bl->owner;
|
||||
|
||||
- if (frame_id_p (b->frame_id)
|
||||
- && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ())))
|
||||
- bs->stop = 0;
|
||||
- else if (bs->stop)
|
||||
+ if (frame_id_p (b->frame_id))
|
||||
+ {
|
||||
+ struct frame_info *b_frame, *frame;
|
||||
+ struct frame_id b_frame_id, current_frame_id;
|
||||
+
|
||||
+ b_frame = frame_find_by_id (b->frame_id);
|
||||
+
|
||||
+ /* get_stack_frame_id normalizes the id to the real non-inlined function
|
||||
+ by skip_inlined_frames. */
|
||||
+ b_frame_id = get_stack_frame_id (b_frame);
|
||||
+ current_frame_id = get_stack_frame_id (get_current_frame ());
|
||||
+
|
||||
+ /* Completely different (inlining notwithstanding) frames? */
|
||||
+ if (!frame_id_eq (b_frame_id, current_frame_id))
|
||||
+ bs->stop = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (bs->stop)
|
||||
{
|
||||
int value_is_zero = 0;
|
||||
|
||||
@@ -2975,6 +2990,12 @@ bpstat_stop_status (CORE_ADDR bp_addr, p
|
||||
bs->print = 0;
|
||||
}
|
||||
bs->commands = copy_command_lines (bs->commands);
|
||||
+
|
||||
+ /* Display the innermost inlined frame at a breakpont as it gives to
|
||||
+ most of the available information. */
|
||||
+ if (b->type != bp_until && b->type != bp_finish)
|
||||
+ while (inline_skipped_frames (ptid))
|
||||
+ step_into_inline_frame (ptid);
|
||||
}
|
||||
|
||||
/* Print nothing for this entry if we dont stop or if we dont print. */
|
||||
@@ -4826,9 +4847,9 @@ set_momentary_breakpoint (struct symtab_
|
||||
{
|
||||
struct breakpoint *b;
|
||||
|
||||
- /* If FRAME_ID is valid, it should be a real frame, not an inlined
|
||||
- one. */
|
||||
- gdb_assert (!frame_id_inlined_p (frame_id));
|
||||
+ /* We can be returning even into an inline frame. While finish_command will
|
||||
+ shortcut the case of returning _from_ an inline frame we still may be
|
||||
+ returning from non-inlined frame _to_ an inlined frame. */
|
||||
|
||||
b = set_raw_breakpoint (sal, type);
|
||||
b->enable_state = bp_enabled;
|
||||
Index: gdb-6.8.50.20081214/gdb/inline-frame.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/inline-frame.c 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/inline-frame.c 2009-02-09 13:30:16.000000000 +0100
|
||||
@@ -183,6 +183,12 @@ inline_frame_sniffer (const struct frame
|
||||
if (frame_block == NULL)
|
||||
return 0;
|
||||
|
||||
+ /* For >=2 inlined functions SKIPPED_SYMBOL needs to be different after each
|
||||
+ step_into_inline_frame call. But skip_inline_frames is called only once
|
||||
+ and thus SKIPPED_SYMBOL needs to be calculated by INLINE_FRAME_SNIFFER. */
|
||||
+ if (state)
|
||||
+ state->skipped_symbol = NULL;
|
||||
+
|
||||
/* Calculate DEPTH, the number of inlined functions at this
|
||||
location. */
|
||||
depth = 0;
|
||||
@@ -192,6 +198,10 @@ inline_frame_sniffer (const struct frame
|
||||
if (block_inlined_p (cur_block))
|
||||
depth++;
|
||||
|
||||
+ if (state && depth == state->skipped_frames
|
||||
+ && state->skipped_symbol == NULL)
|
||||
+ state->skipped_symbol = BLOCK_FUNCTION (cur_block);
|
||||
+
|
||||
cur_block = BLOCK_SUPERBLOCK (cur_block);
|
||||
}
|
||||
|
||||
@@ -275,7 +285,6 @@ skip_inline_frames (ptid_t ptid)
|
||||
{
|
||||
CORE_ADDR this_pc;
|
||||
struct block *frame_block, *cur_block;
|
||||
- struct symbol *last_sym = NULL;
|
||||
int skip_count = 0;
|
||||
struct inline_state *state;
|
||||
|
||||
@@ -296,10 +305,7 @@ skip_inline_frames (ptid_t ptid)
|
||||
of BLOCK_START. */
|
||||
if (BLOCK_START (cur_block) == this_pc
|
||||
|| block_starting_point_at (this_pc, cur_block))
|
||||
- {
|
||||
- skip_count++;
|
||||
- last_sym = BLOCK_FUNCTION (cur_block);
|
||||
- }
|
||||
+ skip_count++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -311,7 +317,6 @@ skip_inline_frames (ptid_t ptid)
|
||||
state = allocate_inline_frame_state (ptid);
|
||||
state->skipped_frames = skip_count;
|
||||
state->saved_pc = this_pc;
|
||||
- state->skipped_symbol = last_sym;
|
||||
|
||||
if (skip_count != 0)
|
||||
reinit_frame_cache ();
|
||||
@@ -329,6 +334,23 @@ step_into_inline_frame (ptid_t ptid)
|
||||
reinit_frame_cache ();
|
||||
}
|
||||
|
||||
+/* Step out of an inlined function by hiding it. */
|
||||
+
|
||||
+void
|
||||
+step_out_of_inline_frame (ptid_t ptid)
|
||||
+{
|
||||
+ struct inline_state *state = find_inline_frame_state (ptid);
|
||||
+
|
||||
+ gdb_assert (state != NULL);
|
||||
+
|
||||
+ /* Simulate the caller adjustment. */
|
||||
+ if (state->skipped_frames == 0)
|
||||
+ state->saved_pc--;
|
||||
+
|
||||
+ state->skipped_frames++;
|
||||
+ reinit_frame_cache ();
|
||||
+}
|
||||
+
|
||||
/* Return the number of hidden functions inlined into the current
|
||||
frame. */
|
||||
|
||||
Index: gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-markers.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/testsuite/gdb.opt/inline-markers.c 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/testsuite/gdb.opt/inline-markers.c 2009-02-09 13:28:49.000000000 +0100
|
||||
@@ -15,11 +15,6 @@
|
||||
|
||||
extern int x, y;
|
||||
|
||||
-void bar(void)
|
||||
-{
|
||||
- x += y; /* set breakpoint 1 here */
|
||||
-}
|
||||
-
|
||||
void marker(void)
|
||||
{
|
||||
x += y; /* set breakpoint 2 here */
|
||||
Index: gdb-6.8.50.20081214/gdb/gdbthread.h
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/gdbthread.h 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/gdbthread.h 2009-02-09 13:30:16.000000000 +0100
|
||||
@@ -180,6 +180,12 @@ struct thread_info
|
||||
|
||||
/* Private data used by the target vector implementation. */
|
||||
struct private_thread_info *private;
|
||||
+
|
||||
+ /* Nonzero if the current frame PC should be unwound as the caller. It is
|
||||
+ used to keep the backtrace upper levels existing after finish_command into
|
||||
+ an inlined frame if the current inlined function/block was ending at the
|
||||
+ current PC. */
|
||||
+ int current_pc_is_notcurrent;
|
||||
};
|
||||
|
||||
/* Create an empty thread list, or empty the existing one. */
|
||||
Index: gdb-6.8.50.20081214/gdb/infcmd.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/infcmd.c 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/infcmd.c 2009-02-09 13:30:16.000000000 +0100
|
||||
@@ -1373,11 +1373,11 @@ finish_command_continuation (void *arg)
|
||||
struct type *value_type;
|
||||
|
||||
value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function));
|
||||
- if (!value_type)
|
||||
+ if (!SYMBOL_INLINED (a->function) && !value_type)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("finish_command: function has no target type"));
|
||||
|
||||
- if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
|
||||
+ if (value_type && TYPE_CODE (value_type) != TYPE_CODE_VOID)
|
||||
print_return_value (SYMBOL_TYPE (a->function), value_type);
|
||||
}
|
||||
|
||||
@@ -1481,6 +1481,16 @@ finish_forward (struct symbol *function,
|
||||
|
||||
old_chain = make_cleanup_delete_breakpoint (breakpoint);
|
||||
|
||||
+ /* We should _always_ set CURRENT_PC_IS_NOTCURRENT here to always see the
|
||||
+ calling line with the message `Value returned is ...'. Currently it is
|
||||
+ seen only if at least one instruction is on that source line after the
|
||||
+ call instruction. We would also need to hook step_once and only clear
|
||||
+ CURRENT_PC_IS_NOTCURRENT on the first step. But it would be a change of
|
||||
+ general non-inlining behavior against upstream. */
|
||||
+
|
||||
+ if (get_frame_type (frame) == INLINE_FRAME)
|
||||
+ tp->current_pc_is_notcurrent = 1;
|
||||
+
|
||||
tp->proceed_to_finish = 1; /* We want stop_registers, please... */
|
||||
make_cleanup_restore_integer (&suppress_stop_observer);
|
||||
suppress_stop_observer = 1;
|
||||
@@ -1504,7 +1514,9 @@ finish_forward (struct symbol *function,
|
||||
static void
|
||||
finish_command (char *arg, int from_tty)
|
||||
{
|
||||
- struct frame_info *frame;
|
||||
+ /* FIXME: Rename `current_frame' to `frame' upon a merge. */
|
||||
+ struct frame_info *current_frame, *prev_frame;
|
||||
+ CORE_ADDR frame_pc;
|
||||
struct symbol *function;
|
||||
|
||||
int async_exec = 0;
|
||||
@@ -1535,46 +1547,63 @@ finish_command (char *arg, int from_tty)
|
||||
if (!target_has_execution)
|
||||
error (_("The program is not running."));
|
||||
|
||||
- frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
|
||||
- if (frame == 0)
|
||||
+ current_frame = get_selected_frame (_("No selected frame."));
|
||||
+ frame_pc = get_frame_pc (current_frame);
|
||||
+ prev_frame = get_prev_frame (current_frame);
|
||||
+ if (prev_frame == 0)
|
||||
error (_("\"finish\" not meaningful in the outermost frame."));
|
||||
|
||||
- clear_proceed_status ();
|
||||
-
|
||||
/* Finishing from an inline frame is completely different. We don't
|
||||
try to show the "return value" - no way to locate it. So we do
|
||||
not need a completion. */
|
||||
- if (get_frame_type (get_selected_frame (_("No selected frame.")))
|
||||
- == INLINE_FRAME)
|
||||
+ if (get_frame_type (current_frame) == INLINE_FRAME)
|
||||
{
|
||||
struct thread_info *tp = inferior_thread ();
|
||||
-
|
||||
- /* Claim we are stepping in the calling frame. An empty step
|
||||
- range means that we will stop once we aren't in a function
|
||||
- called by that frame. We don't use the magic "1" value for
|
||||
- step_range_end, because then infrun will think this is nexti,
|
||||
- and not step over the rest of this inlined function call. */
|
||||
struct symtab_and_line empty_sal;
|
||||
- init_sal (&empty_sal);
|
||||
- set_step_info (tp, frame, empty_sal);
|
||||
- tp->step_range_start = tp->step_range_end = get_frame_pc (frame);
|
||||
- tp->step_over_calls = STEP_OVER_ALL;
|
||||
+ struct block *frame_block;
|
||||
|
||||
/* Print info on the selected frame, including level number but not
|
||||
source. */
|
||||
if (from_tty)
|
||||
{
|
||||
printf_filtered (_("Run till exit from "));
|
||||
- print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
|
||||
+ print_stack_frame (current_frame, 1, LOCATION);
|
||||
}
|
||||
|
||||
+ /* Even just a single stepi would get us out of the caller function PC
|
||||
+ range. */
|
||||
+
|
||||
+ frame_block = get_frame_block (current_frame, NULL);
|
||||
+
|
||||
+ /* FRAME_BLOCK must be initialized and also the frame printing above must
|
||||
+ be done still with the original CURRENT_PC_IS_NOTCURRENT setting. */
|
||||
+ clear_proceed_status ();
|
||||
+
|
||||
+ if (frame_block && BLOCK_END (frame_block) == frame_pc)
|
||||
+ {
|
||||
+ step_out_of_inline_frame (tp->ptid);
|
||||
+ tp->current_pc_is_notcurrent = 1;
|
||||
+ normal_stop ();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Claim we are stepping in the calling frame. An empty step
|
||||
+ range means that we will stop once we aren't in a function
|
||||
+ called by that frame. We don't use the magic "1" value for
|
||||
+ step_range_end, because then infrun will think this is nexti,
|
||||
+ and not step over the rest of this inlined function call. */
|
||||
+ init_sal (&empty_sal);
|
||||
+ set_step_info (tp, prev_frame, empty_sal);
|
||||
+ tp->step_range_start = tp->step_range_end = get_frame_pc (prev_frame);
|
||||
+ tp->step_over_calls = STEP_OVER_ALL;
|
||||
+
|
||||
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the function we will return from. */
|
||||
|
||||
- function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
|
||||
+ function = find_pc_function (frame_pc);
|
||||
|
||||
/* Print info on the selected frame, including level number but not
|
||||
source. */
|
||||
@@ -1588,10 +1617,14 @@ finish_command (char *arg, int from_tty)
|
||||
print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
|
||||
}
|
||||
|
||||
+ /* Frames printing above must be done still with the original
|
||||
+ CURRENT_PC_IS_NOTCURRENT setting. */
|
||||
+ clear_proceed_status ();
|
||||
+
|
||||
if (execution_direction == EXEC_REVERSE)
|
||||
finish_backward (function);
|
||||
else
|
||||
- finish_forward (function, frame);
|
||||
+ finish_forward (function, prev_frame);
|
||||
}
|
||||
|
||||
|
||||
Index: gdb-6.8.50.20081214/gdb/infrun.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/infrun.c 2009-02-09 13:29:51.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/infrun.c 2009-02-09 13:30:16.000000000 +0100
|
||||
@@ -1147,8 +1150,6 @@ a command like `return' or `jump' to con
|
||||
step = 0;
|
||||
}
|
||||
|
||||
- clear_inline_frame_state (resume_ptid);
|
||||
-
|
||||
if (debug_displaced
|
||||
&& use_displaced_stepping (gdbarch)
|
||||
&& tp->trap_expected)
|
||||
@@ -1201,6 +1201,8 @@ clear_proceed_status_thread (struct thre
|
||||
|
||||
/* Discard any remaining commands or status from previous stop. */
|
||||
bpstat_clear (&tp->stop_bpstat);
|
||||
+
|
||||
+ tp->current_pc_is_notcurrent = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
--- ./gdb/target.c 2009-02-10 23:45:59.000000000 +0100
|
||||
+++ ./gdb/target.c 2009-02-10 23:43:29.000000000 +0100
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "target-descriptions.h"
|
||||
#include "gdbthread.h"
|
||||
#include "solib.h"
|
||||
+#include "inline-frame.h"
|
||||
|
||||
static void target_info (char *, int);
|
||||
|
||||
@@ -1938,6 +1939,7 @@ target_pid_to_str (ptid_t ptid)
|
||||
void
|
||||
target_resume (ptid_t ptid, int step, enum target_signal signal)
|
||||
{
|
||||
+ clear_inline_frame_state (ptid);
|
||||
dcache_invalidate (target_dcache);
|
||||
(*current_target.to_resume) (ptid, step, signal);
|
||||
set_executing (ptid, 1);
|
||||
Index: gdb-6.8.50.20081214/gdb/inline-frame.h
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081214.orig/gdb/inline-frame.h 2009-02-09 13:28:48.000000000 +0100
|
||||
+++ gdb-6.8.50.20081214/gdb/inline-frame.h 2009-02-09 13:30:16.000000000 +0100
|
||||
@@ -43,6 +43,10 @@ void clear_inline_frame_state (ptid_t pt
|
||||
|
||||
void step_into_inline_frame (ptid_t ptid);
|
||||
|
||||
+/* Step out of an inlined function by hiding it. */
|
||||
+
|
||||
+void step_out_of_inline_frame (ptid_t ptid);
|
||||
+
|
||||
/* Return the number of hidden functions inlined into the current
|
||||
frame. */
|
||||
|
||||
--- gdb-6.8.50.20090209/gdb/infcall.c 2009-02-10 00:16:10.000000000 +0100
|
||||
+++ gdb-6.8.50.20090209/gdb/infcall.c-removed 2009-02-10 00:15:58.000000000 +0100
|
||||
@@ -841,8 +841,15 @@ When the function is done executing, GDB
|
||||
|
||||
if (unwind_on_signal_p)
|
||||
{
|
||||
- /* The user wants the context restored. Calling error will
|
||||
- run inf_status_cleanup, which does all the work. */
|
||||
+ /* The user wants the context restored. */
|
||||
+
|
||||
+ /* We must get back to the frame we were before the
|
||||
+ dummy call. */
|
||||
+ dummy_frame_pop (dummy_id);
|
||||
+
|
||||
+ /* We also need to restore inferior status to that before the
|
||||
+ dummy call. */
|
||||
+ restore_inferior_status (inf_status);
|
||||
|
||||
/* FIXME: Insert a bunch of wrap_here; name can be very
|
||||
long if it's a C++ name with arguments and stuff. */
|
104
gdb-6.8-inlining-by-name.patch
Normal file
104
gdb-6.8-inlining-by-name.patch
Normal file
@@ -0,0 +1,104 @@
|
||||
Implement `b <funcname>' for <funcname> with concete inlined instances by
|
||||
a multiple-PC breakpoint.
|
||||
|
||||
Index: gdb-6.8.50.20081128/gdb/ada-lang.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081128.orig/gdb/ada-lang.c 2008-11-25 00:21:15.000000000 +0100
|
||||
+++ gdb-6.8.50.20081128/gdb/ada-lang.c 2008-12-06 21:39:56.000000000 +0100
|
||||
@@ -4614,7 +4614,7 @@ remove_irrelevant_renamings (struct ada_
|
||||
if (current_block == NULL)
|
||||
return nsyms;
|
||||
|
||||
- current_function = block_linkage_function (current_block);
|
||||
+ current_function = block_function (current_block);
|
||||
if (current_function == NULL)
|
||||
return nsyms;
|
||||
|
||||
@@ -6625,7 +6625,7 @@ ada_find_renaming_symbol (const char *na
|
||||
static struct symbol *
|
||||
find_old_style_renaming_symbol (const char *name, struct block *block)
|
||||
{
|
||||
- const struct symbol *function_sym = block_linkage_function (block);
|
||||
+ const struct symbol *function_sym = block_function (block);
|
||||
char *rename;
|
||||
|
||||
if (function_sym != NULL)
|
||||
Index: gdb-6.8.50.20081128/gdb/block.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081128.orig/gdb/block.c 2008-12-06 14:06:16.000000000 +0100
|
||||
+++ gdb-6.8.50.20081128/gdb/block.c 2008-12-06 21:40:29.000000000 +0100
|
||||
@@ -75,6 +75,19 @@ block_linkage_function (const struct blo
|
||||
return BLOCK_FUNCTION (bl);
|
||||
}
|
||||
|
||||
+/* Return the symbol for the function which contains a specified
|
||||
+ lexical block, described by a struct block BL. Inlined functions
|
||||
+ can be returned. */
|
||||
+
|
||||
+struct symbol *
|
||||
+block_function (const struct block *bl)
|
||||
+{
|
||||
+ while (BLOCK_FUNCTION (bl) == NULL && BLOCK_SUPERBLOCK (bl) != NULL)
|
||||
+ bl = BLOCK_SUPERBLOCK (bl);
|
||||
+
|
||||
+ return BLOCK_FUNCTION (bl);
|
||||
+}
|
||||
+
|
||||
/* Return one if BL represents an inlined function. */
|
||||
|
||||
int
|
||||
Index: gdb-6.8.50.20081128/gdb/block.h
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081128.orig/gdb/block.h 2008-12-06 14:06:16.000000000 +0100
|
||||
+++ gdb-6.8.50.20081128/gdb/block.h 2008-12-06 21:39:56.000000000 +0100
|
||||
@@ -133,6 +133,7 @@ struct blockvector
|
||||
enum { GLOBAL_BLOCK = 0, STATIC_BLOCK = 1, FIRST_LOCAL_BLOCK = 2 };
|
||||
|
||||
extern struct symbol *block_linkage_function (const struct block *);
|
||||
+extern struct symbol *block_function (const struct block *bl);
|
||||
|
||||
extern int block_inlined_p (const struct block *block);
|
||||
|
||||
Index: gdb-6.8.50.20081128/gdb/blockframe.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081128.orig/gdb/blockframe.c 2008-12-06 14:06:16.000000000 +0100
|
||||
+++ gdb-6.8.50.20081128/gdb/blockframe.c 2008-12-06 21:39:56.000000000 +0100
|
||||
@@ -143,7 +143,7 @@ find_pc_sect_function (CORE_ADDR pc, str
|
||||
struct block *b = block_for_pc_sect (pc, section);
|
||||
if (b == 0)
|
||||
return 0;
|
||||
- return block_linkage_function (b);
|
||||
+ return block_function (b);
|
||||
}
|
||||
|
||||
/* Return the function containing pc value PC.
|
||||
Index: gdb-6.8.50.20081128/gdb/breakpoint.c
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081128.orig/gdb/breakpoint.c 2008-12-06 14:06:17.000000000 +0100
|
||||
+++ gdb-6.8.50.20081128/gdb/breakpoint.c 2008-12-06 21:39:56.000000000 +0100
|
||||
@@ -5712,7 +5712,7 @@ resolve_sal_pc (struct symtab_and_line *
|
||||
bv = blockvector_for_pc_sect (sal->pc, 0, &b, sal->symtab);
|
||||
if (bv != NULL)
|
||||
{
|
||||
- sym = block_linkage_function (b);
|
||||
+ sym = block_function (b);
|
||||
if (sym != NULL)
|
||||
{
|
||||
fixup_symbol_section (sym, sal->symtab->objfile);
|
||||
Index: gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-cmds.exp
|
||||
===================================================================
|
||||
--- gdb-6.8.50.20081128.orig/gdb/testsuite/gdb.opt/inline-cmds.exp 2008-12-06 21:37:27.000000000 +0100
|
||||
+++ gdb-6.8.50.20081128/gdb/testsuite/gdb.opt/inline-cmds.exp 2008-12-06 21:41:37.000000000 +0100
|
||||
@@ -45,8 +45,10 @@ if { [skip_inline_frame_tests] } {
|
||||
|
||||
# First, check that the things we expected to be inlined really were,
|
||||
# and those that shouldn't be weren't.
|
||||
-set line1 [gdb_get_line_number "set breakpoint 1 here" ${srcfile2}]
|
||||
-gdb_breakpoint $srcfile2:$line1
|
||||
+# We test also inlining by the function name, otherwise we would use:
|
||||
+# set line1 [gdb_get_line_number "set breakpoint 1 here" ${srcfile2}]
|
||||
+# gdb_breakpoint $srcfile2:$line1
|
||||
+gdb_breakpoint "bar"
|
||||
set line2 [gdb_get_line_number "set breakpoint 2 here" ${srcfile2}]
|
||||
gdb_breakpoint $srcfile2:$line2
|
||||
|
3271
gdb-6.8-inlining.patch
Normal file
3271
gdb-6.8-inlining.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,8 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Mar 2 11:42:03 CET 2009 - rguenther@suse.de
|
||||
|
||||
- Integrate support for transparently debugging inline functions.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Feb 16 11:40:00 CET 2009 - schwab@suse.de
|
||||
|
||||
|
14
gdb.spec
14
gdb.spec
@@ -20,7 +20,7 @@
|
||||
Name: gdb
|
||||
Summary: The GNU Debugger
|
||||
Version: 6.8.50.20090216
|
||||
Release: 1
|
||||
Release: 2
|
||||
BuildRequires: bison dejagnu flex gcc-c++ gcc-fortran gcc-java gcc-objc python-devel readline-devel zlib-devel
|
||||
%if 0%{?suse_version} > 1020
|
||||
BuildRequires: libexpat-devel
|
||||
@@ -43,6 +43,7 @@ Obsoletes: gdb-64bit
|
||||
PreReq: %{install_info_prereq}
|
||||
Recommends: python
|
||||
%define sss -cvs
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
Source: gdb-%{version}%{sss}.tar.bz2
|
||||
Patch: cell-combined.diff
|
||||
Patch1: find-pc-sect-line.diff
|
||||
@@ -54,7 +55,11 @@ Patch7: pie-relocate.diff
|
||||
Patch8: find-separate-debug-file.diff
|
||||
Patch9: fix-gdb-backtrace.diff
|
||||
Patch10: expand-line-sal-maybe.diff
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
# Patches from Fedora
|
||||
# Support transparent debugging of inlined functions for an optimized code.
|
||||
Patch327: gdb-6.8-inlining.patch
|
||||
Patch350: gdb-6.8-inlining-addon.patch
|
||||
Patch328: gdb-6.8-inlining-by-name.patch
|
||||
|
||||
%description
|
||||
You can use GDB to debug programs written in C, C++, Ada, and Modula-2.
|
||||
@@ -123,6 +128,9 @@ Authors:
|
||||
%patch8
|
||||
%patch9
|
||||
%patch10
|
||||
%patch327 -p1
|
||||
%patch350 -p1
|
||||
%patch328 -p1
|
||||
|
||||
%build
|
||||
%ifarch %ix86 ia64 ppc ppc64 s390 s390x x86_64
|
||||
@@ -199,6 +207,8 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Mar 02 2009 rguenther@suse.de
|
||||
- Integrate support for transparently debugging inline functions.
|
||||
* Mon Feb 16 2009 schwab@suse.de
|
||||
- Update to head to trunk.
|
||||
* Tue Feb 03 2009 schwab@suse.de
|
||||
|
Reference in New Issue
Block a user