forked from Imagelibrary/binutils-gdb
Compare commits
2 Commits
users/abur
...
users/keit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a62f06ebb3 | ||
|
|
83b9557361 |
@@ -68,6 +68,7 @@
|
|||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include "thread-fsm.h"
|
#include "thread-fsm.h"
|
||||||
#include "tid-parse.h"
|
#include "tid-parse.h"
|
||||||
|
#include "inline-frame.h"
|
||||||
|
|
||||||
/* readline include files */
|
/* readline include files */
|
||||||
#include "readline/readline.h"
|
#include "readline/readline.h"
|
||||||
@@ -5315,6 +5316,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
|
|||||||
}
|
}
|
||||||
CATCH (ex, RETURN_MASK_ALL)
|
CATCH (ex, RETURN_MASK_ALL)
|
||||||
{
|
{
|
||||||
|
clear_inline_frame_state (ptid);
|
||||||
exception_fprintf (gdb_stderr, ex,
|
exception_fprintf (gdb_stderr, ex,
|
||||||
"Error in testing breakpoint condition:\n");
|
"Error in testing breakpoint condition:\n");
|
||||||
}
|
}
|
||||||
@@ -6780,22 +6782,9 @@ describe_other_breakpoints (struct gdbarch *gdbarch,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return true iff it is meaningful to use the address member of
|
/* See breakpoint.h. */
|
||||||
BPT locations. For some breakpoint types, the locations' address members
|
|
||||||
are irrelevant and it makes no sense to attempt to compare them to other
|
|
||||||
addresses (or use them for any other purpose either).
|
|
||||||
|
|
||||||
More specifically, each of the following breakpoint types will
|
bool
|
||||||
always have a zero valued location address and we don't want to mark
|
|
||||||
breakpoints of any of these types to be a duplicate of an actual
|
|
||||||
breakpoint location at address zero:
|
|
||||||
|
|
||||||
bp_watchpoint
|
|
||||||
bp_catchpoint
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
breakpoint_address_is_meaningful (struct breakpoint *bpt)
|
breakpoint_address_is_meaningful (struct breakpoint *bpt)
|
||||||
{
|
{
|
||||||
enum bptype type = bpt->type;
|
enum bptype type = bpt->type;
|
||||||
|
|||||||
@@ -920,6 +920,23 @@ extern bpstat bpstat_copy (bpstat);
|
|||||||
extern bpstat bpstat_stop_status (const address_space *aspace,
|
extern bpstat bpstat_stop_status (const address_space *aspace,
|
||||||
CORE_ADDR pc, ptid_t ptid,
|
CORE_ADDR pc, ptid_t ptid,
|
||||||
const struct target_waitstatus *ws);
|
const struct target_waitstatus *ws);
|
||||||
|
|
||||||
|
/* Return true iff it is meaningful to use the address member of
|
||||||
|
BPT locations. For some breakpoint types, the locations' address members
|
||||||
|
are irrelevant and it makes no sense to attempt to compare them to other
|
||||||
|
addresses (or use them for any other purpose either).
|
||||||
|
|
||||||
|
More specifically, each of the following breakpoint types will
|
||||||
|
always have a zero valued location address and we don't want to mark
|
||||||
|
breakpoints of any of these types to be a duplicate of an actual
|
||||||
|
breakpoint location at address zero:
|
||||||
|
|
||||||
|
bp_watchpoint
|
||||||
|
bp_catchpoint
|
||||||
|
|
||||||
|
*/
|
||||||
|
extern bool breakpoint_address_is_meaningful (struct breakpoint *bpt);
|
||||||
|
|
||||||
|
|
||||||
/* This bpstat_what stuff tells wait_for_inferior what to do with a
|
/* This bpstat_what stuff tells wait_for_inferior what to do with a
|
||||||
breakpoint (a challenging task).
|
breakpoint (a challenging task).
|
||||||
|
|||||||
19
gdb/infrun.c
19
gdb/infrun.c
@@ -5840,6 +5840,12 @@ handle_signal_stop (struct execution_control_state *ecs)
|
|||||||
stop_print_frame = 1;
|
stop_print_frame = 1;
|
||||||
stopped_by_random_signal = 0;
|
stopped_by_random_signal = 0;
|
||||||
|
|
||||||
|
/* See if there is a breakpoint/watchpoint/catchpoint/etc. that
|
||||||
|
handles this event. */
|
||||||
|
ecs->event_thread->control.stop_bpstat
|
||||||
|
= bpstat_stop_status (get_current_regcache ()->aspace (),
|
||||||
|
stop_pc, ecs->ptid, &ecs->ws);
|
||||||
|
|
||||||
/* Hide inlined functions starting here, unless we just performed stepi or
|
/* Hide inlined functions starting here, unless we just performed stepi or
|
||||||
nexti. After stepi and nexti, always show the innermost frame (not any
|
nexti. After stepi and nexti, always show the innermost frame (not any
|
||||||
inline function call sites). */
|
inline function call sites). */
|
||||||
@@ -5870,7 +5876,12 @@ handle_signal_stop (struct execution_control_state *ecs)
|
|||||||
ecs->event_thread->prev_pc,
|
ecs->event_thread->prev_pc,
|
||||||
&ecs->ws)))
|
&ecs->ws)))
|
||||||
{
|
{
|
||||||
skip_inline_frames (ecs->ptid);
|
struct breakpoint *bpt = NULL;
|
||||||
|
|
||||||
|
if (ecs->event_thread->control.stop_bpstat != NULL)
|
||||||
|
bpt = ecs->event_thread->control.stop_bpstat->breakpoint_at;
|
||||||
|
|
||||||
|
skip_inline_frames (ecs->ptid, bpt);
|
||||||
|
|
||||||
/* Re-fetch current thread's frame in case that invalidated
|
/* Re-fetch current thread's frame in case that invalidated
|
||||||
the frame cache. */
|
the frame cache. */
|
||||||
@@ -5915,12 +5926,6 @@ handle_signal_stop (struct execution_control_state *ecs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if there is a breakpoint/watchpoint/catchpoint/etc. that
|
|
||||||
handles this event. */
|
|
||||||
ecs->event_thread->control.stop_bpstat
|
|
||||||
= bpstat_stop_status (get_current_regcache ()->aspace (),
|
|
||||||
stop_pc, ecs->ptid, &ecs->ws);
|
|
||||||
|
|
||||||
/* Following in case break condition called a
|
/* Following in case break condition called a
|
||||||
function. */
|
function. */
|
||||||
stop_print_frame = 1;
|
stop_print_frame = 1;
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ block_starting_point_at (CORE_ADDR pc, const struct block *block)
|
|||||||
user steps into them. */
|
user steps into them. */
|
||||||
|
|
||||||
void
|
void
|
||||||
skip_inline_frames (ptid_t ptid)
|
skip_inline_frames (ptid_t ptid, struct breakpoint *bpt)
|
||||||
{
|
{
|
||||||
CORE_ADDR this_pc;
|
CORE_ADDR this_pc;
|
||||||
const struct block *frame_block, *cur_block;
|
const struct block *frame_block, *cur_block;
|
||||||
@@ -327,7 +327,25 @@ skip_inline_frames (ptid_t ptid)
|
|||||||
if (BLOCK_START (cur_block) == this_pc
|
if (BLOCK_START (cur_block) == this_pc
|
||||||
|| block_starting_point_at (this_pc, cur_block))
|
|| block_starting_point_at (this_pc, cur_block))
|
||||||
{
|
{
|
||||||
skip_count++;
|
bool skip_this_frame = true;
|
||||||
|
|
||||||
|
if (bpt != NULL
|
||||||
|
&& user_breakpoint_p (bpt)
|
||||||
|
&& breakpoint_address_is_meaningful (bpt))
|
||||||
|
{
|
||||||
|
for (bp_location *loc = bpt->loc; loc != NULL;
|
||||||
|
loc = loc->next)
|
||||||
|
{
|
||||||
|
if (loc->address == this_pc)
|
||||||
|
{
|
||||||
|
skip_this_frame = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip_this_frame)
|
||||||
|
skip_count++;
|
||||||
last_sym = BLOCK_FUNCTION (cur_block);
|
last_sym = BLOCK_FUNCTION (cur_block);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ extern const struct frame_unwind inline_frame_unwind;
|
|||||||
Frames for the hidden functions will not appear in the backtrace until the
|
Frames for the hidden functions will not appear in the backtrace until the
|
||||||
user steps into them. */
|
user steps into them. */
|
||||||
|
|
||||||
void skip_inline_frames (ptid_t ptid);
|
void skip_inline_frames (ptid_t ptid, struct breakpoint *bpt);
|
||||||
|
|
||||||
/* Forget about any hidden inlined functions in PTID, which is new or
|
/* Forget about any hidden inlined functions in PTID, which is new or
|
||||||
about to be resumed. If PTID is minus_one_ptid, forget about all
|
about to be resumed. If PTID is minus_one_ptid, forget about all
|
||||||
|
|||||||
@@ -128,6 +128,54 @@ func8a (int x)
|
|||||||
return func8b (x * 31);
|
return func8b (x * 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ATTR int
|
||||||
|
inline_func1 (int x)
|
||||||
|
{
|
||||||
|
int y = 1; /* inline_func1 */
|
||||||
|
|
||||||
|
return y + x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
not_inline_func1 (int x)
|
||||||
|
{
|
||||||
|
int y = 2; /* not_inline_func1 */
|
||||||
|
|
||||||
|
return y + inline_func1 (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ATTR int
|
||||||
|
inline_func2 (int x)
|
||||||
|
{
|
||||||
|
int y = 3; /* inline_func2 */
|
||||||
|
|
||||||
|
return y + not_inline_func1 (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
not_inline_func2 (int x)
|
||||||
|
{
|
||||||
|
int y = 4; /* not_inline_func2 */
|
||||||
|
|
||||||
|
return y + inline_func2 (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ATTR int
|
||||||
|
inline_func3 (int x)
|
||||||
|
{
|
||||||
|
int y = 5; /* inline_func3 */
|
||||||
|
|
||||||
|
return y + not_inline_func2 (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
not_inline_func3 (int x)
|
||||||
|
{
|
||||||
|
int y = 6; /* not_inline_func3 */
|
||||||
|
|
||||||
|
return y + inline_func3 (x);
|
||||||
|
}
|
||||||
|
|
||||||
/* Entry point. */
|
/* Entry point. */
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -155,5 +203,7 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
x = func8a (x) + func8b (x);
|
x = func8a (x) + func8b (x);
|
||||||
|
|
||||||
|
x = not_inline_func3 (-21);
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,4 +185,39 @@ for {set i 1} {$i <= [array size results]} {incr i} {
|
|||||||
gdb_test "info break $i" $results($i)
|
gdb_test "info break $i" $results($i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Start us running.
|
||||||
|
if {![runto main]} {
|
||||||
|
untested "could not run to main"
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Insert breakpoints for all inline_func? and not_inline_func? and check
|
||||||
|
# that we actually stop where we think we should.
|
||||||
|
|
||||||
|
for {set i 1} {$i < 4} {incr i} {
|
||||||
|
foreach inline {"not_inline" "inline"} {
|
||||||
|
gdb_breakpoint "${inline}_func$i" message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set ws {[\r\n\t ]+}
|
||||||
|
set backtrace [list "(in|at)? main"]
|
||||||
|
for {set i 3} {$i > 0} {incr i -1} {
|
||||||
|
|
||||||
|
foreach inline {"not_inline" "inline"} {
|
||||||
|
|
||||||
|
# Check that we stop at the correct location and print out
|
||||||
|
# the (possibly) inlined frames.
|
||||||
|
set num [gdb_get_line_number "/* ${inline}_func$i */"]
|
||||||
|
set pattern ".*/$srcfile:$num${ws}.*$num${ws}int y = $decimal;"
|
||||||
|
append pattern "${ws}/\\\* ${inline}_func$i \\\*/"
|
||||||
|
send_log "Expecting $pattern\n"
|
||||||
|
gdb_continue_to_breakpoint "${inline}_func$i" $pattern
|
||||||
|
|
||||||
|
# Also check for the correct backtrace.
|
||||||
|
set backtrace [linsert $backtrace 0 "(in|at)?${ws}${inline}_func$i"]
|
||||||
|
gdb_test_sequence "bt" "bt stopped in ${inline}_func$i" $backtrace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unset -nocomplain results
|
unset -nocomplain results
|
||||||
|
|||||||
Reference in New Issue
Block a user