2734 lines
86 KiB
Diff
2734 lines
86 KiB
Diff
http://sourceware.org/ml/gdb-patches/2016-03/msg00013.html
|
||
Subject: [PATCH 1/2] Fix PR gdb/19676: Disable displaced stepping if /proc not mounted
|
||
|
||
On GNU/Linux archs that support displaced stepping, if /proc is not
|
||
mounted, GDB gets stuck not able to step past breakpoints:
|
||
|
||
(gdb) c
|
||
Continuing.
|
||
dl_main (phdr=<optimized out>, phnum=<optimized out>, user_entry=<optimized out>, auxv=<optimized out>) at rtld.c:2163
|
||
2163 LIBC_PROBE (init_complete, 2, LM_ID_BASE, r);
|
||
Cannot find AT_ENTRY auxiliary vector entry.
|
||
(gdb) c
|
||
Continuing.
|
||
dl_main (phdr=<optimized out>, phnum=<optimized out>, user_entry=<optimized out>, auxv=<optimized out>) at rtld.c:2163
|
||
2163 LIBC_PROBE (init_complete, 2, LM_ID_BASE, r);
|
||
Cannot find AT_ENTRY auxiliary vector entry.
|
||
(gdb)
|
||
|
||
That's because GDB can't figure out where the scratch pad is.
|
||
|
||
This is a regression introduced by the earlier changes to make the
|
||
Linux native target always work in non-stop mode.
|
||
|
||
This commit makes GDB detect the case and fallback to stepping over
|
||
breakpoints in-line.
|
||
|
||
gdb/ChangeLog:
|
||
2016-03-01 Pedro Alves <pedro@cascais.lan>
|
||
|
||
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.
|
||
---
|
||
gdb/infrun.c | 3 ++-
|
||
gdb/linux-tdep.c | 3 ++-
|
||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||
|
||
diff --git a/gdb/infrun.c b/gdb/infrun.c
|
||
index 3e8c9e0..696105d 100644
|
||
--- a/gdb/infrun.c
|
||
+++ b/gdb/infrun.c
|
||
@@ -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)
|
||
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
|
||
index 555c302..f197aa7 100644
|
||
--- a/gdb/linux-tdep.c
|
||
+++ b/gdb/linux-tdep.c
|
||
@@ -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. */
|
||
--
|
||
2.5.0
|
||
|
||
|
||
|
||
http://sourceware.org/ml/gdb-patches/2016-03/msg00014.html
|
||
Subject: [PATCH 2/2] Fix PR gdb/19676: Internal error in linux-thread.db.c if /proc not mounted
|
||
|
||
If /proc is not mounted, GDB fails an assertion in find_new_threads_once:
|
||
|
||
Continuing.
|
||
/home/pedro/gdb/mygit/src/gdb/linux-thread-db.c:1249: internal-error: find_new_threads_once: Assertion `!target_has_execution' failed.
|
||
A problem internal to GDB has been detected,
|
||
further debugging may prove unreliable.
|
||
Quit this debugging session? (y or n)
|
||
|
||
That was supposed to catch misuses of td_ta_thr_iter, which is unsafe
|
||
for live debugging. However, if /proc is not mounted, we still
|
||
fallback to using it.
|
||
|
||
I didn't bother with a warning, because GDB already prints several
|
||
others related to failing to open /proc files.
|
||
|
||
gdb/ChangeLog:
|
||
2016-03-01 Pedro Alves <pedro@cascais.lan>
|
||
|
||
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.
|
||
---
|
||
gdb/linux-thread-db.c | 16 ++++++++++------
|
||
1 file changed, 10 insertions(+), 6 deletions(-)
|
||
|
||
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
|
||
index 1eb457d..ce60beb 100644
|
||
--- a/gdb/linux-thread-db.c
|
||
+++ b/gdb/linux-thread-db.c
|
||
@@ -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
|
||
{
|
||
--
|
||
2.5.0
|
||
|
||
|
||
|
||
http://sourceware.org/ml/gdb-patches/2016-03/msg00246.html
|
||
Subject: [patch] Suggest running gdbserver for a PID in container
|
||
|
||
|
||
--azLHFNyN32YCQGCU
|
||
Content-Type: text/plain; charset=us-ascii
|
||
Content-Disposition: inline
|
||
|
||
Hi,
|
||
|
||
currently
|
||
gdb -p <pid from a container>
|
||
will print:
|
||
warning: Target and debugger are in different PID namespaces; thread lists and other data are likely unreliable
|
||
|
||
BTW it is a bit lost in all the other messages. Full screen output is in:
|
||
https://sourceware.org/bugzilla/show_bug.cgi?id=19828
|
||
|
||
It correctly states the problem but it does not say how to solve it.
|
||
|
||
Is at least this little suggestion OK?
|
||
|
||
Originally I wanted to suggest also the Docker "-p 1234:1234" parameter but
|
||
I see the containers are more general topic than just Docker (even LxC etc.).
|
||
|
||
According to Gary future GDBs should be able to work even without gdbserver.
|
||
But currently gdbserver is still required.
|
||
|
||
|
||
Thanks,
|
||
Jan
|
||
|
||
--azLHFNyN32YCQGCU
|
||
Content-Type: text/plain; charset=us-ascii
|
||
Content-Disposition: inline; filename=1
|
||
|
||
gdb/ChangeLog
|
||
2016-03-15 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
||
* linux-thread-db.c (check_pid_namespace_match): Extend the message.
|
||
|
||
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
|
||
index 1eb457d..21166bf 100644
|
||
--- a/gdb/linux-thread-db.c
|
||
+++ b/gdb/linux-thread-db.c
|
||
@@ -1020,7 +1020,8 @@ check_pid_namespace_match (void)
|
||
{
|
||
warning (_ ("Target and debugger are in different PID "
|
||
"namespaces; thread lists and other data are "
|
||
- "likely unreliable"));
|
||
+ "likely unreliable. "
|
||
+ "Connect to gdbserver inside the container."));
|
||
}
|
||
}
|
||
}
|
||
|
||
--azLHFNyN32YCQGCU--
|
||
|
||
|
||
|
||
commit fef3cb9f3aa84018d10866f89228ae3f23e5ca7e
|
||
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
Date: Wed Apr 6 15:57:08 2016 +0200
|
||
|
||
Print the "file" command suggestion in exec_file_locate_attach
|
||
|
||
currently:
|
||
$ gdbserver-7.9 :1234 true &
|
||
$ gdb -q -ex 'target remote :1234' # that -q is not relevant here
|
||
Remote debugging using :1234
|
||
warning: Could not load vsyscall page because no executable was specified
|
||
try using the "file" command first.
|
||
0x00007ffff7ddcc80 in ?? ()
|
||
(gdb) b main
|
||
No symbol table is loaded. Use the "file" command.
|
||
Make breakpoint pending on future shared library load? (y or [n]) _
|
||
|
||
Provide more suggestive message to use the "file" command.
|
||
|
||
gdb/ChangeLog
|
||
2016-04-06 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
Pedro Alves <palves@redhat.com>
|
||
|
||
* exec.c (exec_file_locate_attach): Print warning for unsupported
|
||
target_pid_to_exec_file.
|
||
* symfile-mem.c (add_vsyscall_page): Remove the "file" command
|
||
message part.
|
||
|
||
### a/gdb/ChangeLog
|
||
### b/gdb/ChangeLog
|
||
## -1,3 +1,11 @@
|
||
+2016-04-06 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
+ Pedro Alves <palves@redhat.com>
|
||
+
|
||
+ * exec.c (exec_file_locate_attach): Print warning for unsupported
|
||
+ target_pid_to_exec_file.
|
||
+ * symfile-mem.c (add_vsyscall_page): Remove the "file" command
|
||
+ message part.
|
||
+
|
||
2016-04-04 Simon Marchi <simon.marchi@ericsson.com>
|
||
|
||
* cli/cli-decode.c (help_cmd_list): Fix function doc and remove
|
||
--- a/gdb/exec.c
|
||
+++ b/gdb/exec.c
|
||
@@ -151,7 +151,13 @@ exec_file_locate_attach (int pid, int from_tty)
|
||
/* Try to determine a filename from the process itself. */
|
||
exec_file = target_pid_to_exec_file (pid);
|
||
if (exec_file == NULL)
|
||
- return;
|
||
+ {
|
||
+ warning (_("No executable has been specified and target does not "
|
||
+ "support\n"
|
||
+ "determining executable automatically. "
|
||
+ "Try using the \"file\" command."));
|
||
+ return;
|
||
+ }
|
||
|
||
/* If gdb_sysroot is not empty and the discovered filename
|
||
is absolute then prefix the filename with gdb_sysroot. */
|
||
--- a/gdb/symfile-mem.c
|
||
+++ b/gdb/symfile-mem.c
|
||
@@ -214,8 +214,7 @@ add_vsyscall_page (struct target_ops *target, int from_tty)
|
||
format should fix this. */
|
||
{
|
||
warning (_("Could not load vsyscall page "
|
||
- "because no executable was specified\n"
|
||
- "try using the \"file\" command first."));
|
||
+ "because no executable was specified"));
|
||
return;
|
||
}
|
||
args.bfd = bfd;
|
||
|
||
|
||
|
||
commit 2ef34d11f61d79dcb152713aa059051d8cd3295d
|
||
Author: Markus Metzger <markus.t.metzger@intel.com>
|
||
Date: Fri Feb 5 09:32:53 2016 +0100
|
||
|
||
btrace: fix PR gdb/19829
|
||
|
||
This is a backport of
|
||
|
||
33b4777ca1b7 btrace, frame: fix crash in get_frame_type
|
||
a038fa3e14a4 stack: check frame_unwind_caller_id
|
||
2f3ef606b912 frame: add skip_tailcall_frames
|
||
|
||
In skip_artificial_frames we repeatedly call get_prev_frame_always until we get
|
||
a non-inline and non-tailcall frame assuming that there must be such a frame
|
||
eventually.
|
||
|
||
For record targets, however, we may have a frame chain that consists only of
|
||
artificial frames. This leads to a crash in get_frame_type when dereferencing a
|
||
NULL frame pointer.
|
||
|
||
Change skip_artificial_frames and skip_tailcall_frames to return NULL in such a
|
||
case and modify each caller to cope with a NULL return.
|
||
|
||
In frame_unwind_caller_pc and frame_unwind_caller_arch, we simply assert that
|
||
the returned value is not NULL. Their caller was supposed to check
|
||
frame_unwind_caller_id before calling those functions.
|
||
|
||
In other cases, we thrown an error.
|
||
|
||
In infcmd further move the skip_tailcall_frames call to the forward-stepping
|
||
case since we don't need a frame for reverse execution and we don't want to fail
|
||
because of that. Reverse-finish does make sense for a tailcall frame.
|
||
|
||
gdb/
|
||
* 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.
|
||
|
||
testsuite/
|
||
* 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.
|
||
|
||
### a/gdb/ChangeLog
|
||
### b/gdb/ChangeLog
|
||
## -1,3 +1,19 @@
|
||
+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
|
||
--- a/gdb/frame.c
|
||
+++ b/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. */
|
||
--- a/gdb/frame.h
|
||
+++ b/gdb/frame.h
|
||
@@ -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) */
|
||
--- a/gdb/infcmd.c
|
||
+++ b/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);
|
||
+ }
|
||
}
|
||
|
||
|
||
--- a/gdb/stack.c
|
||
+++ b/gdb/stack.c
|
||
@@ -1509,27 +1509,32 @@ frame_info (char *addr_exp, int from_tty)
|
||
wrap_here (" ");
|
||
printf_filtered ("saved %s = ", pc_regname);
|
||
|
||
- TRY
|
||
- {
|
||
- caller_pc = frame_unwind_caller_pc (fi);
|
||
- caller_pc_p = 1;
|
||
- }
|
||
- CATCH (ex, RETURN_MASK_ERROR)
|
||
+ if (!frame_id_p (frame_unwind_caller_id (fi)))
|
||
+ val_print_unavailable (gdb_stdout);
|
||
+ else
|
||
{
|
||
- 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);
|
||
### a/gdb/testsuite/ChangeLog
|
||
### b/gdb/testsuite/ChangeLog
|
||
## -1,3 +1,11 @@
|
||
+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
|
||
--- /dev/null
|
||
+++ b/gdb/testsuite/gdb.btrace/i686-tailcall-only.S
|
||
@@ -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
|
||
--- /dev/null
|
||
+++ b/gdb/testsuite/gdb.btrace/tailcall-only.c
|
||
@@ -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;
|
||
+}
|
||
--- /dev/null
|
||
+++ b/gdb/testsuite/gdb.btrace/tailcall-only.exp
|
||
@@ -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" ".*"
|
||
--- /dev/null
|
||
+++ b/gdb/testsuite/gdb.btrace/x86_64-tailcall-only.S
|
||
@@ -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
|
||
|
||
|
||
|
||
commit cd64cabb8c66a5565fc33bf66a07c08bc767e413
|
||
Author: Yichao Yu <yyc1992@gmail.com>
|
||
Date: Thu Mar 31 19:28:47 2016 +0100
|
||
|
||
Fix PR gdb/19858: GDB doesn't register the JIT libraries on attach
|
||
|
||
Ref: https://sourceware.org/ml/gdb/2016-03/msg00023.html
|
||
|
||
GDB currently fails to fetch the list of already-registered JIT
|
||
modules on attach.
|
||
|
||
Nothing is calling jit_inferior_init, which is what is responsible for
|
||
walking the JIT object list at init time.
|
||
|
||
Despite the misleading naming, jit_inferior_created_hook ->
|
||
jit_inferior_init is only called when the inferior execs.
|
||
|
||
This regressed with the fix for PR gdb/13431 (03bef283c2d3):
|
||
https://sourceware.org/ml/gdb-patches/2012-02/msg00023.html which
|
||
removed the inferior_created (jit_inferior_created_observer)
|
||
observer.
|
||
|
||
Adding an inferior_created observer back fixes the issue.
|
||
|
||
In turn, this exposes a bug in jit_breakpoint_re_set_internal as well,
|
||
which is returning the wrong result when we already have the
|
||
breakpoint at the right address.
|
||
|
||
gdb/ChangeLog:
|
||
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.
|
||
|
||
Signed-off-by: Pedro Alves <palves@redhat.com>
|
||
|
||
### a/gdb/ChangeLog
|
||
### b/gdb/ChangeLog
|
||
## -1,3 +1,12 @@
|
||
+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
|
||
--- a/gdb/jit.c
|
||
+++ b/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);
|
||
|
||
|
||
|
||
|
||
commit 89df5d6cce0e91c4b34c7a62ba4a68756a8ed4e7
|
||
Author: Pedro Alves <palves@redhat.com>
|
||
Date: Thu Mar 31 19:28:47 2016 +0100
|
||
|
||
Make gdb.base/jit.exp binaries unique
|
||
|
||
This testcase compiles the same program and library differently
|
||
multiple times using the same file names. Make them unique, to make
|
||
it easier to debug test problems.
|
||
|
||
gdb/testsuite/ChangeLog:
|
||
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.
|
||
|
||
### a/gdb/testsuite/ChangeLog
|
||
### b/gdb/testsuite/ChangeLog
|
||
## -1,3 +1,10 @@
|
||
+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
|
||
--- a/gdb/testsuite/gdb.base/jit.exp
|
||
+++ b/gdb/testsuite/gdb.base/jit.exp
|
||
@@ -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
|
||
@@ -109,7 +110,7 @@ proc one_jit_test {count match_str} {
|
||
}
|
||
}
|
||
|
||
-if {[compile_jit_test jit.exp {}] < 0} {
|
||
+if {[compile_jit_test jit.exp "" {}] < 0} {
|
||
return
|
||
}
|
||
one_jit_test 1 "${hex} jit_function_0000"
|
||
@@ -117,7 +118,7 @@ one_jit_test 2 "${hex} jit_function_0000\[\r\n\]+${hex} jit_function_0001"
|
||
|
||
with_test_prefix PIE {
|
||
if {[compile_jit_test "jit.exp PIE tests" \
|
||
- {additional_flags=-fPIE ldflags=-pie}] < 0} {
|
||
+ "-pie" {additional_flags=-fPIE ldflags=-pie}] < 0} {
|
||
return
|
||
}
|
||
|
||
|
||
|
||
|
||
commit 85af34ee0211eedf8d30a5c44dfc59dddf8b512a
|
||
Author: Pedro Alves <palves@redhat.com>
|
||
Date: Thu Mar 31 19:28:47 2016 +0100
|
||
|
||
Add regression test for PR gdb/19858 (JIT code registration on attach)
|
||
|
||
This test would fail without the previous gdb/jit.c fix:
|
||
|
||
(gdb) attach 23031
|
||
Attaching to program: .../build/gdb/testsuite/outputs/gdb.base/jit/jit-main, process 23031
|
||
[...]
|
||
207 WAIT_FOR_GDB; i = 0; /* gdb break here 1 */
|
||
(gdb) PASS: gdb.base/jit.exp: attach: one_jit_test-2: attach
|
||
set var wait_for_gdb = 0
|
||
(gdb) PASS: gdb.base/jit.exp: attach: one_jit_test-2: set var wait_for_gdb = 0
|
||
info function ^jit_function
|
||
All functions matching regular expression "^jit_function":
|
||
(gdb) FAIL: gdb.base/jit.exp: attach: one_jit_test-2: info function ^jit_function
|
||
|
||
gdb/testsuite/ChangeLog:
|
||
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.
|
||
|
||
### a/gdb/testsuite/ChangeLog
|
||
### b/gdb/testsuite/ChangeLog
|
||
## -1,6 +1,21 @@
|
||
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.
|
||
--- a/gdb/testsuite/gdb.base/jit-main.c
|
||
+++ b/gdb/testsuite/gdb.base/jit-main.c
|
||
@@ -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 */
|
||
}
|
||
--- a/gdb/testsuite/gdb.base/jit.exp
|
||
+++ b/gdb/testsuite/gdb.base/jit.exp
|
||
@@ -66,7 +66,49 @@ proc compile_jit_test {testname binsuffix 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
|
||
|
||
@@ -91,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"
|
||
|
||
@@ -102,8 +143,8 @@ 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\":"
|
||
@@ -113,8 +154,22 @@ proc one_jit_test {count match_str} {
|
||
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
|
||
+
|
||
+# 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
|
||
+ }
|
||
+
|
||
+ 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" \
|
||
@@ -122,5 +177,5 @@ with_test_prefix PIE {
|
||
return
|
||
}
|
||
|
||
- one_jit_test 1 "${hex} jit_function_0000"
|
||
+ one_jit_test 1 "${hex} jit_function_0000" 0
|
||
}
|
||
|
||
|
||
|
||
commit 2d35e871274a48331c4d6c7b3e4fbee42b901f33
|
||
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
Date: Thu Apr 7 22:18:49 2016 +0200
|
||
|
||
testsuite: Fix false FAILs with .bashrc GDBHISTFILE=...
|
||
|
||
$ GDBHISTFILE=/tmp/gdbhistfile runtest gdb.base/gdbhistsize-history.exp gdb.base/gdbinit-history.exp
|
||
Running ./gdb.base/gdbinit-history.exp ...
|
||
FAIL: gdb.base/gdbinit-history.exp: home=gdbinit-history/unlimited gdbhistsize=1000: show commands
|
||
FAIL: gdb.base/gdbinit-history.exp: home=gdbinit-history/unlimited gdbhistsize=foo: show commands
|
||
Running ./gdb.base/gdbhistsize-history.exp ...
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize=: show commands
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize=20: show commands
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize= 20 : show commands
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize=-5: show commands
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize=not_an_integer: show commands
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize=10zab: show commands
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize=-5ab: show commands
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize=99999999999999999999999999999999999: show commands
|
||
FAIL: gdb.base/gdbhistsize-history.exp: histsize=50: show commands
|
||
|
||
This happens for my setup due to my:
|
||
$ grep GDB ~/.bashrc
|
||
export GDBHISTFILE="$HOME/.gdb_history"
|
||
|
||
gdb/testsuite/ChangeLog
|
||
2016-04-07 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
||
* gdb.base/gdbhistsize-history.exp: Save and unset GDBHISTFILE and
|
||
GDBHISTSIZE prior to the tests.
|
||
* gdb.base/gdbinit-history.exp: Likewise.
|
||
|
||
### a/gdb/testsuite/ChangeLog
|
||
### b/gdb/testsuite/ChangeLog
|
||
## -1,4 +1,10 @@
|
||
-2015-04-07 Pedro Alves <palves@redhat.com>
|
||
+2016-04-07 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
+
|
||
+ * gdb.base/gdbhistsize-history.exp: Save and unset GDBHISTFILE and
|
||
+ GDBHISTSIZE prior to the tests.
|
||
+ * gdb.base/gdbinit-history.exp: Likewise.
|
||
+
|
||
+2016-04-07 Pedro Alves <palves@redhat.com>
|
||
|
||
* gdb.compile/compile.exp: Use gdb_compile with "shlib=" option
|
||
instead of build_executable. Use gdb_load_shlibs.
|
||
--- a/gdb/testsuite/gdb.base/gdbhistsize-history.exp
|
||
+++ b/gdb/testsuite/gdb.base/gdbhistsize-history.exp
|
||
@@ -32,7 +32,13 @@ if { [is_remote host] } {
|
||
proc test_histsize_history_setting { histsize size { env_var "GDBHISTSIZE" } } {
|
||
global env
|
||
|
||
- save_vars { env($env_var) } {
|
||
+ save_vars { env(GDBHISTFILE) env(GDBHISTSIZE) env($env_var) } {
|
||
+ # These environment variables take precedence over whatever
|
||
+ # history size is set in .gdbinit. Make sure the former is not
|
||
+ # set.
|
||
+ unset -nocomplain env(GDBHISTFILE)
|
||
+ unset -nocomplain env(GDBHISTSIZE)
|
||
+
|
||
set env($env_var) $histsize
|
||
|
||
with_test_prefix "histsize=$histsize" {
|
||
--- a/gdb/testsuite/gdb.base/gdbinit-history.exp
|
||
+++ b/gdb/testsuite/gdb.base/gdbinit-history.exp
|
||
@@ -36,12 +36,13 @@ proc test_gdbinit_history_setting { home size { gdbhistsize_val "-" } } {
|
||
global srcdir
|
||
global subdir
|
||
|
||
- save_vars { INTERNAL_GDBFLAGS env(GDBHISTSIZE) env(HOME) } {
|
||
+ save_vars { INTERNAL_GDBFLAGS env(GDBHISTFILE) env(GDBHISTSIZE) env(HOME) } {
|
||
set env(HOME) "$srcdir/$subdir/$home"
|
||
|
||
- # The GDBHISTSIZE environment variable takes precedence over whatever
|
||
+ # These environment variables take precedence over whatever
|
||
# history size is set in .gdbinit. Make sure the former is not
|
||
# set.
|
||
+ unset -nocomplain env(GDBHISTFILE)
|
||
unset -nocomplain env(GDBHISTSIZE)
|
||
|
||
if { $gdbhistsize_val != "-" } {
|
||
@@ -77,10 +78,11 @@ proc test_no_truncation_of_unlimited_history_file { } {
|
||
global env
|
||
global INTERNAL_GDBFLAGS
|
||
|
||
- save_vars { INTERNAL_GDBFLAGS env(GDBHISTSIZE) } {
|
||
- # The GDBHISTSIZE environment variable takes precedence over whatever
|
||
+ save_vars { INTERNAL_GDBFLAGS env(GDBHISTFILE) env(GDBHISTSIZE) } {
|
||
+ # These environment variables take precedence over whatever
|
||
# history size is set in .gdbinit. Make sure the former is not
|
||
# set.
|
||
+ unset -nocomplain env(GDBHISTFILE)
|
||
unset -nocomplain env(GDBHISTSIZE)
|
||
|
||
set temp_gdbinit [standard_output_file "gdbinit-history.gdbinit"]
|
||
|
||
|
||
|
||
commit 065005336492337c92d06e87544646635a5b9566
|
||
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
Date: Fri Apr 8 15:38:53 2016 +0200
|
||
|
||
testsuite: Fix for gcc-4.8: gdb.base/jit.exp gdb.base/jit-so.exp
|
||
|
||
on CentOS-7.2 I get
|
||
|
||
Running /home/jkratoch/redhat/gdb-test-reg/gdb/testsuite/gdb.base/jit.exp ...
|
||
FAIL: gdb.base/jit.exp: one_jit_test-1: continue to breakpoint: break here 2 (the program exited)
|
||
FAIL: gdb.base/jit.exp: one_jit_test-2: continue to breakpoint: break here 2 (the program exited)
|
||
FAIL: gdb.base/jit.exp: attach: one_jit_test-2: continue to breakpoint: break here 2 (the program exited)
|
||
FAIL: gdb.base/jit.exp: attach: one_jit_test-2: break here 2: set var wait_for_gdb = 1
|
||
FAIL: gdb.base/jit.exp: attach: one_jit_test-2: break here 2: detach (the program is no longer running)
|
||
FAIL: gdb.base/jit.exp: attach: one_jit_test-2: break here 2: attach
|
||
FAIL: gdb.base/jit.exp: attach: one_jit_test-2: break here 2: set var wait_for_gdb = 0
|
||
FAIL: gdb.base/jit.exp: PIE: one_jit_test-1: continue to breakpoint: break here 2 (the program exited)
|
||
Running /home/jkratoch/redhat/gdb-test-reg/gdb/testsuite/gdb.base/jit-so.exp ...
|
||
FAIL: gdb.base/jit-so.exp: one_jit_test-1: continue to breakpoint: break here 2 (the program exited)
|
||
FAIL: gdb.base/jit-so.exp: one_jit_test-2: continue to breakpoint: break here 2 (the program exited)
|
||
|
||
since:
|
||
|
||
85af34ee0211eedf8d30a5c44dfc59dddf8b512a is the first bad commit
|
||
commit 85af34ee0211eedf8d30a5c44dfc59dddf8b512a
|
||
Author: Pedro Alves <palves@redhat.com>
|
||
Date: Thu Mar 31 19:28:47 2016 +0100
|
||
Add regression test for PR gdb/19858 (JIT code registration on attach)
|
||
|
||
The compiled code's .debug_line is wrong (for the simplistic approach of GDB
|
||
to put a breakpoint on the first address belonging to that source line) and so
|
||
GDB misses the breakpoint at the last line:
|
||
WAIT_FOR_GDB; return 0; /* gdb break here 2 */
|
||
|
||
Most of the patch is just about reindentation, no changes there.
|
||
|
||
gdb/testsuite/ChangeLog
|
||
2016-04-08 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
||
Fix compatibility with gcc-4.8.5-4.el7.x86_64.
|
||
* gdb.base/jit-main.c: Use exit after usage.
|
||
|
||
### a/gdb/testsuite/ChangeLog
|
||
### b/gdb/testsuite/ChangeLog
|
||
## -1,3 +1,8 @@
|
||
+2016-04-08 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
+
|
||
+ Fix compatibility with gcc-4.8.5-4.el7.x86_64.
|
||
+ * gdb.base/jit-main.c: Use exit after usage.
|
||
+
|
||
2016-04-07 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
||
* gdb.base/gdbhistsize-history.exp: Save and unset GDBHISTFILE and
|
||
--- a/gdb/testsuite/gdb.base/jit-main.c
|
||
+++ b/gdb/testsuite/gdb.base/jit-main.c
|
||
@@ -138,7 +138,8 @@ MAIN (int argc, char *argv[])
|
||
{
|
||
/* These variables are here so they can easily be set from jit.exp. */
|
||
const char *libname = NULL;
|
||
- int count = 0;
|
||
+ int count = 0, i, fd;
|
||
+ struct stat st;
|
||
|
||
alarm (300);
|
||
|
||
@@ -147,90 +148,89 @@ MAIN (int argc, char *argv[])
|
||
count = count; /* gdb break here 0 */
|
||
|
||
if (argc < 2)
|
||
- usage (argv[0]);
|
||
- else
|
||
{
|
||
- int i, fd;
|
||
- struct stat st;
|
||
+ usage (argv[0]);
|
||
+ exit (1);
|
||
+ }
|
||
|
||
- if (libname == NULL)
|
||
- /* Only set if not already set from GDB. */
|
||
- libname = argv[1];
|
||
+ if (libname == NULL)
|
||
+ /* Only set if not already set from GDB. */
|
||
+ libname = argv[1];
|
||
|
||
- if (argc > 2 && count == 0)
|
||
- /* Only set if not already set from GDB. */
|
||
- count = atoi (argv[2]);
|
||
+ if (argc > 2 && count == 0)
|
||
+ /* Only set if not already set from GDB. */
|
||
+ count = atoi (argv[2]);
|
||
|
||
- printf ("%s:%d: libname = %s, count = %d\n", __FILE__, __LINE__,
|
||
- libname, count);
|
||
+ printf ("%s:%d: libname = %s, count = %d\n", __FILE__, __LINE__,
|
||
+ libname, count);
|
||
|
||
- if ((fd = open (libname, O_RDONLY)) == -1)
|
||
- {
|
||
- fprintf (stderr, "open (\"%s\", O_RDONLY): %s\n", libname,
|
||
- strerror (errno));
|
||
- exit (1);
|
||
- }
|
||
+ if ((fd = open (libname, O_RDONLY)) == -1)
|
||
+ {
|
||
+ fprintf (stderr, "open (\"%s\", O_RDONLY): %s\n", libname,
|
||
+ strerror (errno));
|
||
+ exit (1);
|
||
+ }
|
||
|
||
- if (fstat (fd, &st) != 0)
|
||
- {
|
||
- fprintf (stderr, "fstat (\"%d\"): %s\n", fd, strerror (errno));
|
||
- exit (1);
|
||
- }
|
||
+ if (fstat (fd, &st) != 0)
|
||
+ {
|
||
+ fprintf (stderr, "fstat (\"%d\"): %s\n", fd, strerror (errno));
|
||
+ exit (1);
|
||
+ }
|
||
|
||
- for (i = 0; i < count; ++i)
|
||
- {
|
||
- const void *const addr = mmap (0, st.st_size, PROT_READ|PROT_WRITE,
|
||
- MAP_PRIVATE, fd, 0);
|
||
- struct jit_code_entry *const entry = calloc (1, sizeof (*entry));
|
||
-
|
||
- if (addr == MAP_FAILED)
|
||
- {
|
||
- fprintf (stderr, "mmap: %s\n", strerror (errno));
|
||
- exit (1);
|
||
- }
|
||
-
|
||
- update_locations (addr, i);
|
||
-
|
||
- /* Link entry at the end of the list. */
|
||
- entry->symfile_addr = (const char *)addr;
|
||
- entry->symfile_size = st.st_size;
|
||
- entry->prev_entry = __jit_debug_descriptor.relevant_entry;
|
||
- __jit_debug_descriptor.relevant_entry = entry;
|
||
-
|
||
- if (entry->prev_entry != NULL)
|
||
- entry->prev_entry->next_entry = entry;
|
||
- else
|
||
- __jit_debug_descriptor.first_entry = entry;
|
||
-
|
||
- /* Notify GDB. */
|
||
- __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
|
||
- __jit_debug_register_code ();
|
||
- }
|
||
+ for (i = 0; i < count; ++i)
|
||
+ {
|
||
+ const void *const addr = mmap (0, st.st_size, PROT_READ|PROT_WRITE,
|
||
+ MAP_PRIVATE, fd, 0);
|
||
+ struct jit_code_entry *const entry = calloc (1, sizeof (*entry));
|
||
+
|
||
+ if (addr == MAP_FAILED)
|
||
+ {
|
||
+ fprintf (stderr, "mmap: %s\n", strerror (errno));
|
||
+ exit (1);
|
||
+ }
|
||
+
|
||
+ update_locations (addr, i);
|
||
+
|
||
+ /* Link entry at the end of the list. */
|
||
+ entry->symfile_addr = (const char *)addr;
|
||
+ entry->symfile_size = st.st_size;
|
||
+ entry->prev_entry = __jit_debug_descriptor.relevant_entry;
|
||
+ __jit_debug_descriptor.relevant_entry = entry;
|
||
+
|
||
+ if (entry->prev_entry != NULL)
|
||
+ entry->prev_entry->next_entry = entry;
|
||
+ else
|
||
+ __jit_debug_descriptor.first_entry = entry;
|
||
+
|
||
+ /* Notify GDB. */
|
||
+ __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
|
||
+ __jit_debug_register_code ();
|
||
+ }
|
||
|
||
- WAIT_FOR_GDB; 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)
|
||
- {
|
||
- struct jit_code_entry *const entry =
|
||
- __jit_debug_descriptor.relevant_entry;
|
||
- struct jit_code_entry *const prev_entry = entry->prev_entry;
|
||
-
|
||
- if (prev_entry != NULL)
|
||
- {
|
||
- prev_entry->next_entry = NULL;
|
||
- entry->prev_entry = NULL;
|
||
- }
|
||
- else
|
||
- __jit_debug_descriptor.first_entry = NULL;
|
||
-
|
||
- /* Notify GDB. */
|
||
- __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
|
||
- __jit_debug_register_code ();
|
||
-
|
||
- __jit_debug_descriptor.relevant_entry = prev_entry;
|
||
- free (entry);
|
||
- }
|
||
+ /* Now unregister them all in reverse order. */
|
||
+ while (__jit_debug_descriptor.relevant_entry != NULL)
|
||
+ {
|
||
+ struct jit_code_entry *const entry =
|
||
+ __jit_debug_descriptor.relevant_entry;
|
||
+ struct jit_code_entry *const prev_entry = entry->prev_entry;
|
||
+
|
||
+ if (prev_entry != NULL)
|
||
+ {
|
||
+ prev_entry->next_entry = NULL;
|
||
+ entry->prev_entry = NULL;
|
||
+ }
|
||
+ else
|
||
+ __jit_debug_descriptor.first_entry = NULL;
|
||
+
|
||
+ /* Notify GDB. */
|
||
+ __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
|
||
+ __jit_debug_register_code ();
|
||
+
|
||
+ __jit_debug_descriptor.relevant_entry = prev_entry;
|
||
+ free (entry);
|
||
}
|
||
+
|
||
WAIT_FOR_GDB; return 0; /* gdb break here 2 */
|
||
}
|
||
|
||
|
||
|
||
commit 6b9ef0d488c556339aea7b095ef7a9b6bf6b1af1
|
||
Author: Pedro Alves <palves@redhat.com>
|
||
Date: Wed Apr 13 14:34:00 2016 +0100
|
||
|
||
Fix PR remote/19840: gdb crashes on reverse-stepi
|
||
|
||
Reverse debugging against a remote target that does reverse debugging
|
||
itself (with the bs/bc packets) always trips on:
|
||
|
||
(gdb) target remote localhost:...
|
||
(gdb) reverse-stepi
|
||
../../gdb/target.c:602: internal-error: default_execution_direction: to_execution_direction must be implemented for reverse async
|
||
|
||
I missed adding a to_execution_direction method to remote.c in commit
|
||
3223143295b5 (Adds target_execution_direction to make record targets
|
||
support async mode), GDB 7.4 time. Later, GDB 7.8 switched to
|
||
target-async on by default, making the regression user-visible by
|
||
default too.
|
||
|
||
Fix is simply to add the missing to_execution_direction implementation
|
||
to target remote.
|
||
|
||
Tested by Andi Kleen against Simics.
|
||
|
||
gdb/ChangeLog:
|
||
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.
|
||
|
||
### a/gdb/ChangeLog
|
||
### b/gdb/ChangeLog
|
||
## -1,3 +1,15 @@
|
||
+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
|
||
--- a/gdb/remote.c
|
||
+++ b/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;
|
||
@@ -4928,6 +4932,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 +5569,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)
|
||
@@ -13018,6 +13026,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)
|
||
{
|
||
@@ -13163,6 +13182,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
|
||
|
||
|
||
|
||
commit a6ff23076f49c6322d96a76e0098f8019139bc4e
|
||
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
Date: Wed Apr 27 21:27:40 2016 +0200
|
||
|
||
Workaround gdbserver<7.7 for setfs
|
||
|
||
With current FSF GDB HEAD and old FSF gdbserver I expected I could do:
|
||
gdb -ex 'file target:/root/redhat/threadit' -ex 'target remote :1234'
|
||
(supplying that unsupported qXfer:exec-file:read by "file")
|
||
But that does not work because:
|
||
Sending packet: $vFile:setfs:0#bf...Packet received: OK
|
||
Packet vFile:setfs (hostio-setfs) is supported
|
||
...
|
||
Sending packet: $vFile:setfs:104#24...Packet received: OK
|
||
"target:/root/redhat/threadit": could not open as an executable file: Invalid argument
|
||
|
||
GDB documentation says:
|
||
The valid responses to Host I/O packets are:
|
||
An empty response indicates that this operation is not recognized.
|
||
|
||
This "empty response" vs. "OK" was a bug in gdbserver < 7.7. It was fixed by:
|
||
commit e7f0d979dd5cc4f8b658df892e93db69d6d660b7
|
||
Author: Yao Qi <yao@codesourcery.com>
|
||
Date: Tue Dec 10 21:59:20 2013 +0800
|
||
Fix a bug in matching notifications.
|
||
Message-ID: <1386684626-11415-1-git-send-email-yao@codesourcery.com>
|
||
https://sourceware.org/ml/gdb-patches/2013-12/msg00373.html
|
||
2013-12-10 Yao Qi <yao@codesourcery.com>
|
||
* notif.c (handle_notif_ack): Return 0 if no notification
|
||
matches.
|
||
|
||
with unpatched old FSF gdbserver and patched FSF GDB HEAD:
|
||
gdb -ex 'file target:/root/redhat/threadit' -ex 'target remote :1234'
|
||
Sending packet: $vFile:setfs:0#bf...Packet received: OK
|
||
Packet vFile:setfs (hostio-setfs) is NOT supported
|
||
...
|
||
(gdb) info sharedlibrary
|
||
From To Syms Read Shared Object Library
|
||
0x00007ffff7ddbae0 0x00007ffff7df627a Yes (*) target:/lib64/ld-linux-x86-64.so.2
|
||
0x00007ffff7bc48a0 0x00007ffff7bcf514 Yes (*) target:/lib64/libpthread.so.0
|
||
|
||
gdb/ChangeLog
|
||
2016-04-27 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||
|
||
* remote.c (remote_start_remote): Detect PACKET_vFile_setfs.support.
|
||
|
||
### a/gdb/ChangeLog
|
||
### b/gdb/ChangeLog
|
||
## -1,3 +1,7 @@
|
||
+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
|
||
--- a/gdb/remote.c
|
||
+++ b/gdb/remote.c
|
||
@@ -4021,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,
|
||
|
||
|
||
|
||
commit b631e59ba05af7c888838d3e2d6d408bfe60b57f
|
||
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||
Date: Tue May 3 09:40:54 2016 +0100
|
||
|
||
[gdb] Fix -Wparentheses warnings
|
||
|
||
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.
|
||
|
||
### a/gdb/ChangeLog
|
||
### b/gdb/ChangeLog
|
||
## -1,3 +1,10 @@
|
||
+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-05-02 Eli Zaretskii <eliz@gnu.org>
|
||
|
||
* windows-nat.c (_initialize_check_for_gdb_ini): Fix off-by-one
|
||
--- a/gdb/symfile.c
|
||
+++ b/gdb/symfile.c
|
||
@@ -3285,19 +3285,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;
|
||
}
|
||
|
||
@@ -3312,9 +3314,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;
|
||
}
|
||
@@ -3330,31 +3334,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;
|
||
-
|
||
- 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");
|
||
-
|
||
- nmapped++;
|
||
- }
|
||
+ {
|
||
+ 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);
|
||
+
|
||
+ 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++;
|
||
+ }
|
||
+ }
|
||
if (nmapped == 0)
|
||
printf_filtered (_("No sections are mapped.\n"));
|
||
}
|