mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
151 Commits
binutils-2
...
gdb-7.11.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41d82368c3 | ||
|
|
a70e2b5231 | ||
|
|
333cacb483 | ||
|
|
00d6f16a18 | ||
|
|
7cb67a322b | ||
|
|
8ce0a6f81d | ||
|
|
b450bfa82e | ||
|
|
53b26facdd | ||
|
|
136613ef0c | ||
|
|
a0de87e7be | ||
|
|
92e1921256 | ||
|
|
079f7d434d | ||
|
|
8fb059f570 | ||
|
|
fc21d77733 | ||
|
|
2838ada635 | ||
|
|
f4188a7879 | ||
|
|
edf01670a6 | ||
|
|
cf2cd51217 | ||
|
|
f0a8d0dc70 | ||
|
|
2ef476ed0a | ||
|
|
b5f0db46b3 | ||
|
|
bffe67e8c0 | ||
|
|
7f8e34d860 | ||
|
|
d38ce6a68f | ||
|
|
919bc2384a | ||
|
|
d85af00da6 | ||
|
|
5f12f92452 | ||
|
|
ca445d4820 | ||
|
|
1a982b689c | ||
|
|
74e2db3c52 | ||
|
|
8bc1de549e | ||
|
|
46b8da737e | ||
|
|
c6b1e09111 | ||
|
|
3175901324 | ||
|
|
82e0aa86a9 | ||
|
|
85b7329cbf | ||
|
|
329dec6fc5 | ||
|
|
aaa3178dfb | ||
|
|
386c903485 | ||
|
|
56d916d008 | ||
|
|
88d549dbba | ||
|
|
4b8485e42f | ||
|
|
f8ae9852db | ||
|
|
6632574739 | ||
|
|
8dd7634154 | ||
|
|
a6ff23076f | ||
|
|
476e70f3c8 | ||
|
|
064b958634 | ||
|
|
9b075d90e5 | ||
|
|
492fb6e6f8 | ||
|
|
8b52b7e83a | ||
|
|
d6259c13dc | ||
|
|
cdbc63eac7 | ||
|
|
9f1296dc90 | ||
|
|
8b871d3060 | ||
|
|
e0a37db7ab | ||
|
|
13c4107cef | ||
|
|
03c6edc83c | ||
|
|
da611eed9a | ||
|
|
619f36aa00 | ||
|
|
6bdefd8864 | ||
|
|
ec46cd40d1 | ||
|
|
6b9ef0d488 | ||
|
|
1ca6d92fb6 | ||
|
|
d91f748146 | ||
|
|
e275ae514e | ||
|
|
8ec8126cde | ||
|
|
d502ed3d7b | ||
|
|
3290953abc | ||
|
|
23e33df951 | ||
|
|
fe516b1504 | ||
|
|
6cc52a1950 | ||
|
|
bf563723c3 | ||
|
|
5460f86819 | ||
|
|
60c3df5b9c | ||
|
|
f2f5278372 | ||
|
|
85af34ee02 | ||
|
|
89df5d6cce | ||
|
|
cd64cabb8c | ||
|
|
f8210fb710 | ||
|
|
dee3dbc902 | ||
|
|
0b0edae68a | ||
|
|
e571466b82 | ||
|
|
a0d75692a1 | ||
|
|
378b7e3879 | ||
|
|
b33441714a | ||
|
|
a87a0f8b2c | ||
|
|
253b3b9547 | ||
|
|
174d467379 | ||
|
|
a608d6856a | ||
|
|
288b250718 | ||
|
|
ae850cee98 | ||
|
|
f3e8a3a780 | ||
|
|
2ef34d11f6 | ||
|
|
6c410d3b60 | ||
|
|
b102e5372a | ||
|
|
9312893c8d | ||
|
|
4e57eb7028 | ||
|
|
283c00efb7 | ||
|
|
e061ed5b54 | ||
|
|
bb11dc174e | ||
|
|
516ff4a7dd | ||
|
|
b3e987c24c | ||
|
|
5883da401e | ||
|
|
251a7aee76 | ||
|
|
6d1f374b86 | ||
|
|
5ec6069376 | ||
|
|
051cabb732 | ||
|
|
cd58937ca7 | ||
|
|
cc22a0293f | ||
|
|
6bdb373afe | ||
|
|
fc5494cebb | ||
|
|
17b5be823d | ||
|
|
9afc053a96 | ||
|
|
ff474daa69 | ||
|
|
42d294de79 | ||
|
|
08533595dc | ||
|
|
4f80d1d126 | ||
|
|
63a034c19f | ||
|
|
cad15c35d5 | ||
|
|
ac6c80b223 | ||
|
|
7996349ead | ||
|
|
dee54a904b | ||
|
|
3d58f89972 | ||
|
|
976b7aed19 | ||
|
|
cf0091e0aa | ||
|
|
a5d53b5c70 | ||
|
|
d0729c5ff5 | ||
|
|
c4e79d4f7a | ||
|
|
fad83601a1 | ||
|
|
e993d610a9 | ||
|
|
523f1dab16 | ||
|
|
11b051fcc9 | ||
|
|
906c69d06a | ||
|
|
8b6bd5aca6 | ||
|
|
2d059a33d8 | ||
|
|
55afcfaf58 | ||
|
|
46e42194d8 | ||
|
|
307c2facb2 | ||
|
|
a5bb7efba6 | ||
|
|
ceb65faba4 | ||
|
|
bfe7ecf8d9 | ||
|
|
192b594e45 | ||
|
|
83d9e733ab | ||
|
|
7bcc056ca9 | ||
|
|
45e8913772 | ||
|
|
2f43accadf | ||
|
|
8e1043a37a | ||
|
|
4fd877f0a5 | ||
|
|
4ad0fc283c | ||
|
|
d5d168eef1 |
@@ -1,3 +1,7 @@
|
||||
2016-02-10 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* development.sh (development): Set to false.
|
||||
|
||||
2016-02-09 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* oasys.c (oasys_archive_p): Fix indentation.
|
||||
|
||||
@@ -16,4 +16,4 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Controls whether to enable development-mode features by default.
|
||||
development=true
|
||||
development=false
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define BFD_VERSION_DATE 20160210
|
||||
#define BFD_VERSION_DATE 20160601
|
||||
#define BFD_VERSION @bfd_version@
|
||||
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
|
||||
#define REPORT_BUGS_TO @report_bugs_to@
|
||||
|
||||
204
gdb/ChangeLog
204
gdb/ChangeLog
@@ -1,3 +1,207 @@
|
||||
2016-06-01 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.11.1.
|
||||
|
||||
2016-05-25 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/19828
|
||||
* linux-nat.c (attach_proc_task_lwp_callback): Mark the lwp
|
||||
resumed, and add the thread to GDB's thread list.
|
||||
|
||||
2016-05-25 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/19828
|
||||
* linux-nat.c (get_pending_status): If the thread reported the
|
||||
event to the core and it's pending, use the pending status signal
|
||||
number.
|
||||
|
||||
2016-05-17 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
PR gdb/20045
|
||||
* mi/mi-main.c (mi_on_resume): Call target_can_async_p instead
|
||||
of target_is_async_p.
|
||||
|
||||
2016-05-17 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
PR gdb/18077
|
||||
* mi/mi-main.c (run_one_inferior): Use run target to determine
|
||||
whether to run async or not.
|
||||
(mi_cmd_exec_run): Likewise.
|
||||
|
||||
2016-05-16 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/20039
|
||||
* mi/mi-interp.c (mi_new_thread): Put
|
||||
target_terminal_ours_for_output in effect while outputting.
|
||||
(mi_thread_exit): Use target_terminal_ours_for_output instead of
|
||||
target_terminal_ours.
|
||||
(mi_record_changed, mi_inferior_added, mi_inferior_appeared)
|
||||
(mi_inferior_exit, mi_inferior_removed, mi_traceframe_changed)
|
||||
(mi_tsv_created, mi_tsv_deleted, mi_tsv_modified)
|
||||
(mi_breakpoint_created, mi_breakpoint_deleted)
|
||||
(mi_breakpoint_modified, mi_solib_loaded, mi_solib_unloaded)
|
||||
(mi_command_param_changed, mi_memory_changed)
|
||||
(report_initial_inferior): Use target_terminal_ours_for_output
|
||||
instead of target_terminal_ours. Restore terminal settings.
|
||||
* mi/mi-main.c (mi_execute_command): Use
|
||||
target_terminal_ours_for_output instead of target_terminal_ours.
|
||||
Restore terminal settings.
|
||||
|
||||
2016-05-03 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR python/20037
|
||||
* python/python.c (_initialize_python) [IS_PY3K]: xstrdup/xfree
|
||||
oldloc.
|
||||
|
||||
2016-05-03 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* python/python.c (_initialize_python) [IS_PY3K]: Remove dead
|
||||
code.
|
||||
|
||||
2016-05-03 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
* symfile.c (find_pc_overlay): Add braces to avoid -Wparentheses
|
||||
warning.
|
||||
(find_pc_mapped_section): Likewise.
|
||||
(list_overlays_command): Likewise.
|
||||
|
||||
2016-04-27 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* remote.c (remote_start_remote): Detect PACKET_vFile_setfs.support.
|
||||
|
||||
2016-04-15 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* nat/linux-ptrace.h [__mips__] (GDB_ARCH_IS_TRAP_BRKPT): Also
|
||||
accept TRAP_BRKPT.
|
||||
[__mips__] (GDB_ARCH_IS_TRAP_HWBKPT): Also accept TRAP_HWBKPT.
|
||||
|
||||
2016-04-15 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* linux-nat.c (save_sigtrap) Delete.
|
||||
(stop_wait_callback): Call save_stop_reason instead of
|
||||
save_sigtrap.
|
||||
(check_stopped_by_breakpoint): Rename to ...
|
||||
(save_stop_reason): ... this. Bits of save_sigtrap folded here.
|
||||
Use GDB_ARCH_IS_TRAP_HWBKPT and handle ambiguous
|
||||
GDB_ARCH_IS_TRAP_BRKPT / GDB_ARCH_IS_TRAP_HWBKPT. Factor out
|
||||
common code between the USE_SIGTRAP_SIGINFO and
|
||||
!USE_SIGTRAP_SIGINFO blocks.
|
||||
(linux_nat_filter_event): Call save_stop_reason instead of
|
||||
save_sigtrap.
|
||||
* nat/linux-ptrace.h: Check for both SI_KERNEL and TRAP_BRKPT
|
||||
si_code for MIPS.
|
||||
* nat/linux-ptrace.h: Fix "TRAP_HWBPT" typo in x86 table. Add
|
||||
comments on MIPS behavior.
|
||||
(GDB_ARCH_IS_TRAP_HWBKPT): Define for all archs.
|
||||
|
||||
2016-04-13 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR remote/19840
|
||||
* remote.c (struct remote_state) <last_resume_exec_dir>: New
|
||||
field.
|
||||
(new_remote_state): Default last_resume_exec_dir to EXEC_FORWARD.
|
||||
(remote_open_1): Reset last_resume_exec_dir to EXEC_FORWARD.
|
||||
(remote_resume): Store the last execution direction.
|
||||
(remote_execution_direction): New function.
|
||||
(init_remote_ops): Install it as to_execution_direction target_ops
|
||||
method.
|
||||
|
||||
2016-03-31 Yichao Yu <yyc1992@gmail.com>
|
||||
|
||||
PR gdb/19858
|
||||
* jit.c (jit_breakpoint_re_set_internal): Return 0 if we already
|
||||
got the breakpoint at the right address.
|
||||
(jit_inferior_created): New function.
|
||||
(_initialize_jit): Install jit_inferior_created as
|
||||
inferior_created observer.
|
||||
|
||||
2016-03-17 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
PR gdb/19829
|
||||
* frame.h (skip_tailcall_frames): New.
|
||||
* infcmd.c (finish_command): Call skip_tailcall_frames.
|
||||
* frame.c (skip_artificial_frames): Return NULL if only artificial
|
||||
frames are found. Update comment.
|
||||
(frame_pop): Call skip_tailcall_frames.
|
||||
(frame_unwind_caller_id): Handle NULL return.
|
||||
(frame_unwind_caller_pc, frame_unwind_caller_arch): Assert that
|
||||
skip_artificial_frames does not return NULL.
|
||||
(frame_pop): Add an error if only tailcall frames are found.
|
||||
* infcmd.c (finish_command): Move skip_tailcall_frames call into
|
||||
forward-execution case. Add an error if only tailcall frames are found.
|
||||
* stack.c (frame_info): Check frame_unwind_caller_id.
|
||||
|
||||
2016-03-15 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/19676
|
||||
* linux-thread-db.c (try_thread_db_load_1): Leave
|
||||
info->td_ta_thr_iter_p NULL iff debugging a live process and we
|
||||
have /proc access.
|
||||
(find_new_threads_once): Assert that we have a non-NULL
|
||||
info->td_ta_thr_iter_p instead of checking whether the target has
|
||||
execution.
|
||||
|
||||
2016-03-15 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/19676
|
||||
* infrun.c (displaced_step_prepare): Also disable displaced
|
||||
stepping on NOT_SUPPORTED_ERROR.
|
||||
* linux-tdep.c (linux_displaced_step_location): If reading auxv
|
||||
fails, throw NOT_SUPPORTED_ERROR instead of generic error.
|
||||
|
||||
2016-02-24 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.11.0.DATE-git.
|
||||
|
||||
2016-02-24 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 7.11 released.
|
||||
|
||||
2016-02-24 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.11.
|
||||
|
||||
2016-02-22 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb-gdb.py (class TypeFlagsPrinter): Use parentheses for print.
|
||||
|
||||
2016-02-16 Don Breazeal <donb@codesourcery.com>
|
||||
|
||||
PR remote/19496
|
||||
* remote.c (remove_new_fork_children): Check for pending
|
||||
fork status in thread_info.suspend.
|
||||
|
||||
2016-02-16 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* arm-linux-tdep.c (arm_linux_software_single_step): Assign
|
||||
'old_chain' later.
|
||||
|
||||
2016-02-10 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Replace -cvs suffix by -git suffix.
|
||||
|
||||
2016-02-10 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.10.90.DATE-cvs.
|
||||
|
||||
2016-02-10 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 7.10.90 released.
|
||||
|
||||
2016-02-10 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* version.in: Set GDB version number to 7.10.90.
|
||||
|
||||
2016-02-10 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* NEWS: Change "Changes since GDB version 7.10" into "Changes
|
||||
in GDB version 7.11".
|
||||
|
||||
2016-02-10 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
GDB 7.11 branch created (9ef9e6a6a0dd8f948708cb67c9afcfd0be40cb0a):
|
||||
* version.in: Bump version to 7.10.90.DATE-git.
|
||||
|
||||
2016-02-09 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
PR breakpoints/19546
|
||||
|
||||
2
gdb/NEWS
2
gdb/NEWS
@@ -1,7 +1,7 @@
|
||||
What has changed in GDB?
|
||||
(Organized release by release)
|
||||
|
||||
*** Changes since GDB 7.10
|
||||
*** Changes in GDB 7.11
|
||||
|
||||
* GDB now supports debugging kernel-based threads on FreeBSD.
|
||||
|
||||
|
||||
@@ -933,13 +933,15 @@ arm_linux_software_single_step (struct frame_info *frame)
|
||||
CORE_ADDR pc;
|
||||
int i;
|
||||
VEC (CORE_ADDR) *next_pcs = NULL;
|
||||
struct cleanup *old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs);
|
||||
struct cleanup *old_chain;
|
||||
|
||||
/* If the target does have hardware single step, GDB doesn't have
|
||||
to bother software single step. */
|
||||
if (target_can_do_single_step () == 1)
|
||||
return 0;
|
||||
|
||||
old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs);
|
||||
|
||||
arm_get_next_pcs_ctor (&next_pcs_ctx,
|
||||
&arm_linux_get_next_pcs_ops,
|
||||
gdbarch_byte_order (gdbarch),
|
||||
|
||||
60
gdb/frame.c
60
gdb/frame.c
@@ -420,7 +420,8 @@ fprint_frame (struct ui_file *file, struct frame_info *fi)
|
||||
|
||||
/* Given FRAME, return the enclosing frame as found in real frames read-in from
|
||||
inferior memory. Skip any previous frames which were made up by GDB.
|
||||
Return the original frame if no immediate previous frames exist. */
|
||||
Return FRAME if FRAME is a non-artificial frame.
|
||||
Return NULL if FRAME is the start of an artificial-only chain. */
|
||||
|
||||
static struct frame_info *
|
||||
skip_artificial_frames (struct frame_info *frame)
|
||||
@@ -428,12 +429,34 @@ skip_artificial_frames (struct frame_info *frame)
|
||||
/* Note we use get_prev_frame_always, and not get_prev_frame. The
|
||||
latter will truncate the frame chain, leading to this function
|
||||
unintentionally returning a null_frame_id (e.g., when the user
|
||||
sets a backtrace limit). This is safe, because as these frames
|
||||
are made up by GDB, there must be a real frame in the chain
|
||||
below. */
|
||||
sets a backtrace limit).
|
||||
|
||||
Note that for record targets we may get a frame chain that consists
|
||||
of artificial frames only. */
|
||||
while (get_frame_type (frame) == INLINE_FRAME
|
||||
|| get_frame_type (frame) == TAILCALL_FRAME)
|
||||
frame = get_prev_frame_always (frame);
|
||||
{
|
||||
frame = get_prev_frame_always (frame);
|
||||
if (frame == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/* See frame.h. */
|
||||
|
||||
struct frame_info *
|
||||
skip_tailcall_frames (struct frame_info *frame)
|
||||
{
|
||||
while (get_frame_type (frame) == TAILCALL_FRAME)
|
||||
{
|
||||
/* Note that for record targets we may get a frame chain that consists of
|
||||
tailcall frames only. */
|
||||
frame = get_prev_frame (frame);
|
||||
if (frame == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
@@ -496,6 +519,9 @@ frame_unwind_caller_id (struct frame_info *next_frame)
|
||||
requests the frame ID of "main()"s caller. */
|
||||
|
||||
next_frame = skip_artificial_frames (next_frame);
|
||||
if (next_frame == NULL)
|
||||
return null_frame_id;
|
||||
|
||||
this_frame = get_prev_frame_always (next_frame);
|
||||
if (this_frame)
|
||||
return get_frame_id (skip_artificial_frames (this_frame));
|
||||
@@ -869,7 +895,14 @@ frame_unwind_pc (struct frame_info *this_frame)
|
||||
CORE_ADDR
|
||||
frame_unwind_caller_pc (struct frame_info *this_frame)
|
||||
{
|
||||
return frame_unwind_pc (skip_artificial_frames (this_frame));
|
||||
this_frame = skip_artificial_frames (this_frame);
|
||||
|
||||
/* We must have a non-artificial frame. The caller is supposed to check
|
||||
the result of frame_unwind_caller_id (), which returns NULL_FRAME_ID
|
||||
in this case. */
|
||||
gdb_assert (this_frame != NULL);
|
||||
|
||||
return frame_unwind_pc (this_frame);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -972,8 +1005,10 @@ frame_pop (struct frame_info *this_frame)
|
||||
|
||||
/* Ignore TAILCALL_FRAME type frames, they were executed already before
|
||||
entering THISFRAME. */
|
||||
while (get_frame_type (prev_frame) == TAILCALL_FRAME)
|
||||
prev_frame = get_prev_frame (prev_frame);
|
||||
prev_frame = skip_tailcall_frames (prev_frame);
|
||||
|
||||
if (prev_frame == NULL)
|
||||
error (_("Cannot find the caller frame."));
|
||||
|
||||
/* Make a copy of all the register values unwound from this frame.
|
||||
Save them in a scratch buffer so that there isn't a race between
|
||||
@@ -2561,7 +2596,14 @@ frame_unwind_arch (struct frame_info *next_frame)
|
||||
struct gdbarch *
|
||||
frame_unwind_caller_arch (struct frame_info *next_frame)
|
||||
{
|
||||
return frame_unwind_arch (skip_artificial_frames (next_frame));
|
||||
next_frame = skip_artificial_frames (next_frame);
|
||||
|
||||
/* We must have a non-artificial frame. The caller is supposed to check
|
||||
the result of frame_unwind_caller_id (), which returns NULL_FRAME_ID
|
||||
in this case. */
|
||||
gdb_assert (next_frame != NULL);
|
||||
|
||||
return frame_unwind_arch (next_frame);
|
||||
}
|
||||
|
||||
/* Gets the language of FRAME. */
|
||||
|
||||
@@ -820,5 +820,10 @@ extern int frame_unwinder_is (struct frame_info *fi,
|
||||
|
||||
extern enum language get_frame_language (struct frame_info *frame);
|
||||
|
||||
/* Return the first non-tailcall frame above FRAME or FRAME if it is not a
|
||||
tailcall frame. Return NULL if FRAME is the start of a tailcall-only
|
||||
chain. */
|
||||
|
||||
extern struct frame_info *skip_tailcall_frames (struct frame_info *frame);
|
||||
|
||||
#endif /* !defined (FRAME_H) */
|
||||
|
||||
@@ -88,14 +88,14 @@ class TypeFlagsPrinter:
|
||||
try:
|
||||
flags = gdb.lookup_type("enum type_flag_value")
|
||||
except:
|
||||
print "Warning: Cannot find enum type_flag_value type."
|
||||
print " `struct type' pretty-printer will be degraded"
|
||||
print("Warning: Cannot find enum type_flag_value type.")
|
||||
print(" `struct type' pretty-printer will be degraded")
|
||||
return
|
||||
try:
|
||||
iflags = gdb.lookup_type("enum type_instance_flag_value")
|
||||
except:
|
||||
print "Warning: Cannot find enum type_instance_flag_value type."
|
||||
print " `struct type' pretty-printer will be degraded"
|
||||
print("Warning: Cannot find enum type_instance_flag_value type.")
|
||||
print(" `struct type' pretty-printer will be degraded")
|
||||
return
|
||||
# Note: TYPE_FLAG_MIN is a duplicate of TYPE_FLAG_UNSIGNED,
|
||||
# so exclude it from the list we are building.
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
2016-04-15 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* linux-low.c (check_stopped_by_breakpoint): Rename to ...
|
||||
(save_stop_reason): ... this. Use GDB_ARCH_IS_TRAP_HWBKPT and
|
||||
handle ambiguous GDB_ARCH_IS_TRAP_BRKPT / GDB_ARCH_IS_TRAP_HWBKPT.
|
||||
Factor out common code between the USE_SIGTRAP_SIGINFO and
|
||||
!USE_SIGTRAP_SIGINFO blocks.
|
||||
(linux_low_filter_event): Call save_stop_reason instead of
|
||||
check_stopped_by_breakpoint and check_stopped_by_watchpoint.
|
||||
Update comments.
|
||||
(linux_wait_1): Update comments.
|
||||
|
||||
2016-02-10 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* regcache.c (regcache_raw_read_unsigned): Clear *VAL.
|
||||
|
||||
2016-02-09 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* configure.ac: Use AC_CONFIG_FILES instead of passing arguments
|
||||
|
||||
@@ -735,32 +735,16 @@ get_syscall_trapinfo (struct lwp_info *lwp, int *sysno, int *sysret)
|
||||
current_thread = saved_thread;
|
||||
}
|
||||
|
||||
/* This function should only be called if LWP got a SIGTRAP.
|
||||
The SIGTRAP could mean several things.
|
||||
static int check_stopped_by_watchpoint (struct lwp_info *child);
|
||||
|
||||
On i386, where decr_pc_after_break is non-zero:
|
||||
|
||||
If we were single-stepping this process using PTRACE_SINGLESTEP, we
|
||||
will get only the one SIGTRAP. The value of $eip will be the next
|
||||
instruction. If the instruction we stepped over was a breakpoint,
|
||||
we need to decrement the PC.
|
||||
|
||||
If we continue the process using PTRACE_CONT, we will get a
|
||||
SIGTRAP when we hit a breakpoint. The value of $eip will be
|
||||
the instruction after the breakpoint (i.e. needs to be
|
||||
decremented). If we report the SIGTRAP to GDB, we must also
|
||||
report the undecremented PC. If the breakpoint is removed, we
|
||||
must resume at the decremented PC.
|
||||
|
||||
On a non-decr_pc_after_break machine with hardware or kernel
|
||||
single-step:
|
||||
|
||||
If we either single-step a breakpoint instruction, or continue and
|
||||
hit a breakpoint instruction, our PC will point at the breakpoint
|
||||
instruction. */
|
||||
/* Called when the LWP stopped for a signal/trap. If it stopped for a
|
||||
trap check what caused it (breakpoint, watchpoint, trace, etc.),
|
||||
and save the result in the LWP's stop_reason field. If it stopped
|
||||
for a breakpoint, decrement the PC if necessary on the lwp's
|
||||
architecture. Returns true if we now have the LWP's stop PC. */
|
||||
|
||||
static int
|
||||
check_stopped_by_breakpoint (struct lwp_info *lwp)
|
||||
save_stop_reason (struct lwp_info *lwp)
|
||||
{
|
||||
CORE_ADDR pc;
|
||||
CORE_ADDR sw_breakpoint_pc;
|
||||
@@ -785,56 +769,39 @@ check_stopped_by_breakpoint (struct lwp_info *lwp)
|
||||
{
|
||||
if (siginfo.si_signo == SIGTRAP)
|
||||
{
|
||||
if (GDB_ARCH_IS_TRAP_BRKPT (siginfo.si_code))
|
||||
if (GDB_ARCH_IS_TRAP_BRKPT (siginfo.si_code)
|
||||
&& GDB_ARCH_IS_TRAP_HWBKPT (siginfo.si_code))
|
||||
{
|
||||
if (debug_threads)
|
||||
{
|
||||
struct thread_info *thr = get_lwp_thread (lwp);
|
||||
|
||||
debug_printf ("CSBB: %s stopped by software breakpoint\n",
|
||||
target_pid_to_str (ptid_of (thr)));
|
||||
}
|
||||
|
||||
/* Back up the PC if necessary. */
|
||||
if (pc != sw_breakpoint_pc)
|
||||
{
|
||||
struct regcache *regcache
|
||||
= get_thread_regcache (current_thread, 1);
|
||||
(*the_low_target.set_pc) (regcache, sw_breakpoint_pc);
|
||||
}
|
||||
|
||||
lwp->stop_pc = sw_breakpoint_pc;
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
current_thread = saved_thread;
|
||||
return 1;
|
||||
/* The si_code is ambiguous on this arch -- check debug
|
||||
registers. */
|
||||
if (!check_stopped_by_watchpoint (lwp))
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
}
|
||||
else if (siginfo.si_code == TRAP_HWBKPT)
|
||||
else if (GDB_ARCH_IS_TRAP_BRKPT (siginfo.si_code))
|
||||
{
|
||||
if (debug_threads)
|
||||
{
|
||||
struct thread_info *thr = get_lwp_thread (lwp);
|
||||
|
||||
debug_printf ("CSBB: %s stopped by hardware "
|
||||
"breakpoint/watchpoint\n",
|
||||
target_pid_to_str (ptid_of (thr)));
|
||||
}
|
||||
|
||||
lwp->stop_pc = pc;
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
|
||||
current_thread = saved_thread;
|
||||
return 1;
|
||||
/* If we determine the LWP stopped for a SW breakpoint,
|
||||
trust it. Particularly don't check watchpoint
|
||||
registers, because at least on s390, we'd find
|
||||
stopped-by-watchpoint as long as there's a watchpoint
|
||||
set. */
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
}
|
||||
else if (GDB_ARCH_IS_TRAP_HWBKPT (siginfo.si_code))
|
||||
{
|
||||
/* This can indicate either a hardware breakpoint or
|
||||
hardware watchpoint. Check debug registers. */
|
||||
if (!check_stopped_by_watchpoint (lwp))
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
|
||||
}
|
||||
else if (siginfo.si_code == TRAP_TRACE)
|
||||
{
|
||||
if (debug_threads)
|
||||
{
|
||||
struct thread_info *thr = get_lwp_thread (lwp);
|
||||
|
||||
debug_printf ("CSBB: %s stopped by trace\n",
|
||||
target_pid_to_str (ptid_of (thr)));
|
||||
}
|
||||
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_SINGLE_STEP;
|
||||
/* We may have single stepped an instruction that
|
||||
triggered a watchpoint. In that case, on some
|
||||
architectures (such as x86), instead of TRAP_HWBKPT,
|
||||
si_code indicates TRAP_TRACE, and we need to check
|
||||
the debug registers separately. */
|
||||
if (!check_stopped_by_watchpoint (lwp))
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_SINGLE_STEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -845,6 +812,16 @@ check_stopped_by_breakpoint (struct lwp_info *lwp)
|
||||
case we need to report the breakpoint PC. */
|
||||
if ((!lwp->stepping || lwp->stop_pc == sw_breakpoint_pc)
|
||||
&& (*the_low_target.breakpoint_at) (sw_breakpoint_pc))
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
|
||||
if (hardware_breakpoint_inserted_here (pc))
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
|
||||
|
||||
if (lwp->stop_reason == TARGET_STOPPED_BY_NO_REASON)
|
||||
check_stopped_by_watchpoint (lwp);
|
||||
#endif
|
||||
|
||||
if (lwp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT)
|
||||
{
|
||||
if (debug_threads)
|
||||
{
|
||||
@@ -856,19 +833,16 @@ check_stopped_by_breakpoint (struct lwp_info *lwp)
|
||||
|
||||
/* Back up the PC if necessary. */
|
||||
if (pc != sw_breakpoint_pc)
|
||||
{
|
||||
{
|
||||
struct regcache *regcache
|
||||
= get_thread_regcache (current_thread, 1);
|
||||
(*the_low_target.set_pc) (regcache, sw_breakpoint_pc);
|
||||
}
|
||||
|
||||
lwp->stop_pc = sw_breakpoint_pc;
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
current_thread = saved_thread;
|
||||
return 1;
|
||||
/* Update this so we record the correct stop PC below. */
|
||||
pc = sw_breakpoint_pc;
|
||||
}
|
||||
|
||||
if (hardware_breakpoint_inserted_here (pc))
|
||||
else if (lwp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
|
||||
{
|
||||
if (debug_threads)
|
||||
{
|
||||
@@ -877,16 +851,31 @@ check_stopped_by_breakpoint (struct lwp_info *lwp)
|
||||
debug_printf ("CSBB: %s stopped by hardware breakpoint\n",
|
||||
target_pid_to_str (ptid_of (thr)));
|
||||
}
|
||||
|
||||
lwp->stop_pc = pc;
|
||||
lwp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
|
||||
current_thread = saved_thread;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
else if (lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
|
||||
{
|
||||
if (debug_threads)
|
||||
{
|
||||
struct thread_info *thr = get_lwp_thread (lwp);
|
||||
|
||||
debug_printf ("CSBB: %s stopped by hardware watchpoint\n",
|
||||
target_pid_to_str (ptid_of (thr)));
|
||||
}
|
||||
}
|
||||
else if (lwp->stop_reason == TARGET_STOPPED_BY_SINGLE_STEP)
|
||||
{
|
||||
if (debug_threads)
|
||||
{
|
||||
struct thread_info *thr = get_lwp_thread (lwp);
|
||||
|
||||
debug_printf ("CSBB: %s stopped by trace\n",
|
||||
target_pid_to_str (ptid_of (thr)));
|
||||
}
|
||||
}
|
||||
|
||||
lwp->stop_pc = pc;
|
||||
current_thread = saved_thread;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct lwp_info *
|
||||
@@ -2434,8 +2423,8 @@ linux_low_filter_event (int lwpid, int wstat)
|
||||
child->syscall_state = TARGET_WAITKIND_IGNORE;
|
||||
}
|
||||
|
||||
/* Be careful to not overwrite stop_pc until
|
||||
check_stopped_by_breakpoint is called. */
|
||||
/* Be careful to not overwrite stop_pc until save_stop_reason is
|
||||
called. */
|
||||
if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGTRAP
|
||||
&& linux_is_extended_waitstatus (wstat))
|
||||
{
|
||||
@@ -2448,27 +2437,12 @@ linux_low_filter_event (int lwpid, int wstat)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check first whether this was a SW/HW breakpoint before checking
|
||||
watchpoints, because at least s390 can't tell the data address of
|
||||
hardware watchpoint hits, and returns stopped-by-watchpoint as
|
||||
long as there's a watchpoint set. */
|
||||
if (WIFSTOPPED (wstat) && linux_wstatus_maybe_breakpoint (wstat))
|
||||
{
|
||||
if (check_stopped_by_breakpoint (child))
|
||||
if (save_stop_reason (child))
|
||||
have_stop_pc = 1;
|
||||
}
|
||||
|
||||
/* Note that TRAP_HWBKPT can indicate either a hardware breakpoint
|
||||
or hardware watchpoint. Check which is which if we got
|
||||
TARGET_STOPPED_BY_HW_BREAKPOINT. Likewise, we may have single
|
||||
stepped an instruction that triggered a watchpoint. In that
|
||||
case, on some architectures (such as x86), instead of
|
||||
TRAP_HWBKPT, si_code indicates TRAP_TRACE, and we need to check
|
||||
the debug registers separately. */
|
||||
if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGTRAP
|
||||
&& child->stop_reason != TARGET_STOPPED_BY_SW_BREAKPOINT)
|
||||
check_stopped_by_watchpoint (child);
|
||||
|
||||
if (!have_stop_pc)
|
||||
child->stop_pc = get_pc (child);
|
||||
|
||||
@@ -3209,7 +3183,7 @@ linux_wait_1 (ptid_t ptid,
|
||||
hardware single step it means a gdb/gdbserver breakpoint had been
|
||||
planted on top of a permanent breakpoint, in the case of a software
|
||||
single step it may just mean that gdbserver hit the reinsert breakpoint.
|
||||
The PC has been adjusted by check_stopped_by_breakpoint to point at
|
||||
The PC has been adjusted by save_stop_reason to point at
|
||||
the breakpoint address.
|
||||
So in the case of the hardware single step advance the PC manually
|
||||
past the breakpoint and in the case of software single step advance only
|
||||
|
||||
@@ -440,6 +440,7 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
|
||||
"%d bytes."),
|
||||
(int) sizeof (ULONGEST));
|
||||
|
||||
*val = 0;
|
||||
collect_register (regcache, regnum, val);
|
||||
|
||||
return REG_VALID;
|
||||
|
||||
16
gdb/infcmd.c
16
gdb/infcmd.c
@@ -2000,11 +2000,6 @@ finish_command (char *arg, int from_tty)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ignore TAILCALL_FRAME type frames, they were executed already before
|
||||
entering THISFRAME. */
|
||||
while (get_frame_type (frame) == TAILCALL_FRAME)
|
||||
frame = get_prev_frame (frame);
|
||||
|
||||
/* Find the function we will return from. */
|
||||
|
||||
sm->function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
|
||||
@@ -2031,7 +2026,16 @@ finish_command (char *arg, int from_tty)
|
||||
if (execution_direction == EXEC_REVERSE)
|
||||
finish_backward (sm);
|
||||
else
|
||||
finish_forward (sm, frame);
|
||||
{
|
||||
/* Ignore TAILCALL_FRAME type frames, they were executed already before
|
||||
entering THISFRAME. */
|
||||
frame = skip_tailcall_frames (frame);
|
||||
|
||||
if (frame == NULL)
|
||||
error (_("Cannot find the caller frame."));
|
||||
|
||||
finish_forward (sm, frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1894,7 +1894,8 @@ displaced_step_prepare (ptid_t ptid)
|
||||
{
|
||||
struct displaced_step_inferior_state *displaced_state;
|
||||
|
||||
if (ex.error != MEMORY_ERROR)
|
||||
if (ex.error != MEMORY_ERROR
|
||||
&& ex.error != NOT_SUPPORTED_ERROR)
|
||||
throw_exception (ex);
|
||||
|
||||
if (debug_infrun)
|
||||
|
||||
13
gdb/jit.c
13
gdb/jit.c
@@ -1026,7 +1026,7 @@ jit_breakpoint_deleted (struct breakpoint *b)
|
||||
}
|
||||
|
||||
/* (Re-)Initialize the jit breakpoint if necessary.
|
||||
Return 0 on success. */
|
||||
Return 0 if the jit breakpoint has been successfully initialized. */
|
||||
|
||||
static int
|
||||
jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
|
||||
@@ -1070,7 +1070,7 @@ jit_breakpoint_re_set_internal (struct gdbarch *gdbarch,
|
||||
paddress (gdbarch, addr));
|
||||
|
||||
if (ps_data->cached_code_address == addr)
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
/* Delete the old breakpoint. */
|
||||
if (ps_data->jit_breakpoint != NULL)
|
||||
@@ -1367,6 +1367,14 @@ jit_inferior_init (struct gdbarch *gdbarch)
|
||||
}
|
||||
}
|
||||
|
||||
/* inferior_created observer. */
|
||||
|
||||
static void
|
||||
jit_inferior_created (struct target_ops *ops, int from_tty)
|
||||
{
|
||||
jit_inferior_created_hook ();
|
||||
}
|
||||
|
||||
/* Exported routine to call when an inferior has been created. */
|
||||
|
||||
void
|
||||
@@ -1496,6 +1504,7 @@ _initialize_jit (void)
|
||||
show_jit_debug,
|
||||
&setdebuglist, &showdebuglist);
|
||||
|
||||
observer_attach_inferior_created (jit_inferior_created);
|
||||
observer_attach_inferior_exit (jit_inferior_exit_hook);
|
||||
observer_attach_breakpoint_deleted (jit_breakpoint_deleted);
|
||||
|
||||
|
||||
166
gdb/linux-nat.c
166
gdb/linux-nat.c
@@ -303,10 +303,11 @@ static struct lwp_info *find_lwp_pid (ptid_t ptid);
|
||||
|
||||
static int lwp_status_pending_p (struct lwp_info *lp);
|
||||
|
||||
static int check_stopped_by_breakpoint (struct lwp_info *lp);
|
||||
static int sigtrap_is_event (int status);
|
||||
static int (*linux_nat_status_is_event) (int status) = sigtrap_is_event;
|
||||
|
||||
static void save_stop_reason (struct lwp_info *lp);
|
||||
|
||||
|
||||
/* LWP accessors. */
|
||||
|
||||
@@ -1087,6 +1088,16 @@ attach_proc_task_lwp_callback (ptid_t ptid)
|
||||
/* We need to wait for a stop before being able to make the
|
||||
next ptrace call on this LWP. */
|
||||
lp->must_set_ptrace_flags = 1;
|
||||
|
||||
/* So that wait collects the SIGSTOP. */
|
||||
lp->resumed = 1;
|
||||
|
||||
/* Also add the LWP to gdb's thread list, in case a
|
||||
matching libthread_db is not found (or the process uses
|
||||
raw clone). */
|
||||
add_thread (lp->ptid);
|
||||
set_running (lp->ptid, 1);
|
||||
set_executing (lp->ptid, 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -1235,7 +1246,10 @@ get_pending_status (struct lwp_info *lp, int *status)
|
||||
{
|
||||
struct thread_info *tp = find_thread_ptid (lp->ptid);
|
||||
|
||||
signo = tp->suspend.stop_signal;
|
||||
if (tp->suspend.waitstatus_pending_p)
|
||||
signo = tp->suspend.waitstatus.value.sig;
|
||||
else
|
||||
signo = tp->suspend.stop_signal;
|
||||
}
|
||||
else if (!target_is_non_stop_p ())
|
||||
{
|
||||
@@ -2321,30 +2335,6 @@ check_stopped_by_watchpoint (struct lwp_info *lp)
|
||||
return lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
|
||||
}
|
||||
|
||||
/* Called when the LWP stopped for a trap that could be explained by a
|
||||
watchpoint or a breakpoint. */
|
||||
|
||||
static void
|
||||
save_sigtrap (struct lwp_info *lp)
|
||||
{
|
||||
gdb_assert (lp->stop_reason == TARGET_STOPPED_BY_NO_REASON);
|
||||
gdb_assert (lp->status != 0);
|
||||
|
||||
/* Check first if this was a SW/HW breakpoint before checking
|
||||
watchpoints, because at least s390 can't tell the data address of
|
||||
hardware watchpoint hits, and the kernel returns
|
||||
stopped-by-watchpoint as long as there's a watchpoint set. */
|
||||
if (linux_nat_status_is_event (lp->status))
|
||||
check_stopped_by_breakpoint (lp);
|
||||
|
||||
/* Note that TRAP_HWBKPT can indicate either a hardware breakpoint
|
||||
or hardware watchpoint. Check which is which if we got
|
||||
TARGET_STOPPED_BY_HW_BREAKPOINT. */
|
||||
if (lp->stop_reason == TARGET_STOPPED_BY_NO_REASON
|
||||
|| lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
|
||||
check_stopped_by_watchpoint (lp);
|
||||
}
|
||||
|
||||
/* Returns true if the LWP had stopped for a watchpoint. */
|
||||
|
||||
static int
|
||||
@@ -2441,7 +2431,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
|
||||
/* Save the sigtrap event. */
|
||||
lp->status = status;
|
||||
gdb_assert (lp->signalled);
|
||||
save_sigtrap (lp);
|
||||
save_stop_reason (lp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2583,29 +2573,32 @@ select_event_lwp_callback (struct lwp_info *lp, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when the LWP got a signal/trap that could be explained by a
|
||||
software or hardware breakpoint. */
|
||||
/* Called when the LWP stopped for a signal/trap. If it stopped for a
|
||||
trap check what caused it (breakpoint, watchpoint, trace, etc.),
|
||||
and save the result in the LWP's stop_reason field. If it stopped
|
||||
for a breakpoint, decrement the PC if necessary on the lwp's
|
||||
architecture. */
|
||||
|
||||
static int
|
||||
check_stopped_by_breakpoint (struct lwp_info *lp)
|
||||
static void
|
||||
save_stop_reason (struct lwp_info *lp)
|
||||
{
|
||||
/* Arrange for a breakpoint to be hit again later. We don't keep
|
||||
the SIGTRAP status and don't forward the SIGTRAP signal to the
|
||||
LWP. We will handle the current event, eventually we will resume
|
||||
this LWP, and this breakpoint will trap again.
|
||||
|
||||
If we do not do this, then we run the risk that the user will
|
||||
delete or disable the breakpoint, but the LWP will have already
|
||||
tripped on it. */
|
||||
|
||||
struct regcache *regcache = get_thread_regcache (lp->ptid);
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
struct regcache *regcache;
|
||||
struct gdbarch *gdbarch;
|
||||
CORE_ADDR pc;
|
||||
CORE_ADDR sw_bp_pc;
|
||||
#if USE_SIGTRAP_SIGINFO
|
||||
siginfo_t siginfo;
|
||||
#endif
|
||||
|
||||
gdb_assert (lp->stop_reason == TARGET_STOPPED_BY_NO_REASON);
|
||||
gdb_assert (lp->status != 0);
|
||||
|
||||
if (!linux_nat_status_is_event (lp->status))
|
||||
return;
|
||||
|
||||
regcache = get_thread_regcache (lp->ptid);
|
||||
gdbarch = get_regcache_arch (regcache);
|
||||
|
||||
pc = regcache_read_pc (regcache);
|
||||
sw_bp_pc = pc - gdbarch_decr_pc_after_break (gdbarch);
|
||||
|
||||
@@ -2614,33 +2607,29 @@ check_stopped_by_breakpoint (struct lwp_info *lp)
|
||||
{
|
||||
if (siginfo.si_signo == SIGTRAP)
|
||||
{
|
||||
if (GDB_ARCH_IS_TRAP_BRKPT (siginfo.si_code))
|
||||
if (GDB_ARCH_IS_TRAP_BRKPT (siginfo.si_code)
|
||||
&& GDB_ARCH_IS_TRAP_HWBKPT (siginfo.si_code))
|
||||
{
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"CSBB: %s stopped by software "
|
||||
"breakpoint\n",
|
||||
target_pid_to_str (lp->ptid));
|
||||
|
||||
/* Back up the PC if necessary. */
|
||||
if (pc != sw_bp_pc)
|
||||
regcache_write_pc (regcache, sw_bp_pc);
|
||||
|
||||
lp->stop_pc = sw_bp_pc;
|
||||
lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
return 1;
|
||||
/* The si_code is ambiguous on this arch -- check debug
|
||||
registers. */
|
||||
if (!check_stopped_by_watchpoint (lp))
|
||||
lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
}
|
||||
else if (siginfo.si_code == TRAP_HWBKPT)
|
||||
else if (GDB_ARCH_IS_TRAP_BRKPT (siginfo.si_code))
|
||||
{
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"CSBB: %s stopped by hardware "
|
||||
"breakpoint/watchpoint\n",
|
||||
target_pid_to_str (lp->ptid));
|
||||
|
||||
lp->stop_pc = pc;
|
||||
lp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
|
||||
return 1;
|
||||
/* If we determine the LWP stopped for a SW breakpoint,
|
||||
trust it. Particularly don't check watchpoint
|
||||
registers, because at least on s390, we'd find
|
||||
stopped-by-watchpoint as long as there's a watchpoint
|
||||
set. */
|
||||
lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
}
|
||||
else if (GDB_ARCH_IS_TRAP_HWBKPT (siginfo.si_code))
|
||||
{
|
||||
/* This can indicate either a hardware breakpoint or
|
||||
hardware watchpoint. Check debug registers. */
|
||||
if (!check_stopped_by_watchpoint (lp))
|
||||
lp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
|
||||
}
|
||||
else if (siginfo.si_code == TRAP_TRACE)
|
||||
{
|
||||
@@ -2648,6 +2637,13 @@ check_stopped_by_breakpoint (struct lwp_info *lp)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"CSBB: %s stopped by trace\n",
|
||||
target_pid_to_str (lp->ptid));
|
||||
|
||||
/* We may have single stepped an instruction that
|
||||
triggered a watchpoint. In that case, on some
|
||||
architectures (such as x86), instead of TRAP_HWBKPT,
|
||||
si_code indicates TRAP_TRACE, and we need to check
|
||||
the debug registers separately. */
|
||||
check_stopped_by_watchpoint (lp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2658,6 +2654,18 @@ check_stopped_by_breakpoint (struct lwp_info *lp)
|
||||
{
|
||||
/* The LWP was either continued, or stepped a software
|
||||
breakpoint instruction. */
|
||||
lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
}
|
||||
|
||||
if (hardware_breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
|
||||
lp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
|
||||
|
||||
if (lp->stop_reason == TARGET_STOPPED_BY_NO_REASON)
|
||||
check_stopped_by_watchpoint (lp);
|
||||
#endif
|
||||
|
||||
if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT)
|
||||
{
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"CSBB: %s stopped by software breakpoint\n",
|
||||
@@ -2667,25 +2675,25 @@ check_stopped_by_breakpoint (struct lwp_info *lp)
|
||||
if (pc != sw_bp_pc)
|
||||
regcache_write_pc (regcache, sw_bp_pc);
|
||||
|
||||
lp->stop_pc = sw_bp_pc;
|
||||
lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
|
||||
return 1;
|
||||
/* Update this so we record the correct stop PC below. */
|
||||
pc = sw_bp_pc;
|
||||
}
|
||||
|
||||
if (hardware_breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
|
||||
else if (lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
|
||||
{
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"CSBB: stopped by hardware breakpoint %s\n",
|
||||
"CSBB: %s stopped by hardware breakpoint\n",
|
||||
target_pid_to_str (lp->ptid));
|
||||
}
|
||||
else if (lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
|
||||
{
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"CSBB: %s stopped by hardware watchpoint\n",
|
||||
target_pid_to_str (lp->ptid));
|
||||
|
||||
lp->stop_pc = pc;
|
||||
lp->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
lp->stop_pc = pc;
|
||||
}
|
||||
|
||||
|
||||
@@ -3057,7 +3065,7 @@ linux_nat_filter_event (int lwpid, int status)
|
||||
/* An interesting event. */
|
||||
gdb_assert (lp);
|
||||
lp->status = status;
|
||||
save_sigtrap (lp);
|
||||
save_stop_reason (lp);
|
||||
return lp;
|
||||
}
|
||||
|
||||
|
||||
@@ -2426,7 +2426,8 @@ linux_displaced_step_location (struct gdbarch *gdbarch)
|
||||
location. The auxiliary vector gets us the PowerPC-side entry
|
||||
point address instead. */
|
||||
if (target_auxv_search (¤t_target, AT_ENTRY, &addr) <= 0)
|
||||
error (_("Cannot find AT_ENTRY auxiliary vector entry."));
|
||||
throw_error (NOT_SUPPORTED_ERROR,
|
||||
_("Cannot find AT_ENTRY auxiliary vector entry."));
|
||||
|
||||
/* Make certain that the address points at real code, and not a
|
||||
function descriptor. */
|
||||
|
||||
@@ -564,7 +564,6 @@ try_thread_db_load_1 (struct thread_db_info *info)
|
||||
|
||||
/* These are essential. */
|
||||
CHK (TDB_VERBOSE_DLSYM (info, td_ta_map_lwp2thr));
|
||||
CHK (TDB_VERBOSE_DLSYM (info, td_ta_thr_iter));
|
||||
CHK (TDB_VERBOSE_DLSYM (info, td_thr_validate));
|
||||
CHK (TDB_VERBOSE_DLSYM (info, td_thr_get_info));
|
||||
|
||||
@@ -572,10 +571,6 @@ try_thread_db_load_1 (struct thread_db_info *info)
|
||||
TDB_DLSYM (info, td_thr_tls_get_addr);
|
||||
TDB_DLSYM (info, td_thr_tlsbase);
|
||||
|
||||
#undef TDB_VERBOSE_DLSYM
|
||||
#undef TDB_DLSYM
|
||||
#undef CHK
|
||||
|
||||
/* It's best to avoid td_ta_thr_iter if possible. That walks data
|
||||
structures in the inferior's address space that may be corrupted,
|
||||
or, if the target is running, may change while we walk them. If
|
||||
@@ -587,6 +582,15 @@ try_thread_db_load_1 (struct thread_db_info *info)
|
||||
currently on core targets, as it uses ptrace directly. */
|
||||
if (target_has_execution
|
||||
&& linux_proc_task_list_dir_exists (ptid_get_pid (inferior_ptid)))
|
||||
info->td_ta_thr_iter_p = NULL;
|
||||
else
|
||||
CHK (TDB_VERBOSE_DLSYM (info, td_ta_thr_iter));
|
||||
|
||||
#undef TDB_VERBOSE_DLSYM
|
||||
#undef TDB_DLSYM
|
||||
#undef CHK
|
||||
|
||||
if (info->td_ta_thr_iter_p == NULL)
|
||||
{
|
||||
struct lwp_info *lp;
|
||||
int pid = ptid_get_pid (inferior_ptid);
|
||||
@@ -1246,7 +1250,7 @@ find_new_threads_once (struct thread_db_info *info, int iteration,
|
||||
data.new_threads = 0;
|
||||
|
||||
/* See comment in thread_db_update_thread_list. */
|
||||
gdb_assert (!target_has_execution);
|
||||
gdb_assert (info->td_ta_thr_iter_p != NULL);
|
||||
|
||||
TRY
|
||||
{
|
||||
|
||||
@@ -357,13 +357,19 @@ mi_new_thread (struct thread_info *t)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct inferior *inf = find_inferior_ptid (t->ptid);
|
||||
struct cleanup *old_chain;
|
||||
|
||||
gdb_assert (inf);
|
||||
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-created,id=\"%d\",group-id=\"i%d\"",
|
||||
t->global_num, inf->num);
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -380,7 +386,8 @@ mi_thread_exit (struct thread_info *t, int silent)
|
||||
|
||||
mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-exited,id=\"%d\",group-id=\"i%d\"",
|
||||
t->global_num, inf->num);
|
||||
@@ -395,43 +402,62 @@ static void
|
||||
mi_record_changed (struct inferior *inferior, int started)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel, "record-%s,thread-group=\"i%d\"",
|
||||
started ? "started" : "stopped", inferior->num);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
static void
|
||||
mi_inferior_added (struct inferior *inf)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
target_terminal_ours ();
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-group-added,id=\"i%d\"",
|
||||
inf->num);
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
static void
|
||||
mi_inferior_appeared (struct inferior *inf)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
target_terminal_ours ();
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-group-started,id=\"i%d\",pid=\"%d\"",
|
||||
inf->num, inf->pid);
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
static void
|
||||
mi_inferior_exit (struct inferior *inf)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
target_terminal_ours ();
|
||||
if (inf->has_exit_code)
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
|
||||
@@ -439,20 +465,26 @@ mi_inferior_exit (struct inferior *inf)
|
||||
else
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-group-exited,id=\"i%d\"", inf->num);
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
static void
|
||||
mi_inferior_removed (struct inferior *inf)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
target_terminal_ours ();
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-group-removed,id=\"i%d\"",
|
||||
inf->num);
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Return the MI interpreter, if it is active -- either because it's
|
||||
@@ -675,11 +707,13 @@ static void
|
||||
mi_traceframe_changed (int tfnum, int tpnum)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
if (mi_suppress_notification.traceframe)
|
||||
return;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
if (tfnum >= 0)
|
||||
fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
|
||||
@@ -689,6 +723,8 @@ mi_traceframe_changed (int tfnum, int tpnum)
|
||||
fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Emit notification on creating a trace state variable. */
|
||||
@@ -697,14 +733,18 @@ static void
|
||||
mi_tsv_created (const struct trace_state_variable *tsv)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel, "tsv-created,"
|
||||
"name=\"%s\",initial=\"%s\"\n",
|
||||
tsv->name, plongest (tsv->initial_value));
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Emit notification on deleting a trace state variable. */
|
||||
@@ -713,8 +753,10 @@ static void
|
||||
mi_tsv_deleted (const struct trace_state_variable *tsv)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
if (tsv != NULL)
|
||||
fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
|
||||
@@ -723,6 +765,8 @@ mi_tsv_deleted (const struct trace_state_variable *tsv)
|
||||
fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Emit notification on modifying a trace state variable. */
|
||||
@@ -732,8 +776,10 @@ mi_tsv_modified (const struct trace_state_variable *tsv)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
|
||||
struct cleanup *old_chain;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"tsv-modified");
|
||||
@@ -749,6 +795,8 @@ mi_tsv_modified (const struct trace_state_variable *tsv)
|
||||
ui_out_redirect (mi_uiout, NULL);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Emit notification about a created breakpoint. */
|
||||
@@ -758,6 +806,7 @@ mi_breakpoint_created (struct breakpoint *b)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
|
||||
struct cleanup *old_chain;
|
||||
|
||||
if (mi_suppress_notification.breakpoint)
|
||||
return;
|
||||
@@ -765,7 +814,9 @@ mi_breakpoint_created (struct breakpoint *b)
|
||||
if (b->number <= 0)
|
||||
return;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"breakpoint-created");
|
||||
/* We want the output from gdb_breakpoint_query to go to
|
||||
@@ -788,6 +839,8 @@ mi_breakpoint_created (struct breakpoint *b)
|
||||
ui_out_redirect (mi_uiout, NULL);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Emit notification about deleted breakpoint. */
|
||||
@@ -796,6 +849,7 @@ static void
|
||||
mi_breakpoint_deleted (struct breakpoint *b)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
if (mi_suppress_notification.breakpoint)
|
||||
return;
|
||||
@@ -803,12 +857,15 @@ mi_breakpoint_deleted (struct breakpoint *b)
|
||||
if (b->number <= 0)
|
||||
return;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
|
||||
b->number);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Emit notification about modified breakpoint. */
|
||||
@@ -818,6 +875,7 @@ mi_breakpoint_modified (struct breakpoint *b)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
|
||||
struct cleanup *old_chain;
|
||||
|
||||
if (mi_suppress_notification.breakpoint)
|
||||
return;
|
||||
@@ -825,7 +883,9 @@ mi_breakpoint_modified (struct breakpoint *b)
|
||||
if (b->number <= 0)
|
||||
return;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"breakpoint-modified");
|
||||
/* We want the output from gdb_breakpoint_query to go to
|
||||
@@ -848,6 +908,8 @@ mi_breakpoint_modified (struct breakpoint *b)
|
||||
ui_out_redirect (mi_uiout, NULL);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -936,7 +998,7 @@ mi_on_resume (ptid_t ptid)
|
||||
for MI3, and may be removed even earlier. SYNC_EXECUTION is
|
||||
checked here because we only need to emit a prompt if a
|
||||
synchronous command was issued when the target is async. */
|
||||
if (!target_is_async_p () || sync_execution)
|
||||
if (!target_can_async_p () || sync_execution)
|
||||
fputs_unfiltered ("(gdb) \n", raw_stdout);
|
||||
}
|
||||
gdb_flush (raw_stdout);
|
||||
@@ -947,8 +1009,10 @@ mi_solib_loaded (struct so_list *solib)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct ui_out *uiout = interp_ui_out (top_level_interpreter ());
|
||||
struct cleanup *old_chain;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel, "library-loaded");
|
||||
|
||||
@@ -960,12 +1024,15 @@ mi_solib_loaded (struct so_list *solib)
|
||||
ui_out_field_int (uiout, "symbols-loaded", solib->symbols_loaded);
|
||||
if (!gdbarch_has_global_solist (target_gdbarch ()))
|
||||
{
|
||||
ui_out_field_fmt (uiout, "thread-group", "i%d", current_inferior ()->num);
|
||||
ui_out_field_fmt (uiout, "thread-group", "i%d",
|
||||
current_inferior ()->num);
|
||||
}
|
||||
|
||||
ui_out_redirect (uiout, NULL);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -973,8 +1040,10 @@ mi_solib_unloaded (struct so_list *solib)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct ui_out *uiout = interp_ui_out (top_level_interpreter ());
|
||||
struct cleanup *old_chain;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel, "library-unloaded");
|
||||
|
||||
@@ -985,12 +1054,15 @@ mi_solib_unloaded (struct so_list *solib)
|
||||
ui_out_field_string (uiout, "host-name", solib->so_name);
|
||||
if (!gdbarch_has_global_solist (target_gdbarch ()))
|
||||
{
|
||||
ui_out_field_fmt (uiout, "thread-group", "i%d", current_inferior ()->num);
|
||||
ui_out_field_fmt (uiout, "thread-group", "i%d",
|
||||
current_inferior ()->num);
|
||||
}
|
||||
|
||||
ui_out_redirect (uiout, NULL);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Emit notification about the command parameter change. */
|
||||
@@ -1000,11 +1072,13 @@ mi_command_param_changed (const char *param, const char *value)
|
||||
{
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
|
||||
struct cleanup *old_chain;
|
||||
|
||||
if (mi_suppress_notification.cmd_param_changed)
|
||||
return;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"cmd-param-changed");
|
||||
@@ -1017,6 +1091,8 @@ mi_command_param_changed (const char *param, const char *value)
|
||||
ui_out_redirect (mi_uiout, NULL);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
/* Emit notification about the target memory change. */
|
||||
@@ -1028,11 +1104,13 @@ mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
|
||||
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
|
||||
struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
|
||||
struct obj_section *sec;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
if (mi_suppress_notification.memory)
|
||||
return;
|
||||
|
||||
target_terminal_ours ();
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"memory-changed");
|
||||
@@ -1058,6 +1136,8 @@ mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
|
||||
ui_out_redirect (mi_uiout, NULL);
|
||||
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1068,12 +1148,17 @@ report_initial_inferior (struct inferior *inf, void *closure)
|
||||
and top_level_interpreter_data is set, we cannot call
|
||||
it here. */
|
||||
struct mi_interp *mi = (struct mi_interp *) closure;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
target_terminal_ours ();
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-group-added,id=\"i%d\"",
|
||||
inf->num);
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -415,6 +415,8 @@ run_one_inferior (struct inferior *inf, void *arg)
|
||||
{
|
||||
int start_p = *(int *) arg;
|
||||
const char *run_cmd = start_p ? "start" : "run";
|
||||
struct target_ops *run_target = find_run_target ();
|
||||
int async_p = mi_async && run_target->to_can_async_p (run_target);
|
||||
|
||||
if (inf->pid != 0)
|
||||
{
|
||||
@@ -435,8 +437,8 @@ run_one_inferior (struct inferior *inf, void *arg)
|
||||
switch_to_thread (null_ptid);
|
||||
set_current_program_space (inf->pspace);
|
||||
}
|
||||
mi_execute_cli_command (run_cmd, mi_async_p (),
|
||||
mi_async_p () ? "&" : NULL);
|
||||
mi_execute_cli_command (run_cmd, async_p,
|
||||
async_p ? "&" : NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -489,9 +491,11 @@ mi_cmd_exec_run (char *command, char **argv, int argc)
|
||||
else
|
||||
{
|
||||
const char *run_cmd = start_p ? "start" : "run";
|
||||
struct target_ops *run_target = find_run_target ();
|
||||
int async_p = mi_async && run_target->to_can_async_p (run_target);
|
||||
|
||||
mi_execute_cli_command (run_cmd, mi_async_p (),
|
||||
mi_async_p () ? "&" : NULL);
|
||||
mi_execute_cli_command (run_cmd, async_p,
|
||||
async_p ? "&" : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2171,12 +2175,17 @@ mi_execute_command (const char *cmd, int from_tty)
|
||||
if (report_change)
|
||||
{
|
||||
struct thread_info *ti = inferior_thread ();
|
||||
struct cleanup *old_chain;
|
||||
|
||||
old_chain = make_cleanup_restore_target_terminal ();
|
||||
target_terminal_ours_for_output ();
|
||||
|
||||
target_terminal_ours ();
|
||||
fprintf_unfiltered (mi->event_channel,
|
||||
"thread-selected,id=\"%d\"",
|
||||
ti->global_num);
|
||||
gdb_flush (mi->event_channel);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,14 +119,14 @@ struct buffer;
|
||||
/* The x86 kernel gets some of the si_code values backwards, like
|
||||
this:
|
||||
|
||||
| what | si_code |
|
||||
|------------------------------------------+------------|
|
||||
| software breakpoints (int3) | SI_KERNEL |
|
||||
| single-steps | TRAP_TRACE |
|
||||
| single-stepping a syscall | TRAP_BRKPT |
|
||||
| user sent SIGTRAP | 0 |
|
||||
| exec SIGTRAP (when no PTRACE_EVENT_EXEC) | 0 |
|
||||
| hardware breakpoints/watchpoints | TRAP_HWBPT |
|
||||
| what | si_code |
|
||||
|------------------------------------------+-------------|
|
||||
| software breakpoints (int3) | SI_KERNEL |
|
||||
| single-steps | TRAP_TRACE |
|
||||
| single-stepping a syscall | TRAP_BRKPT |
|
||||
| user sent SIGTRAP | 0 |
|
||||
| exec SIGTRAP (when no PTRACE_EVENT_EXEC) | 0 |
|
||||
| hardware breakpoints/watchpoints | TRAP_HWBKPT |
|
||||
|
||||
That is, it reports SI_KERNEL for software breakpoints (and only
|
||||
for those), and TRAP_BRKPT for single-stepping a syscall... If the
|
||||
@@ -140,14 +140,35 @@ struct buffer;
|
||||
in SPU code on a Cell/B.E. However, SI_KERNEL is never seen
|
||||
on a SIGTRAP for any other reason.
|
||||
|
||||
The generic Linux target code should use GDB_ARCH_IS_TRAP_BRKPT
|
||||
instead of TRAP_BRKPT to abstract out these peculiarities. */
|
||||
The MIPS kernel up until 4.5 used SI_KERNEL for all kernel
|
||||
generated traps. Since:
|
||||
|
||||
- MIPS doesn't do hardware single-step.
|
||||
- We don't need to care about exec SIGTRAPs --- we assume
|
||||
PTRACE_EVENT_EXEC is available.
|
||||
- The MIPS kernel doesn't support hardware breakpoints.
|
||||
|
||||
on MIPS, all we need to care about is distinguishing between
|
||||
software breakpoints and hardware watchpoints, which can be done by
|
||||
peeking the debug registers.
|
||||
|
||||
Beginning with Linux 4.6, the MIPS port reports proper TRAP_BRKPT and
|
||||
TRAP_HWBKPT codes, so we also match them.
|
||||
|
||||
The generic Linux target code should use GDB_ARCH_IS_TRAP_* instead
|
||||
of TRAP_* to abstract out these peculiarities. */
|
||||
#if defined __i386__ || defined __x86_64__
|
||||
# define GDB_ARCH_IS_TRAP_BRKPT(X) ((X) == SI_KERNEL)
|
||||
# define GDB_ARCH_IS_TRAP_HWBKPT(X) ((X) == TRAP_HWBKPT)
|
||||
#elif defined __powerpc__
|
||||
# define GDB_ARCH_IS_TRAP_BRKPT(X) ((X) == SI_KERNEL || (X) == TRAP_BRKPT)
|
||||
# define GDB_ARCH_IS_TRAP_HWBKPT(X) ((X) == TRAP_HWBKPT)
|
||||
#elif defined __mips__
|
||||
# define GDB_ARCH_IS_TRAP_BRKPT(X) ((X) == SI_KERNEL || (X) == TRAP_BRKPT)
|
||||
# define GDB_ARCH_IS_TRAP_HWBKPT(X) ((X) == SI_KERNEL || (X) == TRAP_HWBKPT)
|
||||
#else
|
||||
# define GDB_ARCH_IS_TRAP_BRKPT(X) ((X) == TRAP_BRKPT)
|
||||
# define GDB_ARCH_IS_TRAP_HWBKPT(X) ((X) == TRAP_HWBKPT)
|
||||
#endif
|
||||
|
||||
#ifndef TRAP_HWBKPT
|
||||
|
||||
@@ -1717,27 +1717,25 @@ message == an error message without a stack will be printed."),
|
||||
progname = concat (ldirname (python_libdir), SLASH_STRING, "bin",
|
||||
SLASH_STRING, "python", NULL);
|
||||
#ifdef IS_PY3K
|
||||
oldloc = setlocale (LC_ALL, NULL);
|
||||
oldloc = xstrdup (setlocale (LC_ALL, NULL));
|
||||
setlocale (LC_ALL, "");
|
||||
progsize = strlen (progname);
|
||||
if (progsize == (size_t) -1)
|
||||
{
|
||||
fprintf (stderr, "Could not convert python path to string\n");
|
||||
return;
|
||||
}
|
||||
progname_copy = (wchar_t *) PyMem_Malloc ((progsize + 1) * sizeof (wchar_t));
|
||||
if (!progname_copy)
|
||||
{
|
||||
xfree (oldloc);
|
||||
fprintf (stderr, "out of memory\n");
|
||||
return;
|
||||
}
|
||||
count = mbstowcs (progname_copy, progname, progsize + 1);
|
||||
if (count == (size_t) -1)
|
||||
{
|
||||
xfree (oldloc);
|
||||
fprintf (stderr, "Could not convert python path to string\n");
|
||||
return;
|
||||
}
|
||||
setlocale (LC_ALL, oldloc);
|
||||
xfree (oldloc);
|
||||
|
||||
/* Note that Py_SetProgramName expects the string it is passed to
|
||||
remain alive for the duration of the program's execution, so
|
||||
|
||||
46
gdb/remote.c
46
gdb/remote.c
@@ -389,6 +389,9 @@ struct remote_state
|
||||
|
||||
int last_sent_step;
|
||||
|
||||
/* The execution direction of the last resume we got. */
|
||||
enum exec_direction_kind last_resume_exec_dir;
|
||||
|
||||
char *finished_object;
|
||||
char *finished_annex;
|
||||
ULONGEST finished_offset;
|
||||
@@ -477,6 +480,7 @@ new_remote_state (void)
|
||||
result->buf = (char *) xmalloc (result->buf_size);
|
||||
result->remote_traceframe_number = -1;
|
||||
result->last_sent_signal = GDB_SIGNAL_0;
|
||||
result->last_resume_exec_dir = EXEC_FORWARD;
|
||||
result->fs_pid = -1;
|
||||
|
||||
return result;
|
||||
@@ -4017,6 +4021,25 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
|
||||
if (packet_support (PACKET_QAllow) != PACKET_DISABLE)
|
||||
remote_set_permissions (target);
|
||||
|
||||
/* gdbserver < 7.7 (before its fix from 2013-12-11) did reply to any
|
||||
unknown 'v' packet with string "OK". "OK" gets interpreted by GDB
|
||||
as a reply to known packet. For packet "vFile:setfs:" it is an
|
||||
invalid reply and GDB would return error in
|
||||
remote_hostio_set_filesystem, making remote files access impossible.
|
||||
Disable "vFile:setfs:" in such case. Do not disable other 'v' packets as
|
||||
other "vFile" packets get correctly detected even on gdbserver < 7.7. */
|
||||
{
|
||||
const char v_mustreplyempty[] = "vMustReplyEmpty";
|
||||
|
||||
putpkt (v_mustreplyempty);
|
||||
getpkt (&rs->buf, &rs->buf_size, 0);
|
||||
if (strcmp (rs->buf, "OK") == 0)
|
||||
remote_protocol_packets[PACKET_vFile_setfs].support = PACKET_DISABLE;
|
||||
else if (strcmp (rs->buf, "") != 0)
|
||||
error (_("Remote replied unexpectedly to '%s': %s"), v_mustreplyempty,
|
||||
rs->buf);
|
||||
}
|
||||
|
||||
/* Next, we possibly activate noack mode.
|
||||
|
||||
If the QStartNoAckMode packet configuration is set to AUTO,
|
||||
@@ -4928,6 +4951,8 @@ remote_open_1 (const char *name, int from_tty,
|
||||
rs->continue_thread = not_sent_ptid;
|
||||
rs->remote_traceframe_number = -1;
|
||||
|
||||
rs->last_resume_exec_dir = EXEC_FORWARD;
|
||||
|
||||
/* Probe for ability to use "ThreadInfo" query, as required. */
|
||||
rs->use_threadinfo_query = 1;
|
||||
rs->use_threadextra_query = 1;
|
||||
@@ -5563,6 +5588,8 @@ remote_resume (struct target_ops *ops,
|
||||
rs->last_sent_signal = siggnal;
|
||||
rs->last_sent_step = step;
|
||||
|
||||
rs->last_resume_exec_dir = execution_direction;
|
||||
|
||||
/* The vCont packet doesn't need to specify threads via Hc. */
|
||||
/* No reverse support (yet) for vCont. */
|
||||
if (execution_direction != EXEC_REVERSE)
|
||||
@@ -6166,7 +6193,12 @@ remove_new_fork_children (struct threads_listing_context *context)
|
||||
fork child threads from the CONTEXT list. */
|
||||
ALL_NON_EXITED_THREADS (thread)
|
||||
{
|
||||
struct target_waitstatus *ws = &thread->pending_follow;
|
||||
struct target_waitstatus *ws;
|
||||
|
||||
if (thread->suspend.waitstatus_pending_p)
|
||||
ws = &thread->suspend.waitstatus;
|
||||
else
|
||||
ws = &thread->pending_follow;
|
||||
|
||||
if (is_pending_fork_parent (ws, pid, thread->ptid))
|
||||
{
|
||||
@@ -13013,6 +13045,17 @@ remote_can_do_single_step (struct target_ops *ops)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Implementation of the to_execution_direction method for the remote
|
||||
target. */
|
||||
|
||||
static enum exec_direction_kind
|
||||
remote_execution_direction (struct target_ops *self)
|
||||
{
|
||||
struct remote_state *rs = get_remote_state ();
|
||||
|
||||
return rs->last_resume_exec_dir;
|
||||
}
|
||||
|
||||
static void
|
||||
init_remote_ops (void)
|
||||
{
|
||||
@@ -13158,6 +13201,7 @@ Specify the serial device it is connected to\n\
|
||||
remote_ops.to_remove_vfork_catchpoint = remote_remove_vfork_catchpoint;
|
||||
remote_ops.to_insert_exec_catchpoint = remote_insert_exec_catchpoint;
|
||||
remote_ops.to_remove_exec_catchpoint = remote_remove_exec_catchpoint;
|
||||
remote_ops.to_execution_direction = remote_execution_direction;
|
||||
}
|
||||
|
||||
/* Set up the extended remote vector by making a copy of the standard
|
||||
|
||||
39
gdb/stack.c
39
gdb/stack.c
@@ -1509,27 +1509,32 @@ frame_info (char *addr_exp, int from_tty)
|
||||
wrap_here (" ");
|
||||
printf_filtered ("saved %s = ", pc_regname);
|
||||
|
||||
TRY
|
||||
if (!frame_id_p (frame_unwind_caller_id (fi)))
|
||||
val_print_unavailable (gdb_stdout);
|
||||
else
|
||||
{
|
||||
caller_pc = frame_unwind_caller_pc (fi);
|
||||
caller_pc_p = 1;
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ERROR)
|
||||
{
|
||||
switch (ex.error)
|
||||
TRY
|
||||
{
|
||||
case NOT_AVAILABLE_ERROR:
|
||||
val_print_unavailable (gdb_stdout);
|
||||
break;
|
||||
case OPTIMIZED_OUT_ERROR:
|
||||
val_print_not_saved (gdb_stdout);
|
||||
break;
|
||||
default:
|
||||
fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
|
||||
break;
|
||||
caller_pc = frame_unwind_caller_pc (fi);
|
||||
caller_pc_p = 1;
|
||||
}
|
||||
CATCH (ex, RETURN_MASK_ERROR)
|
||||
{
|
||||
switch (ex.error)
|
||||
{
|
||||
case NOT_AVAILABLE_ERROR:
|
||||
val_print_unavailable (gdb_stdout);
|
||||
break;
|
||||
case OPTIMIZED_OUT_ERROR:
|
||||
val_print_not_saved (gdb_stdout);
|
||||
break;
|
||||
default:
|
||||
fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
END_CATCH
|
||||
}
|
||||
END_CATCH
|
||||
|
||||
if (caller_pc_p)
|
||||
fputs_filtered (paddress (gdbarch, caller_pc), gdb_stdout);
|
||||
|
||||
@@ -3293,19 +3293,21 @@ find_pc_overlay (CORE_ADDR pc)
|
||||
struct obj_section *osect, *best_match = NULL;
|
||||
|
||||
if (overlay_debugging)
|
||||
ALL_OBJSECTIONS (objfile, osect)
|
||||
if (section_is_overlay (osect))
|
||||
{
|
||||
if (pc_in_mapped_range (pc, osect))
|
||||
{
|
||||
ALL_OBJSECTIONS (objfile, osect)
|
||||
if (section_is_overlay (osect))
|
||||
{
|
||||
if (section_is_mapped (osect))
|
||||
return osect;
|
||||
else
|
||||
if (pc_in_mapped_range (pc, osect))
|
||||
{
|
||||
if (section_is_mapped (osect))
|
||||
return osect;
|
||||
else
|
||||
best_match = osect;
|
||||
}
|
||||
else if (pc_in_unmapped_range (pc, osect))
|
||||
best_match = osect;
|
||||
}
|
||||
else if (pc_in_unmapped_range (pc, osect))
|
||||
best_match = osect;
|
||||
}
|
||||
}
|
||||
return best_match;
|
||||
}
|
||||
|
||||
@@ -3320,9 +3322,11 @@ find_pc_mapped_section (CORE_ADDR pc)
|
||||
struct obj_section *osect;
|
||||
|
||||
if (overlay_debugging)
|
||||
ALL_OBJSECTIONS (objfile, osect)
|
||||
if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
|
||||
return osect;
|
||||
{
|
||||
ALL_OBJSECTIONS (objfile, osect)
|
||||
if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
|
||||
return osect;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -3338,31 +3342,33 @@ list_overlays_command (char *args, int from_tty)
|
||||
struct obj_section *osect;
|
||||
|
||||
if (overlay_debugging)
|
||||
ALL_OBJSECTIONS (objfile, osect)
|
||||
{
|
||||
ALL_OBJSECTIONS (objfile, osect)
|
||||
if (section_is_mapped (osect))
|
||||
{
|
||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||
const char *name;
|
||||
bfd_vma lma, vma;
|
||||
int size;
|
||||
{
|
||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||
const char *name;
|
||||
bfd_vma lma, vma;
|
||||
int size;
|
||||
|
||||
vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
|
||||
lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
|
||||
size = bfd_get_section_size (osect->the_bfd_section);
|
||||
name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
|
||||
vma = bfd_section_vma (objfile->obfd, osect->the_bfd_section);
|
||||
lma = bfd_section_lma (objfile->obfd, osect->the_bfd_section);
|
||||
size = bfd_get_section_size (osect->the_bfd_section);
|
||||
name = bfd_section_name (objfile->obfd, osect->the_bfd_section);
|
||||
|
||||
printf_filtered ("Section %s, loaded at ", name);
|
||||
fputs_filtered (paddress (gdbarch, lma), gdb_stdout);
|
||||
puts_filtered (" - ");
|
||||
fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout);
|
||||
printf_filtered (", mapped at ");
|
||||
fputs_filtered (paddress (gdbarch, vma), gdb_stdout);
|
||||
puts_filtered (" - ");
|
||||
fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout);
|
||||
puts_filtered ("\n");
|
||||
printf_filtered ("Section %s, loaded at ", name);
|
||||
fputs_filtered (paddress (gdbarch, lma), gdb_stdout);
|
||||
puts_filtered (" - ");
|
||||
fputs_filtered (paddress (gdbarch, lma + size), gdb_stdout);
|
||||
printf_filtered (", mapped at ");
|
||||
fputs_filtered (paddress (gdbarch, vma), gdb_stdout);
|
||||
puts_filtered (" - ");
|
||||
fputs_filtered (paddress (gdbarch, vma + size), gdb_stdout);
|
||||
puts_filtered ("\n");
|
||||
|
||||
nmapped++;
|
||||
}
|
||||
nmapped++;
|
||||
}
|
||||
}
|
||||
if (nmapped == 0)
|
||||
printf_filtered (_("No sections are mapped.\n"));
|
||||
}
|
||||
|
||||
@@ -1,3 +1,91 @@
|
||||
2016-05-25 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/19828
|
||||
* gdb.threads/clone-attach-detach.c: New file.
|
||||
* gdb.threads/clone-attach-detach.exp: New file.
|
||||
* gdb.threads/attach-many-short-lived-threads.exp: Skip.
|
||||
|
||||
2016-05-18 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* gdb.mi/mi-threads-interrupt.c: New file.
|
||||
* gdb.mi/mi-threads-interrupt.exp: New file.
|
||||
|
||||
2016-05-17 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
PR gdb/18077
|
||||
* gdb.mi/mi-async-run.exp: New file.
|
||||
* gdb.mi/mi-async-run.c: New file.
|
||||
|
||||
2016-03-31 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/19858
|
||||
* gdb.base/jit-main.c: Include unistd.h.
|
||||
(ATTACH): Define to 0 if not already defined.
|
||||
(wait_for_gdb, mypid): New globals.
|
||||
(WAIT_FOR_GDB): New macro.
|
||||
(MAIN): Set an alarm. Store the process's pid. Wait for GDB at
|
||||
some breakpoint locations.
|
||||
* gdb.base/jit.exp (clean_reattach, continue_to_test_location):
|
||||
New procedures.
|
||||
(one_jit_test): Add REATTACH parameter, and handle it. Use
|
||||
continue_to_test_location.
|
||||
(top level): Test attach, and adjusts calls to one_jit_test.
|
||||
|
||||
2016-03-31 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/19858
|
||||
* gdb.base/jit.exp (compile_jit_test): Add intro comment. Add
|
||||
BINSUFFIX parameter, and handle it.
|
||||
(top level): Adjust calls compile_jit_test.
|
||||
|
||||
2016-03-17 Markus Metzger <markus.t.metzger@intel.com>
|
||||
|
||||
PR gdb/19829
|
||||
* gdb.btrace/tailcall-only.exp: New.
|
||||
* gdb.btrace/tailcall-only.c: New.
|
||||
* gdb.btrace/x86_64-tailcall-only.S: New.
|
||||
* gdb.btrace/i686-tailcall-only.S: New.
|
||||
|
||||
2016-02-16 Don Breazeal <donb@codesourcery.com>
|
||||
|
||||
PR remote/19496
|
||||
* gdb.threads/forking-threads-plus-breakpoint.exp (do_test):
|
||||
Remove kfail for PR remote/19496.
|
||||
|
||||
2016-02-15 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb.arch/i386-prologue.c: Add missing prototypes.
|
||||
|
||||
2016-02-15 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb.arch/i386-gnu-cfi.exp: Use standard_output_file.
|
||||
* gdb.arch/i386-prologue.exp: Likewise.
|
||||
* gdb.arch/i386-size.exp: Likewise.
|
||||
|
||||
2016-02-15 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* i386-biarch-core.exp: Define corefile using
|
||||
standard_output_file.
|
||||
|
||||
2016-02-14 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
Fix compatibility with recent gfortran-5.3.1.
|
||||
* gdb.fortran/vla-history.exp (print vla1 allocated)
|
||||
(print vla2 allocated, print $2, print $3): Remove
|
||||
(print $4): Rename to ...
|
||||
(print $2): ... here.
|
||||
(print $9): Rename to ...
|
||||
(print $5): ... here.
|
||||
(print $10): Rename to ...
|
||||
(print $6): ... here.
|
||||
* gdb.fortran/vla.f90: Add pvla initialization.
|
||||
|
||||
2016-02-14 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb.fortran/vla-value-sub-finish.exp (set max-value-size 1024*1024):
|
||||
New test.
|
||||
* gdb.fortran/vla-value-sub.exp: Likewise.
|
||||
|
||||
2016-02-09 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
PR breakpoints/19546
|
||||
|
||||
@@ -40,7 +40,7 @@ gdb_test_multiple "complete set gnutarget " $test {
|
||||
}
|
||||
|
||||
set corebz2file ${srcdir}/${subdir}/${testfile}.core.bz2
|
||||
set corefile ${objdir}/${subdir}/${testfile}.core
|
||||
set corefile [standard_output_file ${testfile}.core]
|
||||
# Entry point of the original executable.
|
||||
set address 0x400078
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ if { ![is_x86_like_target] } then {
|
||||
set testfile "i386-gnu-cfi"
|
||||
set srcfilec ${testfile}.c
|
||||
set srcfileasm ${testfile}-asm.S
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
set binfile [standard_output_file ${testfile}]
|
||||
|
||||
# some targets have leading underscores on assembly symbols.
|
||||
set additional_flags [gdb_target_symbol_prefix_flags]
|
||||
|
||||
@@ -27,6 +27,10 @@ void gdb1253 (void);
|
||||
void gdb1718 (void);
|
||||
void gdb1338 (void);
|
||||
void jump_at_beginning (void);
|
||||
void standard (void);
|
||||
void stack_align_ecx (void);
|
||||
void stack_align_edx (void);
|
||||
void stack_align_eax (void);
|
||||
|
||||
int
|
||||
main (void)
|
||||
|
||||
@@ -28,7 +28,7 @@ if { ![is_x86_like_target] } then {
|
||||
|
||||
set testfile "i386-prologue"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
set binfile [standard_output_file ${testfile}]
|
||||
|
||||
# some targets have leading underscores on assembly symbols.
|
||||
set additional_flags [gdb_target_symbol_prefix_flags]
|
||||
|
||||
@@ -27,7 +27,7 @@ if { ![is_x86_like_target] } then {
|
||||
|
||||
set testfile "i386-size"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
set binfile [standard_output_file ${testfile}]
|
||||
|
||||
# some targets have leading underscores on assembly symbols.
|
||||
set additional_flags [gdb_target_symbol_prefix_flags]
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* ElfW is coming from linux. On other platforms it does not exist.
|
||||
Let us define it here. */
|
||||
@@ -116,10 +117,22 @@ update_locations (const void *const addr, int idx)
|
||||
}
|
||||
}
|
||||
|
||||
/* Defined by the .exp file if testing attach. */
|
||||
#ifndef ATTACH
|
||||
#define ATTACH 0
|
||||
#endif
|
||||
|
||||
#ifndef MAIN
|
||||
#define MAIN main
|
||||
#endif
|
||||
|
||||
/* Used to spin waiting for GDB. */
|
||||
volatile int wait_for_gdb = ATTACH;
|
||||
#define WAIT_FOR_GDB while (wait_for_gdb)
|
||||
|
||||
/* The current process's PID. GDB retrieves this. */
|
||||
int mypid;
|
||||
|
||||
int
|
||||
MAIN (int argc, char *argv[])
|
||||
{
|
||||
@@ -127,6 +140,10 @@ MAIN (int argc, char *argv[])
|
||||
const char *libname = NULL;
|
||||
int count = 0;
|
||||
|
||||
alarm (300);
|
||||
|
||||
mypid = getpid ();
|
||||
|
||||
count = count; /* gdb break here 0 */
|
||||
|
||||
if (argc < 2)
|
||||
@@ -190,7 +207,7 @@ MAIN (int argc, char *argv[])
|
||||
__jit_debug_register_code ();
|
||||
}
|
||||
|
||||
i = 0; /* gdb break here 1 */
|
||||
WAIT_FOR_GDB; i = 0; /* gdb break here 1 */
|
||||
|
||||
/* Now unregister them all in reverse order. */
|
||||
while (__jit_debug_descriptor.relevant_entry != NULL)
|
||||
@@ -215,5 +232,5 @@ MAIN (int argc, char *argv[])
|
||||
free (entry);
|
||||
}
|
||||
}
|
||||
return 0; /* gdb break here 2 */
|
||||
WAIT_FOR_GDB; return 0; /* gdb break here 2 */
|
||||
}
|
||||
|
||||
@@ -24,18 +24,19 @@ if {[get_compiler_info]} {
|
||||
return 1
|
||||
}
|
||||
|
||||
#
|
||||
# test running programs
|
||||
#
|
||||
# Compile the testcase program and library. BINSUFFIX is the suffix
|
||||
# to append to the program and library filenames, to make them unique
|
||||
# between invocations. OPTIONS is passed to gdb_compile when
|
||||
# compiling the program.
|
||||
|
||||
proc compile_jit_test {testname options} {
|
||||
proc compile_jit_test {testname binsuffix options} {
|
||||
global testfile srcfile binfile srcdir subdir
|
||||
global solib_testfile solib_srcfile solib_binfile solib_binfile_test_msg
|
||||
global solib_binfile_target
|
||||
|
||||
set testfile jit-main
|
||||
set srcfile ${testfile}.c
|
||||
set binfile [standard_output_file $testfile]
|
||||
set binfile [standard_output_file $testfile$binsuffix]
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
|
||||
executable [concat debug $options]] != "" } {
|
||||
untested $testname
|
||||
@@ -44,8 +45,8 @@ proc compile_jit_test {testname options} {
|
||||
|
||||
set solib_testfile "jit-solib"
|
||||
set solib_srcfile "${srcdir}/${subdir}/${solib_testfile}.c"
|
||||
set solib_binfile [standard_output_file ${solib_testfile}.so]
|
||||
set solib_binfile_test_msg "SHLIBDIR/${solib_testfile}.so"
|
||||
set solib_binfile [standard_output_file ${solib_testfile}$binsuffix.so]
|
||||
set solib_binfile_test_msg "SHLIBDIR/${solib_testfile}$binsuffix.so"
|
||||
|
||||
# Note: compiling without debug info: the library goes through
|
||||
# symbol renaming by munging on its symbol table, and that
|
||||
@@ -65,7 +66,49 @@ proc compile_jit_test {testname options} {
|
||||
return 0
|
||||
}
|
||||
|
||||
proc one_jit_test {count match_str} {
|
||||
# Detach, restart GDB, and re-attach to the program.
|
||||
|
||||
proc clean_reattach {} {
|
||||
global decimal gdb_prompt srcfile testfile
|
||||
|
||||
# Get PID of test program.
|
||||
set testpid -1
|
||||
set test "get inferior process ID"
|
||||
gdb_test_multiple "p mypid" $test {
|
||||
-re ".* = ($decimal).*$gdb_prompt $" {
|
||||
set testpid $expect_out(1,string)
|
||||
pass $test
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test_no_output "set var wait_for_gdb = 1"
|
||||
gdb_test "detach" "Detaching from .*"
|
||||
|
||||
clean_restart $testfile
|
||||
|
||||
set test "attach"
|
||||
gdb_test_multiple "attach $testpid" "$test" {
|
||||
-re "Attaching to program.*.*main.*at .*$srcfile:.*$gdb_prompt $" {
|
||||
pass "$test"
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test_no_output "set var wait_for_gdb = 0"
|
||||
}
|
||||
|
||||
# Continue to LOCATION in the program. If REATTACH, detach and
|
||||
# re-attach to the program from scratch.
|
||||
proc continue_to_test_location {location reattach} {
|
||||
gdb_breakpoint [gdb_get_line_number $location]
|
||||
gdb_continue_to_breakpoint $location
|
||||
if {$reattach} {
|
||||
with_test_prefix "$location" {
|
||||
clean_reattach
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc one_jit_test {count match_str reattach} {
|
||||
with_test_prefix "one_jit_test-$count" {
|
||||
global verbose testfile solib_binfile_target solib_binfile_test_msg
|
||||
|
||||
@@ -90,8 +133,7 @@ proc one_jit_test {count match_str} {
|
||||
gdb_test_no_output "set var libname = \"$solib_binfile_target\"" "set var libname = \"$solib_binfile_test_msg\""
|
||||
gdb_test_no_output "set var count = $count"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "break here 1"]
|
||||
gdb_continue_to_breakpoint "break here 1"
|
||||
continue_to_test_location "break here 1" $reattach
|
||||
|
||||
gdb_test "info function ^jit_function" "$match_str"
|
||||
|
||||
@@ -101,25 +143,39 @@ proc one_jit_test {count match_str} {
|
||||
gdb_test "maintenance info break"
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "break here 2"]
|
||||
gdb_continue_to_breakpoint "break here 2"
|
||||
continue_to_test_location "break here 2" $reattach
|
||||
|
||||
# All jit librares must have been unregistered
|
||||
gdb_test "info function jit_function" \
|
||||
"All functions matching regular expression \"jit_function\":"
|
||||
}
|
||||
}
|
||||
|
||||
if {[compile_jit_test jit.exp {}] < 0} {
|
||||
if {[compile_jit_test jit.exp "" {}] < 0} {
|
||||
return
|
||||
}
|
||||
one_jit_test 1 "${hex} jit_function_0000"
|
||||
one_jit_test 2 "${hex} jit_function_0000\[\r\n\]+${hex} jit_function_0001"
|
||||
one_jit_test 1 "${hex} jit_function_0000" 0
|
||||
one_jit_test 2 "${hex} jit_function_0000\[\r\n\]+${hex} jit_function_0001" 0
|
||||
|
||||
with_test_prefix PIE {
|
||||
if {[compile_jit_test "jit.exp PIE tests" \
|
||||
{additional_flags=-fPIE ldflags=-pie}] < 0} {
|
||||
# Test attaching to an inferior with some JIT libraries already
|
||||
# registered. We reuse the normal test, and detach/reattach at
|
||||
# specific interesting points.
|
||||
if {[can_spawn_for_attach]} {
|
||||
if {[compile_jit_test "jit.exp attach tests" \
|
||||
"-attach" {additional_flags=-DATTACH=1}] < 0} {
|
||||
return
|
||||
}
|
||||
|
||||
one_jit_test 1 "${hex} jit_function_0000"
|
||||
with_test_prefix attach {
|
||||
one_jit_test 2 "${hex} jit_function_0000\[\r\n\]+${hex} jit_function_0001" 1
|
||||
}
|
||||
}
|
||||
|
||||
with_test_prefix PIE {
|
||||
if {[compile_jit_test "jit.exp PIE tests" \
|
||||
"-pie" {additional_flags=-fPIE ldflags=-pie}] < 0} {
|
||||
return
|
||||
}
|
||||
|
||||
one_jit_test 1 "${hex} jit_function_0000" 0
|
||||
}
|
||||
|
||||
447
gdb/testsuite/gdb.btrace/i686-tailcall-only.S
Normal file
447
gdb/testsuite/gdb.btrace/i686-tailcall-only.S
Normal file
@@ -0,0 +1,447 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
This file has been generated using:
|
||||
gcc -m32 -march=i686 -S -O2 -dA -g tailcall-only.c -o i686-tailcall-only.S
|
||||
*/
|
||||
|
||||
.file "tailcall-only.c"
|
||||
.text
|
||||
.Ltext0:
|
||||
.p2align 4,,15
|
||||
.type bar_1, @function
|
||||
bar_1:
|
||||
.LFB0:
|
||||
.file 1 "tailcall-only.c"
|
||||
# tailcall-only.c:22
|
||||
.loc 1 22 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:24
|
||||
.loc 1 24 0
|
||||
movl $42, %eax
|
||||
# SUCC: EXIT [100.0%]
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size bar_1, .-bar_1
|
||||
.p2align 4,,15
|
||||
.type bar, @function
|
||||
bar:
|
||||
.LFB1:
|
||||
# tailcall-only.c:28
|
||||
.loc 1 28 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:29
|
||||
.loc 1 29 0
|
||||
jmp bar_1
|
||||
# SUCC: EXIT [100.0%] (ABNORMAL,SIBCALL)
|
||||
.LVL0:
|
||||
.cfi_endproc
|
||||
.LFE1:
|
||||
.size bar, .-bar
|
||||
.p2align 4,,15
|
||||
.type foo_1, @function
|
||||
foo_1:
|
||||
.LFB2:
|
||||
# tailcall-only.c:34
|
||||
.loc 1 34 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:35
|
||||
.loc 1 35 0
|
||||
jmp bar
|
||||
# SUCC: EXIT [100.0%] (ABNORMAL,SIBCALL)
|
||||
.LVL1:
|
||||
.cfi_endproc
|
||||
.LFE2:
|
||||
.size foo_1, .-foo_1
|
||||
.p2align 4,,15
|
||||
.type foo, @function
|
||||
foo:
|
||||
.LFB3:
|
||||
# tailcall-only.c:40
|
||||
.loc 1 40 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:41
|
||||
.loc 1 41 0
|
||||
jmp foo_1
|
||||
# SUCC: EXIT [100.0%] (ABNORMAL,SIBCALL)
|
||||
.LVL2:
|
||||
.cfi_endproc
|
||||
.LFE3:
|
||||
.size foo, .-foo
|
||||
.section .text.startup,"ax",@progbits
|
||||
.p2align 4,,15
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB4:
|
||||
# tailcall-only.c:46
|
||||
.loc 1 46 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:49
|
||||
.loc 1 49 0
|
||||
call foo
|
||||
.LVL3:
|
||||
# tailcall-only.c:50
|
||||
.loc 1 50 0
|
||||
addl $1, %eax
|
||||
.LVL4:
|
||||
# SUCC: EXIT [100.0%]
|
||||
# tailcall-only.c:53
|
||||
.loc 1 53 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE4:
|
||||
.size main, .-main
|
||||
.text
|
||||
.Letext0:
|
||||
.section .debug_info,"",@progbits
|
||||
.Ldebug_info0:
|
||||
.long 0xd5 # Length of Compilation Unit Info
|
||||
.value 0x4 # DWARF version number
|
||||
.long .Ldebug_abbrev0 # Offset Into Abbrev. Section
|
||||
.byte 0x4 # Pointer Size (in bytes)
|
||||
.uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit)
|
||||
.long .LASF1 # DW_AT_producer: "GNU C 4.8.3 20140911 (Red Hat 4.8.3-9) -m32 -march=i686 -g -O2"
|
||||
.byte 0x1 # DW_AT_language
|
||||
.long .LASF2 # DW_AT_name: "tailcall-only.c"
|
||||
.long .LASF3 # DW_AT_comp_dir: ""
|
||||
.long .Ldebug_ranges0+0 # DW_AT_ranges
|
||||
.long 0 # DW_AT_low_pc
|
||||
.long .Ldebug_line0 # DW_AT_stmt_list
|
||||
.uleb128 0x2 # (DIE (0x25) DW_TAG_subprogram)
|
||||
.long .LASF4 # DW_AT_name: "bar_1"
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x15 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x3a # DW_AT_type
|
||||
.long .LFB0 # DW_AT_low_pc
|
||||
.long .LFE0-.LFB0 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.uleb128 0x3 # (DIE (0x3a) DW_TAG_base_type)
|
||||
.byte 0x4 # DW_AT_byte_size
|
||||
.byte 0x5 # DW_AT_encoding
|
||||
.ascii "int\0" # DW_AT_name
|
||||
.uleb128 0x4 # (DIE (0x41) DW_TAG_subprogram)
|
||||
.ascii "bar\0" # DW_AT_name
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x1b # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x3a # DW_AT_type
|
||||
.long .LFB1 # DW_AT_low_pc
|
||||
.long .LFE1-.LFB1 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.long 0x64 # DW_AT_sibling
|
||||
.uleb128 0x5 # (DIE (0x5a) DW_TAG_GNU_call_site)
|
||||
.long .LVL0 # DW_AT_low_pc
|
||||
# DW_AT_GNU_tail_call
|
||||
.long 0x25 # DW_AT_abstract_origin
|
||||
.byte 0 # end of children of DIE 0x41
|
||||
.uleb128 0x6 # (DIE (0x64) DW_TAG_subprogram)
|
||||
.long .LASF0 # DW_AT_name: "foo_1"
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x21 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x3a # DW_AT_type
|
||||
.long .LFB2 # DW_AT_low_pc
|
||||
.long .LFE2-.LFB2 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.long 0x87 # DW_AT_sibling
|
||||
.uleb128 0x5 # (DIE (0x7d) DW_TAG_GNU_call_site)
|
||||
.long .LVL1 # DW_AT_low_pc
|
||||
# DW_AT_GNU_tail_call
|
||||
.long 0x41 # DW_AT_abstract_origin
|
||||
.byte 0 # end of children of DIE 0x64
|
||||
.uleb128 0x4 # (DIE (0x87) DW_TAG_subprogram)
|
||||
.ascii "foo\0" # DW_AT_name
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x27 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x3a # DW_AT_type
|
||||
.long .LFB3 # DW_AT_low_pc
|
||||
.long .LFE3-.LFB3 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.long 0xaa # DW_AT_sibling
|
||||
.uleb128 0x5 # (DIE (0xa0) DW_TAG_GNU_call_site)
|
||||
.long .LVL2 # DW_AT_low_pc
|
||||
# DW_AT_GNU_tail_call
|
||||
.long 0x64 # DW_AT_abstract_origin
|
||||
.byte 0 # end of children of DIE 0x87
|
||||
.uleb128 0x7 # (DIE (0xaa) DW_TAG_subprogram)
|
||||
# DW_AT_external
|
||||
.long .LASF5 # DW_AT_name: "main"
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x2d # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x3a # DW_AT_type
|
||||
.long .LFB4 # DW_AT_low_pc
|
||||
.long .LFE4-.LFB4 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.uleb128 0x8 # (DIE (0xbf) DW_TAG_variable)
|
||||
.long .LASF6 # DW_AT_name: "answer"
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x2f # DW_AT_decl_line
|
||||
.long 0x3a # DW_AT_type
|
||||
.long .LLST0 # DW_AT_location
|
||||
.uleb128 0x9 # (DIE (0xce) DW_TAG_GNU_call_site)
|
||||
.long .LVL3 # DW_AT_low_pc
|
||||
.long 0x87 # DW_AT_abstract_origin
|
||||
.byte 0 # end of children of DIE 0xaa
|
||||
.byte 0 # end of children of DIE 0xb
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.Ldebug_abbrev0:
|
||||
.uleb128 0x1 # (abbrev code)
|
||||
.uleb128 0x11 # (TAG: DW_TAG_compile_unit)
|
||||
.byte 0x1 # DW_children_yes
|
||||
.uleb128 0x25 # (DW_AT_producer)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x13 # (DW_AT_language)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x1b # (DW_AT_comp_dir)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x55 # (DW_AT_ranges)
|
||||
.uleb128 0x17 # (DW_FORM_sec_offset)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x10 # (DW_AT_stmt_list)
|
||||
.uleb128 0x17 # (DW_FORM_sec_offset)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x2 # (abbrev code)
|
||||
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x27 # (DW_AT_prototyped)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x12 # (DW_AT_high_pc)
|
||||
.uleb128 0x6 # (DW_FORM_data4)
|
||||
.uleb128 0x40 # (DW_AT_frame_base)
|
||||
.uleb128 0x18 # (DW_FORM_exprloc)
|
||||
.uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x3 # (abbrev code)
|
||||
.uleb128 0x24 # (TAG: DW_TAG_base_type)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0xb # (DW_AT_byte_size)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3e # (DW_AT_encoding)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0x8 # (DW_FORM_string)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x4 # (abbrev code)
|
||||
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
|
||||
.byte 0x1 # DW_children_yes
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0x8 # (DW_FORM_string)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x27 # (DW_AT_prototyped)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x12 # (DW_AT_high_pc)
|
||||
.uleb128 0x6 # (DW_FORM_data4)
|
||||
.uleb128 0x40 # (DW_AT_frame_base)
|
||||
.uleb128 0x18 # (DW_FORM_exprloc)
|
||||
.uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x1 # (DW_AT_sibling)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x5 # (abbrev code)
|
||||
.uleb128 0x4109 # (TAG: DW_TAG_GNU_call_site)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x2115 # (DW_AT_GNU_tail_call)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x31 # (DW_AT_abstract_origin)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x6 # (abbrev code)
|
||||
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
|
||||
.byte 0x1 # DW_children_yes
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x27 # (DW_AT_prototyped)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x12 # (DW_AT_high_pc)
|
||||
.uleb128 0x6 # (DW_FORM_data4)
|
||||
.uleb128 0x40 # (DW_AT_frame_base)
|
||||
.uleb128 0x18 # (DW_FORM_exprloc)
|
||||
.uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x1 # (DW_AT_sibling)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x7 # (abbrev code)
|
||||
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
|
||||
.byte 0x1 # DW_children_yes
|
||||
.uleb128 0x3f # (DW_AT_external)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x27 # (DW_AT_prototyped)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x12 # (DW_AT_high_pc)
|
||||
.uleb128 0x6 # (DW_FORM_data4)
|
||||
.uleb128 0x40 # (DW_AT_frame_base)
|
||||
.uleb128 0x18 # (DW_FORM_exprloc)
|
||||
.uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x8 # (abbrev code)
|
||||
.uleb128 0x34 # (TAG: DW_TAG_variable)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x2 # (DW_AT_location)
|
||||
.uleb128 0x17 # (DW_FORM_sec_offset)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x9 # (abbrev code)
|
||||
.uleb128 0x4109 # (TAG: DW_TAG_GNU_call_site)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x31 # (DW_AT_abstract_origin)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0
|
||||
.section .debug_loc,"",@progbits
|
||||
.Ldebug_loc0:
|
||||
.LLST0:
|
||||
.long .LVL3 # Location list begin address (*.LLST0)
|
||||
.long .LVL4 # Location list end address (*.LLST0)
|
||||
.value 0x3 # Location expression size
|
||||
.byte 0x70 # DW_OP_breg0
|
||||
.sleb128 1
|
||||
.byte 0x9f # DW_OP_stack_value
|
||||
.long .LVL4 # Location list begin address (*.LLST0)
|
||||
.long .LFE4 # Location list end address (*.LLST0)
|
||||
.value 0x1 # Location expression size
|
||||
.byte 0x50 # DW_OP_reg0
|
||||
.long 0 # Location list terminator begin (*.LLST0)
|
||||
.long 0 # Location list terminator end (*.LLST0)
|
||||
.section .debug_aranges,"",@progbits
|
||||
.long 0x24 # Length of Address Ranges Info
|
||||
.value 0x2 # DWARF Version
|
||||
.long .Ldebug_info0 # Offset of Compilation Unit Info
|
||||
.byte 0x4 # Size of Address
|
||||
.byte 0 # Size of Segment Descriptor
|
||||
.value 0 # Pad to 8 byte boundary
|
||||
.value 0
|
||||
.long .Ltext0 # Address
|
||||
.long .Letext0-.Ltext0 # Length
|
||||
.long .LFB4 # Address
|
||||
.long .LFE4-.LFB4 # Length
|
||||
.long 0
|
||||
.long 0
|
||||
.section .debug_ranges,"",@progbits
|
||||
.Ldebug_ranges0:
|
||||
.long .Ltext0 # Offset 0
|
||||
.long .Letext0
|
||||
.long .LFB4 # Offset 0x8
|
||||
.long .LFE4
|
||||
.long 0
|
||||
.long 0
|
||||
.section .debug_line,"",@progbits
|
||||
.Ldebug_line0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.LASF4:
|
||||
.string "bar_1"
|
||||
.LASF2:
|
||||
.string "tailcall-only.c"
|
||||
.LASF1:
|
||||
.string "GNU C 4.8.3 20140911 (Red Hat 4.8.3-9) -m32 -march=i686 -g -O2"
|
||||
.LASF6:
|
||||
.string "answer"
|
||||
.LASF5:
|
||||
.string "main"
|
||||
.LASF3:
|
||||
.string ""
|
||||
.LASF0:
|
||||
.string "foo_1"
|
||||
.ident "GCC: (GNU) 4.8.3 20140911 (Red Hat 4.8.3-9)"
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
53
gdb/testsuite/gdb.btrace/tailcall-only.c
Normal file
53
gdb/testsuite/gdb.btrace/tailcall-only.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Intel Corp. <markus.t.metzger@intel.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
static __attribute__ ((noinline)) int
|
||||
bar_1 (void)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
static __attribute__ ((noinline)) int
|
||||
bar (void)
|
||||
{
|
||||
return bar_1 ();
|
||||
}
|
||||
|
||||
static __attribute__ ((noinline)) int
|
||||
foo_1 (void)
|
||||
{
|
||||
return bar ();
|
||||
}
|
||||
|
||||
static __attribute__ ((noinline)) int
|
||||
foo (void)
|
||||
{
|
||||
return foo_1 ();
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int answer;
|
||||
|
||||
answer = foo ();
|
||||
answer += 1;
|
||||
|
||||
return answer;
|
||||
}
|
||||
97
gdb/testsuite/gdb.btrace/tailcall-only.exp
Normal file
97
gdb/testsuite/gdb.btrace/tailcall-only.exp
Normal file
@@ -0,0 +1,97 @@
|
||||
# This testcase is part of GDB, the GNU debugger.
|
||||
#
|
||||
# Copyright 2016 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
# This is a variant of tailcall.exp where the entire trace contains only tail
|
||||
# calls. This used to cause a crash in get_frame_type.
|
||||
#
|
||||
|
||||
# check for btrace support
|
||||
if { [skip_btrace_tests] } { return -1 }
|
||||
|
||||
# This test requires the compiler to generate a tail call. To guarantee that
|
||||
# we always get one, we use an assembly source file.
|
||||
#
|
||||
# We use different assembly sources based on the target architecture.
|
||||
#
|
||||
# Luckily, they are similar enough that a single test script can handle
|
||||
# both.
|
||||
set opts {}
|
||||
if [info exists COMPILE] {
|
||||
# make check RUNTESTFLAGS="gdb.btrace/tailcall-only.exp COMPILE=1"
|
||||
standard_testfile tailcall-only.c
|
||||
lappend opts debug optimize=-O2
|
||||
} elseif {[istarget "x86_64-*-*"]} {
|
||||
standard_testfile x86_64-tailcall-only.S
|
||||
} elseif {[istarget "i?86-*-*"]} {
|
||||
standard_testfile i686-tailcall-only.S
|
||||
} else {
|
||||
verbose "Skipping ${testfile}."
|
||||
return
|
||||
}
|
||||
|
||||
if [prepare_for_testing tailcall-only.exp $testfile $srcfile $opts] {
|
||||
return -1
|
||||
}
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
# we want to see the full trace for this test
|
||||
gdb_test_no_output "set record function-call-history-size 0"
|
||||
|
||||
# trace foo
|
||||
gdb_test "step" ".*" "prepare for recording"
|
||||
gdb_test_no_output "record btrace"
|
||||
gdb_test "stepi 4" ".*" "record branch trace"
|
||||
|
||||
# for debugging
|
||||
gdb_test "info record" ".*"
|
||||
|
||||
# show the branch trace with calls indented
|
||||
gdb_test "record function-call-history /c 1" [multi_line \
|
||||
"1\tfoo" \
|
||||
"2\t foo_1" \
|
||||
"3\t bar" \
|
||||
"4\t bar_1"
|
||||
] "function-call-history"
|
||||
|
||||
# We can step
|
||||
gdb_test "record goto begin" ".*foo.*"
|
||||
gdb_test "stepi" ".*foo_1.*" "step into foo_1"
|
||||
gdb_test "step" ".*bar.*" "step into bar"
|
||||
gdb_test "stepi" ".*bar_1.*" "step into bar_1"
|
||||
|
||||
# We can neither finish nor return.
|
||||
gdb_test "finish" "Cannot find the caller frame.*"
|
||||
gdb_test_multiple "return" "return" {
|
||||
-re "Make .* return now.*y or n. $" {
|
||||
send_gdb "y\n"
|
||||
exp_continue
|
||||
}
|
||||
-re "Cannot find the caller frame.*$gdb_prompt $" {
|
||||
pass "return"
|
||||
}
|
||||
}
|
||||
|
||||
# But we can reverse-finish
|
||||
gdb_test "reverse-finish" ".*bar.*"
|
||||
gdb_test "reverse-step" ".*foo_1.*"
|
||||
|
||||
# Info frame isn't useful but doesn't crash as it used to.
|
||||
gdb_test "up" ".*foo.*"
|
||||
gdb_test "info frame" ".*"
|
||||
446
gdb/testsuite/gdb.btrace/x86_64-tailcall-only.S
Normal file
446
gdb/testsuite/gdb.btrace/x86_64-tailcall-only.S
Normal file
@@ -0,0 +1,446 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
This file has been generated using:
|
||||
gcc -S -O2 -dA -g tailcall-only.c -o x86_64-tailcall-only.S */
|
||||
|
||||
.file "tailcall-only.c"
|
||||
.text
|
||||
.Ltext0:
|
||||
.p2align 4,,15
|
||||
.type bar_1, @function
|
||||
bar_1:
|
||||
.LFB0:
|
||||
.file 1 "tailcall-only.c"
|
||||
# tailcall-only.c:22
|
||||
.loc 1 22 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:24
|
||||
.loc 1 24 0
|
||||
movl $42, %eax
|
||||
# SUCC: EXIT [100.0%]
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE0:
|
||||
.size bar_1, .-bar_1
|
||||
.p2align 4,,15
|
||||
.type bar, @function
|
||||
bar:
|
||||
.LFB1:
|
||||
# tailcall-only.c:28
|
||||
.loc 1 28 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:29
|
||||
.loc 1 29 0
|
||||
jmp bar_1
|
||||
# SUCC: EXIT [100.0%] (ABNORMAL,SIBCALL)
|
||||
.LVL0:
|
||||
.cfi_endproc
|
||||
.LFE1:
|
||||
.size bar, .-bar
|
||||
.p2align 4,,15
|
||||
.type foo_1, @function
|
||||
foo_1:
|
||||
.LFB2:
|
||||
# tailcall-only.c:34
|
||||
.loc 1 34 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:35
|
||||
.loc 1 35 0
|
||||
jmp bar
|
||||
# SUCC: EXIT [100.0%] (ABNORMAL,SIBCALL)
|
||||
.LVL1:
|
||||
.cfi_endproc
|
||||
.LFE2:
|
||||
.size foo_1, .-foo_1
|
||||
.p2align 4,,15
|
||||
.type foo, @function
|
||||
foo:
|
||||
.LFB3:
|
||||
# tailcall-only.c:40
|
||||
.loc 1 40 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:41
|
||||
.loc 1 41 0
|
||||
jmp foo_1
|
||||
# SUCC: EXIT [100.0%] (ABNORMAL,SIBCALL)
|
||||
.LVL2:
|
||||
.cfi_endproc
|
||||
.LFE3:
|
||||
.size foo, .-foo
|
||||
.section .text.startup,"ax",@progbits
|
||||
.p2align 4,,15
|
||||
.globl main
|
||||
.type main, @function
|
||||
main:
|
||||
.LFB4:
|
||||
# tailcall-only.c:46
|
||||
.loc 1 46 0
|
||||
.cfi_startproc
|
||||
# BLOCK 2 freq:10000 seq:0
|
||||
# PRED: ENTRY [100.0%] (FALLTHRU)
|
||||
# tailcall-only.c:49
|
||||
.loc 1 49 0
|
||||
call foo
|
||||
.LVL3:
|
||||
# tailcall-only.c:50
|
||||
.loc 1 50 0
|
||||
addl $1, %eax
|
||||
.LVL4:
|
||||
# SUCC: EXIT [100.0%]
|
||||
# tailcall-only.c:53
|
||||
.loc 1 53 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
.LFE4:
|
||||
.size main, .-main
|
||||
.text
|
||||
.Letext0:
|
||||
.section .debug_info,"",@progbits
|
||||
.Ldebug_info0:
|
||||
.long 0x111 # Length of Compilation Unit Info
|
||||
.value 0x4 # DWARF version number
|
||||
.long .Ldebug_abbrev0 # Offset Into Abbrev. Section
|
||||
.byte 0x8 # Pointer Size (in bytes)
|
||||
.uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit)
|
||||
.long .LASF1 # DW_AT_producer: "GNU C 4.8.3 20140911 (Red Hat 4.8.3-9) -mtune=generic -march=x86-64 -g -O2"
|
||||
.byte 0x1 # DW_AT_language
|
||||
.long .LASF2 # DW_AT_name: "tailcall-only.c"
|
||||
.long .LASF3 # DW_AT_comp_dir: ""
|
||||
.long .Ldebug_ranges0+0 # DW_AT_ranges
|
||||
.quad 0 # DW_AT_low_pc
|
||||
.long .Ldebug_line0 # DW_AT_stmt_list
|
||||
.uleb128 0x2 # (DIE (0x29) DW_TAG_subprogram)
|
||||
.long .LASF4 # DW_AT_name: "bar_1"
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x15 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x46 # DW_AT_type
|
||||
.quad .LFB0 # DW_AT_low_pc
|
||||
.quad .LFE0-.LFB0 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.uleb128 0x3 # (DIE (0x46) DW_TAG_base_type)
|
||||
.byte 0x4 # DW_AT_byte_size
|
||||
.byte 0x5 # DW_AT_encoding
|
||||
.ascii "int\0" # DW_AT_name
|
||||
.uleb128 0x4 # (DIE (0x4d) DW_TAG_subprogram)
|
||||
.ascii "bar\0" # DW_AT_name
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x1b # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x46 # DW_AT_type
|
||||
.quad .LFB1 # DW_AT_low_pc
|
||||
.quad .LFE1-.LFB1 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.long 0x7c # DW_AT_sibling
|
||||
.uleb128 0x5 # (DIE (0x6e) DW_TAG_GNU_call_site)
|
||||
.quad .LVL0 # DW_AT_low_pc
|
||||
# DW_AT_GNU_tail_call
|
||||
.long 0x29 # DW_AT_abstract_origin
|
||||
.byte 0 # end of children of DIE 0x4d
|
||||
.uleb128 0x6 # (DIE (0x7c) DW_TAG_subprogram)
|
||||
.long .LASF0 # DW_AT_name: "foo_1"
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x21 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x46 # DW_AT_type
|
||||
.quad .LFB2 # DW_AT_low_pc
|
||||
.quad .LFE2-.LFB2 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.long 0xab # DW_AT_sibling
|
||||
.uleb128 0x5 # (DIE (0x9d) DW_TAG_GNU_call_site)
|
||||
.quad .LVL1 # DW_AT_low_pc
|
||||
# DW_AT_GNU_tail_call
|
||||
.long 0x4d # DW_AT_abstract_origin
|
||||
.byte 0 # end of children of DIE 0x7c
|
||||
.uleb128 0x4 # (DIE (0xab) DW_TAG_subprogram)
|
||||
.ascii "foo\0" # DW_AT_name
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x27 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x46 # DW_AT_type
|
||||
.quad .LFB3 # DW_AT_low_pc
|
||||
.quad .LFE3-.LFB3 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.long 0xda # DW_AT_sibling
|
||||
.uleb128 0x5 # (DIE (0xcc) DW_TAG_GNU_call_site)
|
||||
.quad .LVL2 # DW_AT_low_pc
|
||||
# DW_AT_GNU_tail_call
|
||||
.long 0x7c # DW_AT_abstract_origin
|
||||
.byte 0 # end of children of DIE 0xab
|
||||
.uleb128 0x7 # (DIE (0xda) DW_TAG_subprogram)
|
||||
# DW_AT_external
|
||||
.long .LASF5 # DW_AT_name: "main"
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x2d # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 0x46 # DW_AT_type
|
||||
.quad .LFB4 # DW_AT_low_pc
|
||||
.quad .LFE4-.LFB4 # DW_AT_high_pc
|
||||
.uleb128 0x1 # DW_AT_frame_base
|
||||
.byte 0x9c # DW_OP_call_frame_cfa
|
||||
# DW_AT_GNU_all_call_sites
|
||||
.uleb128 0x8 # (DIE (0xf7) DW_TAG_variable)
|
||||
.long .LASF6 # DW_AT_name: "answer"
|
||||
.byte 0x1 # DW_AT_decl_file (tailcall-only.c)
|
||||
.byte 0x2f # DW_AT_decl_line
|
||||
.long 0x46 # DW_AT_type
|
||||
.long .LLST0 # DW_AT_location
|
||||
.uleb128 0x9 # (DIE (0x106) DW_TAG_GNU_call_site)
|
||||
.quad .LVL3 # DW_AT_low_pc
|
||||
.long 0xab # DW_AT_abstract_origin
|
||||
.byte 0 # end of children of DIE 0xda
|
||||
.byte 0 # end of children of DIE 0xb
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.Ldebug_abbrev0:
|
||||
.uleb128 0x1 # (abbrev code)
|
||||
.uleb128 0x11 # (TAG: DW_TAG_compile_unit)
|
||||
.byte 0x1 # DW_children_yes
|
||||
.uleb128 0x25 # (DW_AT_producer)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x13 # (DW_AT_language)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x1b # (DW_AT_comp_dir)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x55 # (DW_AT_ranges)
|
||||
.uleb128 0x17 # (DW_FORM_sec_offset)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x10 # (DW_AT_stmt_list)
|
||||
.uleb128 0x17 # (DW_FORM_sec_offset)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x2 # (abbrev code)
|
||||
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x27 # (DW_AT_prototyped)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x12 # (DW_AT_high_pc)
|
||||
.uleb128 0x7 # (DW_FORM_data8)
|
||||
.uleb128 0x40 # (DW_AT_frame_base)
|
||||
.uleb128 0x18 # (DW_FORM_exprloc)
|
||||
.uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x3 # (abbrev code)
|
||||
.uleb128 0x24 # (TAG: DW_TAG_base_type)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0xb # (DW_AT_byte_size)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3e # (DW_AT_encoding)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0x8 # (DW_FORM_string)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x4 # (abbrev code)
|
||||
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
|
||||
.byte 0x1 # DW_children_yes
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0x8 # (DW_FORM_string)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x27 # (DW_AT_prototyped)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x12 # (DW_AT_high_pc)
|
||||
.uleb128 0x7 # (DW_FORM_data8)
|
||||
.uleb128 0x40 # (DW_AT_frame_base)
|
||||
.uleb128 0x18 # (DW_FORM_exprloc)
|
||||
.uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x1 # (DW_AT_sibling)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x5 # (abbrev code)
|
||||
.uleb128 0x4109 # (TAG: DW_TAG_GNU_call_site)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x2115 # (DW_AT_GNU_tail_call)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x31 # (DW_AT_abstract_origin)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x6 # (abbrev code)
|
||||
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
|
||||
.byte 0x1 # DW_children_yes
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x27 # (DW_AT_prototyped)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x12 # (DW_AT_high_pc)
|
||||
.uleb128 0x7 # (DW_FORM_data8)
|
||||
.uleb128 0x40 # (DW_AT_frame_base)
|
||||
.uleb128 0x18 # (DW_FORM_exprloc)
|
||||
.uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x1 # (DW_AT_sibling)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x7 # (abbrev code)
|
||||
.uleb128 0x2e # (TAG: DW_TAG_subprogram)
|
||||
.byte 0x1 # DW_children_yes
|
||||
.uleb128 0x3f # (DW_AT_external)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x27 # (DW_AT_prototyped)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x12 # (DW_AT_high_pc)
|
||||
.uleb128 0x7 # (DW_FORM_data8)
|
||||
.uleb128 0x40 # (DW_AT_frame_base)
|
||||
.uleb128 0x18 # (DW_FORM_exprloc)
|
||||
.uleb128 0x2117 # (DW_AT_GNU_all_call_sites)
|
||||
.uleb128 0x19 # (DW_FORM_flag_present)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x8 # (abbrev code)
|
||||
.uleb128 0x34 # (TAG: DW_TAG_variable)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0x3 # (DW_AT_name)
|
||||
.uleb128 0xe # (DW_FORM_strp)
|
||||
.uleb128 0x3a # (DW_AT_decl_file)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x3b # (DW_AT_decl_line)
|
||||
.uleb128 0xb # (DW_FORM_data1)
|
||||
.uleb128 0x49 # (DW_AT_type)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.uleb128 0x2 # (DW_AT_location)
|
||||
.uleb128 0x17 # (DW_FORM_sec_offset)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.uleb128 0x9 # (abbrev code)
|
||||
.uleb128 0x4109 # (TAG: DW_TAG_GNU_call_site)
|
||||
.byte 0 # DW_children_no
|
||||
.uleb128 0x11 # (DW_AT_low_pc)
|
||||
.uleb128 0x1 # (DW_FORM_addr)
|
||||
.uleb128 0x31 # (DW_AT_abstract_origin)
|
||||
.uleb128 0x13 # (DW_FORM_ref4)
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0
|
||||
.section .debug_loc,"",@progbits
|
||||
.Ldebug_loc0:
|
||||
.LLST0:
|
||||
.quad .LVL3 # Location list begin address (*.LLST0)
|
||||
.quad .LVL4 # Location list end address (*.LLST0)
|
||||
.value 0x3 # Location expression size
|
||||
.byte 0x70 # DW_OP_breg0
|
||||
.sleb128 1
|
||||
.byte 0x9f # DW_OP_stack_value
|
||||
.quad .LVL4 # Location list begin address (*.LLST0)
|
||||
.quad .LFE4 # Location list end address (*.LLST0)
|
||||
.value 0x1 # Location expression size
|
||||
.byte 0x50 # DW_OP_reg0
|
||||
.quad 0 # Location list terminator begin (*.LLST0)
|
||||
.quad 0 # Location list terminator end (*.LLST0)
|
||||
.section .debug_aranges,"",@progbits
|
||||
.long 0x3c # Length of Address Ranges Info
|
||||
.value 0x2 # DWARF Version
|
||||
.long .Ldebug_info0 # Offset of Compilation Unit Info
|
||||
.byte 0x8 # Size of Address
|
||||
.byte 0 # Size of Segment Descriptor
|
||||
.value 0 # Pad to 16 byte boundary
|
||||
.value 0
|
||||
.quad .Ltext0 # Address
|
||||
.quad .Letext0-.Ltext0 # Length
|
||||
.quad .LFB4 # Address
|
||||
.quad .LFE4-.LFB4 # Length
|
||||
.quad 0
|
||||
.quad 0
|
||||
.section .debug_ranges,"",@progbits
|
||||
.Ldebug_ranges0:
|
||||
.quad .Ltext0 # Offset 0
|
||||
.quad .Letext0
|
||||
.quad .LFB4 # Offset 0x10
|
||||
.quad .LFE4
|
||||
.quad 0
|
||||
.quad 0
|
||||
.section .debug_line,"",@progbits
|
||||
.Ldebug_line0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.LASF4:
|
||||
.string "bar_1"
|
||||
.LASF2:
|
||||
.string "tailcall-only.c"
|
||||
.LASF1:
|
||||
.string "GNU C 4.8.3 20140911 (Red Hat 4.8.3-9) -mtune=generic -march=x86-64 -g -O2"
|
||||
.LASF6:
|
||||
.string "answer"
|
||||
.LASF5:
|
||||
.string "main"
|
||||
.LASF3:
|
||||
.string ""
|
||||
.LASF0:
|
||||
.string "foo_1"
|
||||
.ident "GCC: (GNU) 4.8.3 20140911 (Red Hat 4.8.3-9)"
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
@@ -32,10 +32,6 @@ gdb_test "print vla1" " = <not allocated>" "print non-allocated vla1"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "vla2-allocated"]
|
||||
gdb_continue_to_breakpoint "vla2-allocated"
|
||||
gdb_test "print vla1" " = \\( *\\( *\\( *0, *0, *0,\[()0, .\]*\\)" \
|
||||
"print vla1 allocated"
|
||||
gdb_test "print vla2" " = \\( *\\( *\\( *0, *0, *0,\[()0, .\]*\\)" \
|
||||
"print vla2 allocated"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "vla1-filled"]
|
||||
gdb_continue_to_breakpoint "vla1-filled"
|
||||
@@ -45,12 +41,8 @@ gdb_test "print vla1" \
|
||||
|
||||
# Try to access history values for full vla prints.
|
||||
gdb_test "print \$1" " = <not allocated>" "print \$1"
|
||||
gdb_test "print \$2" " = \\( *\\( *\\( *0, *0, *0,\[()0, .\]*\\)" \
|
||||
"print \$2"
|
||||
gdb_test "print \$3" " = \\( *\\( *\\( *0, *0, *0,\[()0, .\]*\\)" \
|
||||
"print \$3"
|
||||
gdb_test "print \$4" \
|
||||
" = \\( *\\( *\\( *1311, *1311, *1311,\[()1311, .\]*\\)" "print \$4"
|
||||
gdb_test "print \$2" \
|
||||
" = \\( *\\( *\\( *1311, *1311, *1311,\[()1311, .\]*\\)" "print \$2"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "vla2-filled"]
|
||||
gdb_continue_to_breakpoint "vla2-filled"
|
||||
@@ -58,5 +50,5 @@ gdb_test "print vla2(1,43,20)" " = 1311" "print vla2(1,43,20)"
|
||||
gdb_test "print vla1(1,3,8)" " = 1001" "print vla2(1,3,8)"
|
||||
|
||||
# Try to access history values for vla values.
|
||||
gdb_test "print \$9" " = 1311" "print \$9"
|
||||
gdb_test "print \$10" " = 1001" "print \$10"
|
||||
gdb_test "print \$5" " = 1311" "print \$5"
|
||||
gdb_test "print \$6" " = 1001" "print \$6"
|
||||
|
||||
@@ -32,6 +32,8 @@ if ![runto_main] {
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "array2-almost-filled"]
|
||||
gdb_continue_to_breakpoint "array2-almost-filled"
|
||||
# array2 size is 296352 bytes.
|
||||
gdb_test_no_output "set max-value-size 1024*1024"
|
||||
gdb_test "print array2" " = \\( *\\( *\\( *30, *3, *3,\[()3, .\]*\\)" \
|
||||
"print array2 in foo after it was filled"
|
||||
gdb_test "print array2(2,1,1)=20" " = 20" \
|
||||
|
||||
@@ -42,6 +42,8 @@ gdb_test "print array1(1, 1)" " = 30" \
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "array2-almost-filled"]
|
||||
gdb_continue_to_breakpoint "array2-almost-filled (1st)"
|
||||
# array2 size is 296352 bytes.
|
||||
gdb_test_no_output "set max-value-size 1024*1024"
|
||||
gdb_test "print array2" " = \\( *\\( *\\( *30, *3, *3,\[()3, .\]*\\)" \
|
||||
"print array2 in foo after it was filled (passed fixed array)"
|
||||
gdb_test "print array2(2,1,1)=20" " = 20" \
|
||||
|
||||
@@ -19,6 +19,7 @@ program vla
|
||||
real, target, allocatable :: vla3 (:, :)
|
||||
real, pointer :: pvla (:, :, :)
|
||||
logical :: l
|
||||
nullify(pvla)
|
||||
|
||||
allocate (vla1 (10,10,10)) ! vla1-init
|
||||
l = allocated(vla1)
|
||||
|
||||
31
gdb/testsuite/gdb.mi/mi-async-run.c
Normal file
31
gdb/testsuite/gdb.mi/mi-async-run.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/* Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 30; i++)
|
||||
{
|
||||
sleep (1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
50
gdb/testsuite/gdb.mi/mi-async-run.exp
Normal file
50
gdb/testsuite/gdb.mi/mi-async-run.exp
Normal file
@@ -0,0 +1,50 @@
|
||||
# Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib mi-support.exp
|
||||
|
||||
standard_testfile
|
||||
|
||||
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
||||
untested "mi-async-run.exp"
|
||||
return -1
|
||||
}
|
||||
|
||||
# Test the resolution of PR 18077
|
||||
#
|
||||
# When doing an -exec-run with a fresh copy of GDB, it would result in
|
||||
# synchronous execution, even though mi-async was on.
|
||||
|
||||
proc test_async_run {} {
|
||||
global GDBFLAGS
|
||||
|
||||
save_vars { GDBFLAGS } {
|
||||
global binfile
|
||||
|
||||
set GDBFLAGS [concat $GDBFLAGS " -ex \"set mi-async on\""]
|
||||
|
||||
gdb_exit
|
||||
if [mi_gdb_start] {
|
||||
continue
|
||||
}
|
||||
|
||||
mi_gdb_load ${binfile}
|
||||
mi_run_cmd
|
||||
mi_gdb_test "123-exec-interrupt --all" "123\\^done" "send interrupt command"
|
||||
mi_expect_interrupt "expect interrupt"
|
||||
}
|
||||
}
|
||||
|
||||
test_async_run
|
||||
61
gdb/testsuite/gdb.mi/mi-threads-interrupt.c
Normal file
61
gdb/testsuite/gdb.mi/mi-threads-interrupt.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define NUM_THREADS 2
|
||||
|
||||
static pthread_barrier_t barrier;
|
||||
|
||||
static void *
|
||||
thread_func (void *v)
|
||||
{
|
||||
int i;
|
||||
|
||||
pthread_barrier_wait (&barrier);
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
sleep (1);
|
||||
}
|
||||
|
||||
static void
|
||||
all_threads_created (void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int i;
|
||||
pthread_t threads[NUM_THREADS];
|
||||
|
||||
/* +1 to account for the main thread */
|
||||
pthread_barrier_init (&barrier, NULL, NUM_THREADS + 1);
|
||||
|
||||
for (i = 0; i < NUM_THREADS; i++)
|
||||
pthread_create (&threads[i], NULL, thread_func, NULL);
|
||||
|
||||
pthread_barrier_wait (&barrier);
|
||||
|
||||
all_threads_created ();
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
sleep (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
69
gdb/testsuite/gdb.mi/mi-threads-interrupt.exp
Normal file
69
gdb/testsuite/gdb.mi/mi-threads-interrupt.exp
Normal file
@@ -0,0 +1,69 @@
|
||||
# Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib mi-support.exp
|
||||
set MIFLAGS "-i=mi"
|
||||
|
||||
standard_testfile
|
||||
|
||||
if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable {debug}] != "" } {
|
||||
return -1
|
||||
}
|
||||
|
||||
# This tests the resolution of PR 20039.
|
||||
#
|
||||
# With a multi-threaded inferior and with MI/all-stop, it was not possible
|
||||
# to interrupt it with ctrl-C after a continue.
|
||||
|
||||
proc test_continue_interrupt { } {
|
||||
global binfile
|
||||
global async
|
||||
|
||||
gdb_exit
|
||||
if {[mi_gdb_start]} {
|
||||
continue
|
||||
}
|
||||
|
||||
# Load the binary in gdb...
|
||||
mi_gdb_load $binfile
|
||||
|
||||
# ... and run it.
|
||||
#
|
||||
# Note this test relies on mi_runto deleting the breakpoint.
|
||||
# A step-over here would mask the bug.
|
||||
mi_runto "all_threads_created"
|
||||
|
||||
# Consistency check.
|
||||
mi_check_thread_states {"stopped" "stopped" "stopped"} "check thread states"
|
||||
|
||||
# Continue.
|
||||
mi_send_resuming_command "exec-continue" "continue"
|
||||
|
||||
# Wait a bit to make sure all MI events are sent, before sending the
|
||||
# interruption request.
|
||||
sleep 1
|
||||
|
||||
# Send the interrupt request.
|
||||
if { $async } {
|
||||
mi_gdb_test "888-exec-interrupt" "888\\^done" "interrupt"
|
||||
} else {
|
||||
send_gdb "\003"
|
||||
}
|
||||
|
||||
# Wait for the *stopped.
|
||||
mi_expect_interrupt "interrupt reported"
|
||||
}
|
||||
|
||||
test_continue_interrupt
|
||||
@@ -21,6 +21,10 @@
|
||||
# end up leaving stale state behind that confuse the following
|
||||
# attach).
|
||||
|
||||
# Disabled in gdb 7.11.1 because the fix for PR gdb/19828 exposes
|
||||
# latent inefficiencies that make this test often time out.
|
||||
return
|
||||
|
||||
if {![can_spawn_for_attach]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
66
gdb/testsuite/gdb.threads/clone-attach-detach.c
Normal file
66
gdb/testsuite/gdb.threads/clone-attach-detach.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define STACK_SIZE 0x1000
|
||||
|
||||
int clone_pid;
|
||||
|
||||
static int
|
||||
clone_fn (void *unused)
|
||||
{
|
||||
/* Wait for alarm. */
|
||||
while (1)
|
||||
sleep (1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
unsigned char *stack;
|
||||
int res;
|
||||
|
||||
alarm (300);
|
||||
|
||||
stack = malloc (STACK_SIZE);
|
||||
assert (stack != NULL);
|
||||
|
||||
#define CLONE_FLAGS (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)
|
||||
|
||||
#ifdef __ia64__
|
||||
clone_pid = __clone2 (clone_fn, stack, STACK_SIZE, CLONE_FLAGS, NULL);
|
||||
#else
|
||||
clone_pid = clone (clone_fn, stack + STACK_SIZE, CLONE_FLAGS, NULL);
|
||||
#endif
|
||||
|
||||
assert (clone_pid > 0);
|
||||
|
||||
/* Wait for alarm. */
|
||||
while (1)
|
||||
sleep (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
98
gdb/testsuite/gdb.threads/clone-attach-detach.exp
Normal file
98
gdb/testsuite/gdb.threads/clone-attach-detach.exp
Normal file
@@ -0,0 +1,98 @@
|
||||
# This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
# Copyright 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Test attach / detach from a process that uses raw clone. We use raw
|
||||
# clone as proxy for when libthread_db is not available.
|
||||
|
||||
# This only works on targets with the Linux kernel.
|
||||
if ![istarget *-*-linux*] {
|
||||
return
|
||||
}
|
||||
|
||||
if {![can_spawn_for_attach]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
standard_testfile
|
||||
|
||||
if [prepare_for_testing "failed to prepare" $testfile $srcfile {debug}] {
|
||||
return -1
|
||||
}
|
||||
|
||||
clean_restart ${binfile}
|
||||
|
||||
set test_spawn_id [spawn_wait_for_attach $binfile]
|
||||
set testpid [spawn_id_get_pid $test_spawn_id]
|
||||
|
||||
# Native/gdbserver.
|
||||
set thread_re "(LWP $decimal|Thread )"
|
||||
|
||||
# Try attach / detach a few times, in case GDB ends up with stale
|
||||
# state after detaching.
|
||||
|
||||
set attempts 3
|
||||
for {set attempt 1} {$attempt <= $attempts} {incr attempt} {
|
||||
with_test_prefix "fg attach $attempt" {
|
||||
|
||||
gdb_test "attach $testpid" \
|
||||
"Attaching to program.*process $testpid.*" \
|
||||
"attach"
|
||||
|
||||
gdb_test "info threads" \
|
||||
"1.*${thread_re}.*\r\n.*2.*${thread_re}.*" \
|
||||
"info threads shows two LWPs"
|
||||
|
||||
gdb_test "detach" "Detaching from .*, process $testpid"
|
||||
}
|
||||
}
|
||||
|
||||
# Same, but use async/background attach.
|
||||
|
||||
# If debugging with target remote, check whether the all-stop variant
|
||||
# of the RSP is being used. If so, we can't run the background tests.
|
||||
if {[target_info exists gdb_protocol]
|
||||
&& ([target_info gdb_protocol] == "remote"
|
||||
|| [target_info gdb_protocol] == "extended-remote")} {
|
||||
|
||||
set test "maint show target-non-stop"
|
||||
gdb_test_multiple "maint show target-non-stop" $test {
|
||||
-re "(is|currently) on.*$gdb_prompt $" {
|
||||
}
|
||||
-re "(is|currently) off.*$gdb_prompt $" {
|
||||
unsupported "bg attach: can't issue info threads while target is running"
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set attempts 3
|
||||
for {set attempt 1} {$attempt <= $attempts} {incr attempt} {
|
||||
with_test_prefix "bg attach $attempt" {
|
||||
|
||||
gdb_test "attach $testpid &" \
|
||||
"Attaching to program.*process $testpid.*" \
|
||||
"attach"
|
||||
|
||||
gdb_test "info threads" \
|
||||
"1.*${thread_re}.*\\(running\\)\r\n.*2.*${thread_re}.*\\(running\\)" \
|
||||
"info threads shows two LWPs"
|
||||
|
||||
gdb_test "detach" "Detaching from .*, process $testpid"
|
||||
}
|
||||
}
|
||||
|
||||
kill_wait_spawned_process $test_spawn_id
|
||||
@@ -100,12 +100,6 @@ proc do_test { cond_bp_target detach_on_fork displaced } {
|
||||
set fork_count 0
|
||||
set ok 0
|
||||
|
||||
if {$displaced == "off"
|
||||
&& [target_info exists gdb_protocol]
|
||||
&& ([target_info gdb_protocol] == "remote"
|
||||
|| [target_info gdb_protocol] == "extended-remote")} {
|
||||
setup_kfail "remote/19496" *-*-*
|
||||
}
|
||||
set test "inferior 1 exited"
|
||||
gdb_test_multiple "" $test {
|
||||
-re "Inferior 1 \(\[^\r\n\]+\) exited normally" {
|
||||
|
||||
@@ -1 +1 @@
|
||||
7.10.50.DATE-git
|
||||
7.11.1
|
||||
|
||||
Reference in New Issue
Block a user