This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch 1/9]#2 Rename `enum target_signal' to target_signal_t


On Thu, 02 Sep 2010 21:33:11 +0200, Jan Kratochvil wrote:
> On Thu, 02 Sep 2010 19:27:52 +0200, Pedro Alves wrote:
> > I don't think it is a good idea to associate the siginfo with a signal
> > and think of it as a single entity.  For many cases, you don't need the
> > siginfo.  Carrying it around would be extra burden, especially for the remote
> > target.
> 
> For the remote part I was thinking about making it lazy, requesting it only
> when retrieved for a different kind of processing than a target resume.

While trying to implement it I found it cannot be done (without C++).

If target_signal_t as returned by remote_wait (=to_wait implementation) is
lazy it can either be passed to remote_resume (=to_resume implementation) or
saved by infrun.c save_inferior_thread_state.  But remote.c can no longer
track where that target_signal_t has been copied without C++.

On Mon, 30 Aug 2010 09:09:55 +0200, Jan Kratochvil wrote:
# I tried to make target_signal a pointer with reference counter.  I have the
# unfinished patch here but I really do not find it viable.  All the assignments
# and passing by value to functions make it difficult to catch all the cases.
# With C++ GDB this patchset could be greatly simplified with fixed performance.
+
Even if the implementation would get finished I find target_signal_t a too
basic type to require explicit reference counting while having no compiler
checks of it.  It could become a large problem similar to all the effort to
manage the GObject reference counting in Gnome/C.

remote.c PASSes with FSF gdbserver even for gdb.base/siginfo-infcall.exp but
without C++ it has to have the back-and-forth siginfo_t transfer overhead.
[attached as a preview]

Therefore going to implement explicit carrying of associated siginfo_t
together with siginfo-less target_signal_t in the middle-end (infrun.c&co.).


Regards,
Jan


--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -176,6 +176,18 @@ static void print_packet (char *);
 
 static void compare_sections_command (char *, int);
 
+struct packet_config;
+
+static LONGEST remote_read_qxfer (struct target_ops *ops,
+				  const char *object_name, const char *annex,
+				  gdb_byte *readbuf, ULONGEST offset,
+				  LONGEST len, struct packet_config *packet);
+
+static LONGEST remote_write_qxfer (struct target_ops *ops,
+				   const char *object_name, const char *annex,
+				   const gdb_byte *writebuf, ULONGEST offset,
+				   LONGEST len, struct packet_config *packet);
+
 static void packet_command (char *, int);
 
 static int stub_unpack_int (char *buff, int fieldlength);
@@ -196,8 +208,6 @@ static int putpkt_binary (char *buf, int cnt);
 
 static void check_binary_download (CORE_ADDR addr);
 
-struct packet_config;
-
 static void show_packet_config_cmd (struct packet_config *config);
 
 static void update_packet_config (struct packet_config *config);
@@ -4446,6 +4456,32 @@ remote_vcont_resume (ptid_t ptid, int step, target_signal_t siggnal)
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_DISABLE)
     return 0;
 
+  if (target_signal_siginfo_p (&siggnal))
+    {
+      ptid_t siggnal_ptid;
+      struct gdbarch *siggnal_ptid_gdbarch;
+      size_t len;
+      gdb_byte *siginfop;
+      LONGEST got;
+
+      if (ptid_equal (ptid, magic_null_ptid)
+          || ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
+	siggnal_ptid = inferior_ptid;
+      else
+	siggnal_ptid = ptid;
+
+      set_general_thread (siggnal_ptid);
+
+      siggnal_ptid_gdbarch = target_thread_architecture (siggnal_ptid);
+      len = target_signal_siginfo_len (siggnal_ptid_gdbarch);
+      siginfop = target_signal_siginfo_get (&siggnal, siggnal_ptid_gdbarch);
+
+      got = remote_write_qxfer (NULL /* unused */, "siginfo", NULL, siginfop,
+				0, len, &remote_protocol_packets
+					 [PACKET_qXfer_siginfo_read]);
+      /* FIXME: Real len.  */
+    }
+
   p = rs->buf;
   endp = rs->buf + get_remote_packet_size ();
 
@@ -4554,6 +4590,34 @@ remote_resume (struct target_ops *ops,
     {
       int siggnal_number = TARGET_SIGNAL_NUMBER (siggnal);
 
+      if (target_signal_siginfo_p (&siggnal))
+	{
+	  ptid_t siggnal_ptid;
+	  struct gdbarch *siggnal_ptid_gdbarch;
+	  size_t len;
+	  gdb_byte *siginfop;
+	  LONGEST got;
+
+	  if (ptid_equal (ptid, magic_null_ptid)
+	      || ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
+	    siggnal_ptid = inferior_ptid;
+	  else
+	    siggnal_ptid = ptid;
+
+	  set_general_thread (siggnal_ptid);
+
+	  siggnal_ptid_gdbarch = target_thread_architecture (siggnal_ptid);
+	  len = target_signal_siginfo_len (siggnal_ptid_gdbarch);
+	  siginfop = target_signal_siginfo_get (&siggnal,
+						siggnal_ptid_gdbarch);
+
+	  got = remote_write_qxfer (NULL /* unused */, "siginfo", NULL,
+				    siginfop, 0, len,
+				    &remote_protocol_packets
+				     [PACKET_qXfer_siginfo_read]);
+	  /* FIXME: Real len.  */
+	}
+
       buf[0] = step ? 'S' : 'C';
       buf[1] = tohex ((siggnal_number >> 4) & 0xf);
       buf[2] = tohex (siggnal_number & 0xf);
@@ -5575,6 +5639,37 @@ remote_wait (struct target_ops *ops,
   else
     event_ptid = remote_wait_as (ptid, status, options);
 
+  if (TARGET_WAITKIND_USES_SIG (status->kind))
+    {
+      ptid_t siggnal_ptid;
+      struct gdbarch *siggnal_ptid_gdbarch;
+      size_t len;
+      gdb_byte siginfo[MAX_SIGINFO_SIZE];
+      LONGEST got;
+
+      if (ptid_equal (event_ptid, magic_null_ptid)
+	  || ptid_equal (event_ptid, minus_one_ptid)
+	  || ptid_is_pid (event_ptid))
+	siggnal_ptid = inferior_ptid;
+      else
+	siggnal_ptid = event_ptid;
+
+      siggnal_ptid_gdbarch = target_thread_architecture (siggnal_ptid);
+      len = target_signal_siginfo_len (siggnal_ptid_gdbarch);
+
+      got = remote_read_qxfer (ops, "siginfo", NULL, siginfo, 0, len,
+			       &remote_protocol_packets
+				[PACKET_qXfer_siginfo_read]);
+      if (got >= 0)
+	{
+	  set_general_thread (siggnal_ptid);
+
+	  memset (&siginfo[got], 0, len - got);
+	  target_signal_siginfo_set (&status->value.sig, siggnal_ptid_gdbarch,
+				     siginfo);
+	}
+    }
+
   if (target_can_async_p ())
     {
       /* If there are are events left in the queue tell the event loop


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]