From: Denis PILAT <denis.pilat@st.com>
To: Daniel Jacobowitz <drow@false.org>,
gdb-patches <gdb-patches@sourceware.org>
Subject: Re: [RFC] thread apply commands change selected frame
Date: Wed, 31 Jan 2007 08:58:00 -0000 [thread overview]
Message-ID: <45C05A1A.6010109@st.com> (raw)
In-Reply-To: <45B73813.9060005@st.com>
[-- Attachment #1: Type: text/plain, Size: 727 bytes --]
>>
>> It looks right to me. With a ChangeLog entry and testsuite results
>> from some target with threads, it would be OK to commit.
>>
>
I propose a new implementation that does not change the old behavior of
gdb with respect to the printing of the last frame in case we changed of
thread during "thread apply" command execution.
This implementation does not make any regression in the testsuite for a
i386-linux target.
To me the part that prints the stack frame at the end of execution of
"thread apply" could be entirely removed but this will imply some
changes in the testsuite. I can do that it's up to you.
About the bug initially fixed by this patch, I include some new tests in
threadapply.exp.
--
Denis
[-- Attachment #2: thread.patch --]
[-- Type: text/plain, Size: 6907 bytes --]
2007-01-30 Denis Pilat <denis.pilat@st.com>
* thread.c (make_cleanup_restore_current_thread): New function.
(info_threads_command): Use of make_cleanup_restore_current_thread
to restore the current thread and the selected frame.
(restore_selected_frame): New function.
(struct current_thread_cleanup): Add frame_id field.
(do_restore_current_thread_cleanup): Add restoring of the selected
frame.
(make_cleanup_restore_current_thread): Likewise.
(thread_apply_all_command): backup the selected frame while
entering the function and restore it at exit.
(thread_apply_command): Likewise.
Index: thread.c
===================================================================
--- thread.c (revision 553)
+++ thread.c (working copy)
@@ -65,6 +65,8 @@ static void thread_apply_command (char *
static void restore_current_thread (ptid_t);
static void switch_to_thread (ptid_t ptid);
static void prune_threads (void);
+static struct cleanup *make_cleanup_restore_current_thread (ptid_t,
+ struct frame_id);
void
delete_step_resume_breakpoint (void *arg)
@@ -408,9 +410,14 @@ info_threads_command (char *arg, int fro
struct thread_info *tp;
ptid_t current_ptid;
struct frame_info *cur_frame;
- struct frame_id saved_frame_id = get_frame_id (get_selected_frame (NULL));
+ struct cleanup *old_chain;
+ struct frame_id saved_frame_id;
char *extra_info;
+ /* Backup current thread and selected frame. */
+ saved_frame_id = get_frame_id (get_selected_frame (NULL));
+ old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
+
prune_threads ();
target_find_new_threads ();
current_ptid = inferior_ptid;
@@ -427,30 +434,22 @@ info_threads_command (char *arg, int fro
if (extra_info)
printf_filtered (" (%s)", extra_info);
puts_filtered (" ");
-
+ /* That switch put us at the top of the stack (leaf frame). */
switch_to_thread (tp->ptid);
print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
}
- switch_to_thread (current_ptid);
+ /* Restores the current thread and the frame selected before
+ the "info threads" command. */
+ do_cleanups (old_chain);
- /* Restores the frame set by the user before the "info threads"
- command. We have finished the info-threads display by switching
- back to the current thread. That switch has put us at the top of
- the stack (leaf frame). */
- cur_frame = frame_find_by_id (saved_frame_id);
- if (cur_frame == NULL)
+ /* If case we were not able to find the original frame, print the
+ new selected frame. */
+ if (frame_find_by_id (saved_frame_id) == NULL)
{
- /* Ooops, can't restore, tell user where we are. */
warning (_("Couldn't restore frame in current thread, at frame 0"));
print_stack_frame (get_selected_frame (NULL), 0, LOCATION);
}
- else
- {
- select_frame (cur_frame);
- /* re-show current frame. */
- show_stack_frame (cur_frame);
- }
}
/* Switch from one thread to another. */
@@ -474,13 +473,27 @@ restore_current_thread (ptid_t ptid)
if (!ptid_equal (ptid, inferior_ptid))
{
switch_to_thread (ptid);
- print_stack_frame (get_current_frame (), 1, SRC_LINE);
+ }
+}
+
+static void
+restore_selected_frame (struct frame_id a_frame_id)
+{
+ struct frame_info *selected_frame_info = NULL;
+
+ if (frame_id_eq (a_frame_id, null_frame_id))
+ return;
+
+ if ((selected_frame_info = frame_find_by_id (a_frame_id)) != NULL)
+ {
+ select_frame (selected_frame_info);
}
}
struct current_thread_cleanup
{
ptid_t inferior_ptid;
+ struct frame_id selected_frame_id;
};
static void
@@ -488,15 +501,18 @@ do_restore_current_thread_cleanup (void
{
struct current_thread_cleanup *old = arg;
restore_current_thread (old->inferior_ptid);
+ restore_selected_frame (old->selected_frame_id);
xfree (old);
}
static struct cleanup *
-make_cleanup_restore_current_thread (ptid_t inferior_ptid)
+make_cleanup_restore_current_thread (ptid_t inferior_ptid,
+ struct frame_id a_frame_id)
{
struct current_thread_cleanup *old
= xmalloc (sizeof (struct current_thread_cleanup));
old->inferior_ptid = inferior_ptid;
+ old->selected_frame_id = a_frame_id;
return make_cleanup (do_restore_current_thread_cleanup, old);
}
@@ -516,11 +532,16 @@ thread_apply_all_command (char *cmd, int
struct cleanup *old_chain;
struct cleanup *saved_cmd_cleanup_chain;
char *saved_cmd;
+ struct frame_id saved_frame_id;
+ ptid_t current_ptid;
+ int thread_has_changed = 0;
if (cmd == NULL || *cmd == '\000')
error (_("Please specify a command following the thread ID list"));
-
- old_chain = make_cleanup_restore_current_thread (inferior_ptid);
+
+ current_ptid = inferior_ptid;
+ saved_frame_id = get_frame_id (get_selected_frame (NULL));
+ old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
/* It is safe to update the thread list now, before
traversing it for "thread apply all". MVS */
@@ -540,8 +561,15 @@ thread_apply_all_command (char *cmd, int
strcpy (cmd, saved_cmd); /* Restore exact command used previously */
}
+ if (!ptid_equal (current_ptid, inferior_ptid))
+ thread_has_changed = 1;
+
do_cleanups (saved_cmd_cleanup_chain);
do_cleanups (old_chain);
+ /* Print stack frame only if we changed thread. */
+ if (thread_has_changed)
+ print_stack_frame (get_current_frame (), 1, SRC_LINE);
+
}
static void
@@ -552,6 +580,9 @@ thread_apply_command (char *tidlist, int
struct cleanup *old_chain;
struct cleanup *saved_cmd_cleanup_chain;
char *saved_cmd;
+ struct frame_id saved_frame_id;
+ ptid_t current_ptid;
+ int thread_has_changed = 0;
if (tidlist == NULL || *tidlist == '\000')
error (_("Please specify a thread ID list"));
@@ -561,7 +592,9 @@ thread_apply_command (char *tidlist, int
if (*cmd == '\000')
error (_("Please specify a command following the thread ID list"));
- old_chain = make_cleanup_restore_current_thread (inferior_ptid);
+ current_ptid = inferior_ptid;
+ saved_frame_id = get_frame_id (get_selected_frame (NULL));
+ old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
/* Save a copy of the command in case it is clobbered by
execute_command */
@@ -613,8 +646,14 @@ thread_apply_command (char *tidlist, int
}
}
+ if (!ptid_equal (current_ptid, inferior_ptid))
+ thread_has_changed = 1;
+
do_cleanups (saved_cmd_cleanup_chain);
do_cleanups (old_chain);
+ /* Print stack frame only if we changed thread. */
+ if (thread_has_changed)
+ print_stack_frame (get_current_frame (), 1, SRC_LINE);
}
/* Switch to the specified thread. Will dispatch off to thread_apply_command
[-- Attachment #3: threadapply.exp.patch --]
[-- Type: text/plain, Size: 947 bytes --]
2007-01-30 Denis Pilat <denis.pilat@st.com>
* gdb.threads/threadapply.exp: check that frame is not changed by
the thread apply all command.
Index: testsuite/gdb.threads/threadapply.exp
===================================================================
--- testsuite/gdb.threads/threadapply.exp (revision 553)
+++ testsuite/gdb.threads/threadapply.exp (working copy)
@@ -69,3 +69,10 @@ gdb_test_multiple "define backthread" "d
gdb_test "set backtrace limit 3" ""
gdb_test "thread apply all backthread" "Thread ..*\\\$1 = 0x14.*Thread ..*\\\$2 = 0x14.*Thread ..*\\\$3 = 0x14.*Thread ..*\\\$4 = 0x14.*Thread ..*\\\$5 = 0x14.*Thread ..*\\\$. = 0x14"
+# Go into the thread_function to check that a simple "thread apply"
+# does not change the selected frame.
+gdb_test "step" "thread_function.*"
+gdb_test "up"
+gdb_test "thread apply all print 1"
+gdb_test "down" "#0.*thread_function.*" "Thread apply must not change the selected frame"
+
next prev parent reply other threads:[~2007-01-31 8:58 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-11 11:24 Denis PILAT
2007-01-21 17:33 ` Daniel Jacobowitz
2007-01-24 10:42 ` Denis PILAT
2007-01-31 8:58 ` Denis PILAT [this message]
2007-01-31 14:54 ` Daniel Jacobowitz
2007-01-31 19:30 ` Denis PILAT
2007-01-31 19:33 ` Daniel Jacobowitz
2007-02-01 9:49 ` [RFA] " Denis PILAT
2007-02-01 14:33 ` Daniel Jacobowitz
2007-02-02 12:40 ` Denis PILAT
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=45C05A1A.6010109@st.com \
--to=denis.pilat@st.com \
--cc=drow@false.org \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox