mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
2 Commits
gdb-8.2.1-
...
users/keit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a62f06ebb3 | ||
|
|
83b9557361 |
@@ -68,6 +68,7 @@
|
||||
#include "format.h"
|
||||
#include "thread-fsm.h"
|
||||
#include "tid-parse.h"
|
||||
#include "inline-frame.h"
|
||||
|
||||
/* readline include files */
|
||||
#include "readline/readline.h"
|
||||
@@ -5315,6 +5316,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
clear_inline_frame_state (ptid);
|
||||
exception_fprintf (gdb_stderr, ex,
|
||||
"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
|
||||
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).
|
||||
/* See breakpoint.h. */
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
static int
|
||||
bool
|
||||
breakpoint_address_is_meaningful (struct breakpoint *bpt)
|
||||
{
|
||||
enum bptype type = bpt->type;
|
||||
|
||||
@@ -920,6 +920,23 @@ extern bpstat bpstat_copy (bpstat);
|
||||
extern bpstat bpstat_stop_status (const address_space *aspace,
|
||||
CORE_ADDR pc, ptid_t ptid,
|
||||
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
|
||||
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;
|
||||
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
|
||||
nexti. After stepi and nexti, always show the innermost frame (not any
|
||||
inline function call sites). */
|
||||
@@ -5870,7 +5876,12 @@ handle_signal_stop (struct execution_control_state *ecs)
|
||||
ecs->event_thread->prev_pc,
|
||||
&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
|
||||
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
|
||||
function. */
|
||||
stop_print_frame = 1;
|
||||
|
||||
@@ -301,7 +301,7 @@ block_starting_point_at (CORE_ADDR pc, const struct block *block)
|
||||
user steps into them. */
|
||||
|
||||
void
|
||||
skip_inline_frames (ptid_t ptid)
|
||||
skip_inline_frames (ptid_t ptid, struct breakpoint *bpt)
|
||||
{
|
||||
CORE_ADDR this_pc;
|
||||
const struct block *frame_block, *cur_block;
|
||||
@@ -327,7 +327,25 @@ skip_inline_frames (ptid_t ptid)
|
||||
if (BLOCK_START (cur_block) == this_pc
|
||||
|| 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);
|
||||
}
|
||||
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
|
||||
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
|
||||
about to be resumed. If PTID is minus_one_ptid, forget about all
|
||||
|
||||
@@ -128,6 +128,54 @@ func8a (int x)
|
||||
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. */
|
||||
|
||||
int
|
||||
@@ -155,5 +203,7 @@ main (int argc, char *argv[])
|
||||
|
||||
x = func8a (x) + func8b (x);
|
||||
|
||||
x = not_inline_func3 (-21);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -185,4 +185,39 @@ for {set i 1} {$i <= [array size results]} {incr 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
|
||||
|
||||
Reference in New Issue
Block a user