[PATCH] Report additional details for signals received on FreeBSD.

John Baldwin jhb@FreeBSD.org
Mon May 31 16:29:40 GMT 2021


Provide a description for si_code values as a sigcode-meaning field.
For signals raised by a system call, provide the pid and user ID of
the sending process.  For signals raised by a POSIX timer exparation,
provide the id of the timer.  For signals raised by a POSIX message
queue, provide the id of the message queue.  For SIGCHLD provide the
pid and user ID of the child process along with the exit status or
relevant signal number.

gdb/ChangeLog:

	* fbsd-tdep.c (fbsd_signal_cause, fbsd_report_signal_info): New.
	(fbsd_init_abi): Use fbsd_report_signal_info as gdbarch
	report_signal_info method.
---
 gdb/ChangeLog   |   6 ++
 gdb/fbsd-tdep.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 278 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b0f448a35e..0f5ec65680 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2021-05-30  John Baldwin  <jhb@FreeBSD.org>
+
+	* fbsd-tdep.c (fbsd_signal_cause, fbsd_report_signal_info): New.
+	(fbsd_init_abi): Use fbsd_report_signal_info as gdbarch
+	report_signal_info method.
+
 2021-05-30  John Baldwin  <jhb@FreeBSD.org>
 
 	* infrun.c (handle_inferior_event): Only call
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index 6cab31dde8..3fe4c5c595 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -75,6 +75,63 @@ enum
     FREEBSD_SIGRTMAX = 126,
   };
 
+/* Constants for values of si_code as defined in FreeBSD's
+   <sys/signal.h>.  */
+
+#define	FBSD_SI_USER		0x10001
+#define	FBSD_SI_QUEUE		0x10002
+#define	FBSD_SI_TIMER		0x10003
+#define	FBSD_SI_ASYNCIO		0x10004
+#define	FBSD_SI_MESGQ		0x10005
+#define	FBSD_SI_KERNEL		0x10006
+#define	FBSD_SI_LWP		0x10007
+
+#define	FBSD_ILL_ILLOPC		1
+#define	FBSD_ILL_ILLOPN		2
+#define	FBSD_ILL_ILLADR		3
+#define	FBSD_ILL_ILLTRP		4
+#define	FBSD_ILL_PRVOPC		5
+#define	FBSD_ILL_PRVREG		6
+#define	FBSD_ILL_COPROC		7
+#define	FBSD_ILL_BADSTK		8
+
+#define	FBSD_BUS_ADRALN		1
+#define	FBSD_BUS_ADRERR		2
+#define	FBSD_BUS_OBJERR		3
+#define	FBSD_BUS_OOMERR		100
+
+#define	FBSD_SEGV_MAPERR	1
+#define	FBSD_SEGV_ACCERR	2
+#define	FBSD_SEGV_PKUERR	100
+
+#define	FBSD_FPE_INTOVF		1
+#define	FBSD_FPE_INTDIV		2
+#define	FBSD_FPE_FLTDIV		3
+#define	FBSD_FPE_FLTOVF		4
+#define	FBSD_FPE_FLTUND		5
+#define	FBSD_FPE_FLTRES		6
+#define	FBSD_FPE_FLTINV		7
+#define	FBSD_FPE_FLTSUB		8
+
+#define	FBSD_TRAP_BRKPT		1
+#define	FBSD_TRAP_TRACE		2
+#define	FBSD_TRAP_DTRACE	3
+#define	FBSD_TRAP_CAP		4
+
+#define	FBSD_CLD_EXITED		1
+#define	FBSD_CLD_KILLED		2
+#define	FBSD_CLD_DUMPED		3
+#define	FBSD_CLD_TRAPPED	4
+#define	FBSD_CLD_STOPPED	5
+#define	FBSD_CLD_CONTINUED	6
+
+#define	FBSD_POLL_IN		1
+#define	FBSD_POLL_OUT		2
+#define	FBSD_POLL_MSG		3
+#define	FBSD_POLL_ERR		4
+#define	FBSD_POLL_PRI		5
+#define	FBSD_POLL_HUP		6
+
 /* FreeBSD kernels 12.0 and later include a copy of the
    'ptrace_lwpinfo' structure returned by the PT_LWPINFO ptrace
    operation in an ELF core note (NT_FREEBSD_PTLWPINFO) for each LWP.
@@ -1988,6 +2045,220 @@ fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
   return 0;
 }
 
+/* Return description of signal code or nullptr.  */
+
+static const char *
+fbsd_signal_cause (enum gdb_signal siggnal, int code)
+{
+  /* Signal-independent causes.  */
+  switch (code)
+    {
+    case FBSD_SI_USER:
+      return _("sent by kill()");
+    case FBSD_SI_QUEUE:
+      return _("sent by sigqueue()");
+    case FBSD_SI_TIMER:
+      return _("timer expired");
+    case FBSD_SI_ASYNCIO:
+      return _("Asynchronous I/O request completed");
+    case FBSD_SI_MESGQ:
+      return _("Message arrived on empty message queue");
+    case FBSD_SI_KERNEL:
+      return _("sent by kernel");
+    case FBSD_SI_LWP:
+      return _("sent by thr_kill()");
+    }
+
+  switch (siggnal)
+    {
+    case GDB_SIGNAL_ILL:
+      switch (code)
+	{
+	case FBSD_ILL_ILLOPC:
+	  return _("Illegal opcode");
+	case FBSD_ILL_ILLOPN:
+	  return _("Illegal operand");
+	case FBSD_ILL_ILLADR:
+	  return _("Illegal addressing mode");
+	case FBSD_ILL_ILLTRP:
+	  return _("Illegal trap");
+	case FBSD_ILL_PRVOPC:
+	  return _("Privileged opcode");
+	case FBSD_ILL_PRVREG:
+	  return _("Privileged register");
+	case FBSD_ILL_COPROC:
+	  return _("Coprocessor error");
+	case FBSD_ILL_BADSTK:
+	  return _("Internal stack error");
+	}
+      break;
+    case GDB_SIGNAL_BUS:
+      switch (code)
+	{
+	case FBSD_BUS_ADRALN:
+	  return _("Invalid address alignment");
+	case FBSD_BUS_ADRERR:
+	  return _("Address not present");
+	case FBSD_BUS_OBJERR:
+	  return _("Object-specific hardware error");
+	case FBSD_BUS_OOMERR:
+	  return _("Out of memory");
+	}
+      break;
+    case GDB_SIGNAL_SEGV:
+      switch (code)
+	{
+	case FBSD_SEGV_MAPERR:
+	  return _("Address not mapped to object");
+	case FBSD_SEGV_ACCERR:
+	  return _("Invalid permissions for mapped object");
+	case FBSD_SEGV_PKUERR:
+	  return _("PKU violation");
+	}
+      break;
+    case GDB_SIGNAL_FPE:
+      switch (code)
+	{
+	case FBSD_FPE_INTOVF:
+	  return _("Integer overflow");
+	case FBSD_FPE_INTDIV:
+	  return _("Integer divide by zero");
+	case FBSD_FPE_FLTDIV:
+	  return _("Floating point divide by zero");
+	case FBSD_FPE_FLTOVF:
+	  return _("Floating point overflow");
+	case FBSD_FPE_FLTUND:
+	  return _("Floating point underflow");
+	case FBSD_FPE_FLTRES:
+	  return _("Floating point inexact result");
+	case FBSD_FPE_FLTINV:
+	  return _("Invalid floating point operation");
+	case FBSD_FPE_FLTSUB:
+	  return _("Subscript out of range");
+	}
+      break;
+    case GDB_SIGNAL_TRAP:
+      switch (code)
+	{
+	case FBSD_TRAP_BRKPT:
+	  return _("Breakpoint");
+	case FBSD_TRAP_TRACE:
+	  return _("Trace trap");
+	case FBSD_TRAP_DTRACE:
+	  return _("DTrace-induced trap");
+	case FBSD_TRAP_CAP:
+	  return _("Capability violation");
+	}
+      break;
+    case GDB_SIGNAL_CHLD:
+      switch (code)
+	{
+	case FBSD_CLD_EXITED:
+	  return _("Child has exited");
+	case FBSD_CLD_KILLED:
+	  return _("Child has terminated abnormally");
+	case FBSD_CLD_DUMPED:
+	  return _("Child has dumped core");
+	case FBSD_CLD_TRAPPED:
+	  return _("Traced child has trapped");
+	case FBSD_CLD_STOPPED:
+	  return _("Child has stopped");
+	case FBSD_CLD_CONTINUED:
+	  return _("Stopped child has continued");
+	}
+      break;
+    case GDB_SIGNAL_POLL:
+      switch (code)
+	{
+	case FBSD_POLL_IN:
+	  return _("Data input available");
+	case FBSD_POLL_OUT:
+	  return _("Output buffers available");
+	case FBSD_POLL_MSG:
+	  return _("Input message available");
+	case FBSD_POLL_ERR:
+	  return _("I/O error");
+	case FBSD_POLL_PRI:
+	  return _("High priority input available");
+	case FBSD_POLL_HUP:
+	  return _("Device disconnected");
+	}
+      break;
+    }
+
+  return nullptr;
+}
+
+/* Report additional details for a signal stop.  */
+
+static void
+fbsd_report_signal_info (struct gdbarch *gdbarch, struct ui_out *uiout,
+			 enum gdb_signal siggnal)
+{
+  LONGEST code, mqd, pid, status, timerid, uid;
+
+  try
+    {
+      code = parse_and_eval_long ("$_siginfo.si_code");
+      pid = parse_and_eval_long ("$_siginfo.si_pid");
+      uid = parse_and_eval_long ("$_siginfo.si_uid");
+      status = parse_and_eval_long ("$_siginfo.si_status");
+      timerid = parse_and_eval_long ("$_siginfo._reason._timer.si_timerid");
+      mqd = parse_and_eval_long ("$_siginfo._reason._mesgq.si_mqd");
+    }
+  catch (const gdb_exception_error &e)
+    {
+      return;
+    }
+
+  const char *meaning = fbsd_signal_cause (siggnal, code);
+  if (meaning == nullptr)
+    return;
+
+  uiout->text ("\n");
+  uiout->field_string ("sigcode-meaning", meaning);
+
+  switch (code)
+    {
+    case FBSD_SI_USER:
+    case FBSD_SI_QUEUE:
+    case FBSD_SI_LWP:
+      uiout->text (" from pid ");
+      uiout->field_string ("sending-pid", plongest (pid));
+      uiout->text (" and user ");
+      uiout->field_string ("sending-uid", plongest (uid));
+      return;
+    case FBSD_SI_TIMER:
+      uiout->text (" timerid ");
+      uiout->field_string ("timerid", plongest (timerid));
+      return;
+    case FBSD_SI_MESGQ:
+      uiout->text (" message queue ");
+      uiout->field_string ("message-queue", plongest (mqd));
+      return;
+    case FBSD_SI_ASYNCIO:
+      return;
+    }
+
+  if (siggnal == GDB_SIGNAL_CHLD)
+    {
+      uiout->text (", pid ");
+      uiout->field_string ("child-pid", plongest (pid));
+      uiout->text (", uid ");
+      uiout->field_string ("child-uid", plongest (uid));
+      if (code == FBSD_CLD_EXITED)
+	{
+	  uiout->text (", exit status ");
+	  uiout->field_string ("exit-status", plongest (status));
+	}
+      else
+	{
+	  uiout->text (", signal ");
+	  uiout->field_string ("signal", plongest (status));
+	}
+    }
+}
+
 /* To be called from GDB_OSABI_FREEBSD handlers. */
 
 void
@@ -2002,6 +2273,7 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type);
   set_gdbarch_gdb_signal_from_target (gdbarch, fbsd_gdb_signal_from_target);
   set_gdbarch_gdb_signal_to_target (gdbarch, fbsd_gdb_signal_to_target);
+  set_gdbarch_report_signal_info (gdbarch, fbsd_report_signal_info);
   set_gdbarch_skip_solib_resolver (gdbarch, fbsd_skip_solib_resolver);
 
   /* `catch syscall' */
-- 
2.31.1



More information about the Gdb-patches mailing list