Report additional details for signals received on FreeBSD.

Message ID 20210531162940.10841-1-jhb@FreeBSD.org
State New
Headers show
Series
  • Report additional details for signals received on FreeBSD.
Related show

Commit Message

John Baldwin May 31, 2021, 4:29 p.m.
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(+)

-- 
2.31.1

Comments

John Baldwin May 31, 2021, 4:33 p.m. | #1
On 5/31/21 9:29 AM, John Baldwin wrote:
> 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


Do I need to list all of these new #define's individually in the changelog
or is there a more concise way to list them?

-- 
John Baldwin
Lancelot SIX via Gdb-patches June 1, 2021, 12:49 a.m. | #2
On 2021-05-31 12:33 p.m., John Baldwin wrote:
> On 5/31/21 9:29 AM, John Baldwin wrote:

>> 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

> 

> Do I need to list all of these new #define's individually in the changelog

> or is there a more concise way to list them?


I don't really have an opinion.  But you can probably automate a bit of
it with grep / sed.

In any case the patch LGTM.  It would be nice if you could include an
example output for one of the cases, to get an idea of the user-visible
improvement.

Simon
John Baldwin June 3, 2021, 5:01 p.m. | #3
On 5/31/21 5:49 PM, Simon Marchi wrote:
> On 2021-05-31 12:33 p.m., John Baldwin wrote:

>> On 5/31/21 9:29 AM, John Baldwin wrote:

>>> 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

>>

>> Do I need to list all of these new #define's individually in the changelog

>> or is there a more concise way to list them?

> 

> I don't really have an opinion.  But you can probably automate a bit of

> it with grep / sed.


Ok, I'll just list them all.

> In any case the patch LGTM.  It would be nice if you could include an

> example output for one of the cases, to get an idea of the user-visible

> improvement.


Hmm, would you like it in the commit log?  Here are some sample before/after
comparisons:

SIGUSR1 raised by kill():

before:

Program received signal SIGUSR1, User defined signal 1.
kill () at kill.S:4
4       RSYSCALL(kill)


after:

Program received signal SIGUSR1, User defined signal 1.
Sent by kill() from pid 30529 and user 1001.
kill () at kill.S:4
4       RSYSCALL(kill)

SIGCHLD for exited process:

before:

Program received signal SIGCHLD, Child status changed.

after:

Program received signal SIGCHLD, Child status changed.
Child has exited: pid 31929, uid 1001, exit status 0.

SIGALRM raised by a POSIX timer (timer_create):

before:

Program received signal SIGALRM, Alarm clock.

after:

Program received signal SIGALRM, Alarm clock.
Timer expired: timerid 3.

-- 
John Baldwin
Lancelot SIX via Gdb-patches June 3, 2021, 5:06 p.m. | #4
> Hmm, would you like it in the commit log?  Here are some sample before/after

> comparisons:

> 

> SIGUSR1 raised by kill():

> 

> before:

> 

> Program received signal SIGUSR1, User defined signal 1.

> kill () at kill.S:4

> 4       RSYSCALL(kill)

> 

> 

> after:

> 

> Program received signal SIGUSR1, User defined signal 1.

> Sent by kill() from pid 30529 and user 1001.

> kill () at kill.S:4

> 4       RSYSCALL(kill)

> 

> SIGCHLD for exited process:

> 

> before:

> 

> Program received signal SIGCHLD, Child status changed.

> 

> after:

> 

> Program received signal SIGCHLD, Child status changed.

> Child has exited: pid 31929, uid 1001, exit status 0.

> 

> SIGALRM raised by a POSIX timer (timer_create):

> 

> before:

> 

> Program received signal SIGALRM, Alarm clock.

> 

> after:

> 

> Program received signal SIGALRM, Alarm clock.

> Timer expired: timerid 3.


Thanks, that's nice.  I'd personally put them in the commit message, but
it's as you wish.

Simon

Patch

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' */