Re: [PATCH 3/4] New agent command 'kill' and used by gdbserver

Yao Qi
2012-06-20T13:49:35Z

On 06/16/2012 03:24 AM, Pedro Alves wrote:
>
> I'd really rather see that fixed now. Even with single process,
> you may get here without a selected inferior at all. We just need
> to lookup a thread of PID, and select it as current_inferior for the
> duration of run_inferior_command, I think? (wrapped with the
> save_inferior dance).
>
>> > +int
>> > +kill_inferior (int pid)
>> > +{
>
>> > + char buf[IPA_CMD_BUF_SIZE];
>> > +
>> > + if (!maybe_write_ipa_not_loaded (buf))
>> > + {
>> > + strcpy (buf, "close");
>> > + /* FIXME: It is wrong to assume PID is the current process. In
>> > + a multiple-process scenario, we may run inferior command on
>> > + the wrong process. */
>> > + run_inferior_command (buf, strlen (buf) + 1);
>> > + }
>
> I'd rather have this whole block be factored out to a function
> in tracepoint.c (tracepoint_about_to_kill for example). More so
> with a fix to set current_inferior around run_inferior_command.
> Then we wouldn't have to export details of the IPA, such as
> maybe_write_ipa_not_loaded or run_inferior_command.

Here is the new one.

--
Yao (é½å°§)

gdb/gdbserver:

2012-06-14 Yao Qi <yao@codesourcery.com>

* server.h: Declare gdb_agent_about_to_close.
* target.c (kill_inferior): Include "agent.h".
New. Send command 'kill'.
* target.h (kill_inferior): Removed macro.
* tracepoint.c (gdb_agent_about_to_close): New.
(gdb_agent_helper_thread): Handle command 'close'.
Wait endlessly until the inferior stops.
---
gdb/gdbserver/server.h | 1 +
gdb/gdbserver/target.c | 8 +++++++
gdb/gdbserver/target.h | 3 +--
gdb/gdbserver/tracepoint.c | 53 +++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 02dfa29..752bc3b 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -467,6 +467,7 @@ void stop_tracing (void);

int claim_trampoline_space (ULONGEST used, CORE_ADDR *trampoline);
int have_fast_tracepoint_trampoline_buffer (char *msgbuf);
+void gdb_agent_about_to_close (int pid);
#endif

struct traceframe;
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index 7539476..e8b2b08 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -182,3 +182,11 @@ target_waitstatus_to_string (const struct target_waitstatus *ws)

return buf;
}
+
+int
+kill_inferior (int pid)
+{
+ gdb_agent_about_to_close (pid);
+
+ return (*the_target->kill) (pid);
+}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 0cf5687..9f96e04 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -409,8 +409,7 @@ void set_target_ops (struct target_ops *);
#define myattach(pid) \
(*the_target->attach) (pid)

-#define kill_inferior(pid) \
- (*the_target->kill) (pid)
+int kill_inferior (int);

#define detach_inferior(pid) \
(*the_target->detach) (pid)
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 8fcaa46..7ad77f0 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -3923,6 +3923,38 @@ cmd_qtstmat (char *packet)
run_inferior_command (packet, strlen (packet) + 1);
}

+/* Sent the agent a command to close it. */
+
+void
+gdb_agent_about_to_close (int pid)
+{
+ char buf[IPA_CMD_BUF_SIZE];
+
+ if (!maybe_write_ipa_not_loaded (buf))
+ {
+ struct thread_info *save_inferior;
+ struct inferior_list_entry *inf = all_threads.head;
+
+ save_inferior = current_inferior;
+
+ /* Find a certain thread which belongs to process PID. */
+ while (inf != NULL)
+ {
+ if (ptid_get_pid (inf->id) == pid)
+ break;
+ inf = inf->next;
+ }
+
+ current_inferior = (struct thread_info *) inf;
+
+ strcpy (buf, "close");
+
+ run_inferior_command (buf, strlen (buf) + 1);
+
+ current_inferior = save_inferior;
+ }
+}
+
/* Return the minimum instruction size needed for fast tracepoints as a
hexadecimal number. */

@@ -7033,6 +7065,7 @@ gdb_agent_helper_thread (void *arg)
int fd;
char buf[1];
int ret;
+ int stop_loop = 0;

tmp = sizeof (sockaddr);

@@ -7065,8 +7098,12 @@ gdb_agent_helper_thread (void *arg)

if (cmd_buf[0])
{
+ if (strncmp ("close", cmd_buf, 5) == 0)
+ {
+ stop_loop = 1;
+ }
#ifdef HAVE_UST
- if (strcmp ("qTfSTM", cmd_buf) == 0)
+ else if (strcmp ("qTfSTM", cmd_buf) == 0)
{
cmd_qtfstm (cmd_buf);
}
@@ -7098,6 +7135,20 @@ gdb_agent_helper_thread (void *arg)
/* Fix compiler's warning: ignoring return value of 'write'. */
ret = write (fd, buf, 1);
close (fd);
+
+ if (stop_loop)
+ {
+ close (listen_fd);
+ unlink (agent_socket_name);
+
+ /* Sleep endlessly to wait the whole inferior stops. This
+ thread can not exit because GDB or GDBserver may still need
+ 'current_inferior' (representing this thread) to access
+ inferior memory. Otherwise, this thread exits earlier than
+ other threads, and 'current_inferior' is set to NULL. */
+ while (1)
+ sleep (10);
+ }
}
}

--
1.7.9.5