148596154Schristos /* Everything about signal catchpoints, for GDB.
248596154Schristos 
3*1424dfb3Schristos    Copyright (C) 2011-2020 Free Software Foundation, Inc.
448596154Schristos 
548596154Schristos    This file is part of GDB.
648596154Schristos 
748596154Schristos    This program is free software; you can redistribute it and/or modify
848596154Schristos    it under the terms of the GNU General Public License as published by
948596154Schristos    the Free Software Foundation; either version 3 of the License, or
1048596154Schristos    (at your option) any later version.
1148596154Schristos 
1248596154Schristos    This program is distributed in the hope that it will be useful,
1348596154Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1448596154Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1548596154Schristos    GNU General Public License for more details.
1648596154Schristos 
1748596154Schristos    You should have received a copy of the GNU General Public License
1848596154Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
1948596154Schristos 
2048596154Schristos #include "defs.h"
2148596154Schristos #include "arch-utils.h"
2248596154Schristos #include <ctype.h>
2348596154Schristos #include "breakpoint.h"
2448596154Schristos #include "gdbcmd.h"
2548596154Schristos #include "inferior.h"
2626a53354Schristos #include "infrun.h"
2748596154Schristos #include "annotate.h"
2848596154Schristos #include "valprint.h"
2948596154Schristos #include "cli/cli-utils.h"
3048596154Schristos #include "completer.h"
31*1424dfb3Schristos #include "cli/cli-style.h"
321c468f90Schristos 
331c468f90Schristos #include <string>
3448596154Schristos 
3548596154Schristos #define INTERNAL_SIGNAL(x) ((x) == GDB_SIGNAL_TRAP || (x) == GDB_SIGNAL_INT)
3648596154Schristos 
3748596154Schristos /* An instance of this type is used to represent a signal catchpoint.
3807163879Schristos    A breakpoint is really of this type iff its ops pointer points to
3948596154Schristos    SIGNAL_CATCHPOINT_OPS.  */
4048596154Schristos 
4107163879Schristos struct signal_catchpoint : public breakpoint
4248596154Schristos {
4348596154Schristos   /* Signal numbers used for the 'catch signal' feature.  If no signal
4407163879Schristos      has been specified for filtering, it is empty.  Otherwise,
4548596154Schristos      it holds a list of all signals to be caught.  */
4648596154Schristos 
4707163879Schristos   std::vector<gdb_signal> signals_to_be_caught;
4848596154Schristos 
4907163879Schristos   /* If SIGNALS_TO_BE_CAUGHT is empty, then all "ordinary" signals are
5007163879Schristos      caught.  If CATCH_ALL is true, then internal signals are caught
5107163879Schristos      as well.  If SIGNALS_TO_BE_CAUGHT is not empty, then this field
5207163879Schristos      is ignored.  */
5348596154Schristos 
5407163879Schristos   bool catch_all;
5548596154Schristos };
5648596154Schristos 
5748596154Schristos /* The breakpoint_ops structure to be used in signal catchpoints.  */
5848596154Schristos 
5948596154Schristos static struct breakpoint_ops signal_catchpoint_ops;
6048596154Schristos 
6148596154Schristos /* Count of each signal.  */
6248596154Schristos 
6348596154Schristos static unsigned int *signal_catch_counts;
6448596154Schristos 
6548596154Schristos 
6648596154Schristos 
6748596154Schristos /* A convenience wrapper for gdb_signal_to_name that returns the
6848596154Schristos    integer value if the name is not known.  */
6948596154Schristos 
7048596154Schristos static const char *
signal_to_name_or_int(enum gdb_signal sig)7148596154Schristos signal_to_name_or_int (enum gdb_signal sig)
7248596154Schristos {
7348596154Schristos   const char *result = gdb_signal_to_name (sig);
7448596154Schristos 
7548596154Schristos   if (strcmp (result, "?") == 0)
7648596154Schristos     result = plongest (sig);
7748596154Schristos 
7848596154Schristos   return result;
7948596154Schristos }
8048596154Schristos 
8148596154Schristos 
8248596154Schristos 
8348596154Schristos /* Implement the "insert_location" breakpoint_ops method for signal
8448596154Schristos    catchpoints.  */
8548596154Schristos 
8648596154Schristos static int
signal_catchpoint_insert_location(struct bp_location * bl)8748596154Schristos signal_catchpoint_insert_location (struct bp_location *bl)
8848596154Schristos {
89c03b94e9Schristos   struct signal_catchpoint *c = (struct signal_catchpoint *) bl->owner;
9048596154Schristos 
9107163879Schristos   if (!c->signals_to_be_caught.empty ())
9248596154Schristos     {
9307163879Schristos       for (gdb_signal iter : c->signals_to_be_caught)
9448596154Schristos 	++signal_catch_counts[iter];
9548596154Schristos     }
9648596154Schristos   else
9748596154Schristos     {
9807163879Schristos       for (int i = 0; i < GDB_SIGNAL_LAST; ++i)
9948596154Schristos 	{
10048596154Schristos 	  if (c->catch_all || !INTERNAL_SIGNAL (i))
10148596154Schristos 	    ++signal_catch_counts[i];
10248596154Schristos 	}
10348596154Schristos     }
10448596154Schristos 
10548596154Schristos   signal_catch_update (signal_catch_counts);
10648596154Schristos 
10748596154Schristos   return 0;
10848596154Schristos }
10948596154Schristos 
11048596154Schristos /* Implement the "remove_location" breakpoint_ops method for signal
11148596154Schristos    catchpoints.  */
11248596154Schristos 
11348596154Schristos static int
signal_catchpoint_remove_location(struct bp_location * bl,enum remove_bp_reason reason)114c03b94e9Schristos signal_catchpoint_remove_location (struct bp_location *bl,
115c03b94e9Schristos 				   enum remove_bp_reason reason)
11648596154Schristos {
117c03b94e9Schristos   struct signal_catchpoint *c = (struct signal_catchpoint *) bl->owner;
11848596154Schristos 
11907163879Schristos   if (!c->signals_to_be_caught.empty ())
12048596154Schristos     {
12107163879Schristos       for (gdb_signal iter : c->signals_to_be_caught)
12248596154Schristos 	{
12348596154Schristos 	  gdb_assert (signal_catch_counts[iter] > 0);
12448596154Schristos 	  --signal_catch_counts[iter];
12548596154Schristos 	}
12648596154Schristos     }
12748596154Schristos   else
12848596154Schristos     {
12907163879Schristos       for (int i = 0; i < GDB_SIGNAL_LAST; ++i)
13048596154Schristos 	{
13148596154Schristos 	  if (c->catch_all || !INTERNAL_SIGNAL (i))
13248596154Schristos 	    {
13348596154Schristos 	      gdb_assert (signal_catch_counts[i] > 0);
13448596154Schristos 	      --signal_catch_counts[i];
13548596154Schristos 	    }
13648596154Schristos 	}
13748596154Schristos     }
13848596154Schristos 
13948596154Schristos   signal_catch_update (signal_catch_counts);
14048596154Schristos 
14148596154Schristos   return 0;
14248596154Schristos }
14348596154Schristos 
14448596154Schristos /* Implement the "breakpoint_hit" breakpoint_ops method for signal
14548596154Schristos    catchpoints.  */
14648596154Schristos 
14748596154Schristos static int
signal_catchpoint_breakpoint_hit(const struct bp_location * bl,const address_space * aspace,CORE_ADDR bp_addr,const struct target_waitstatus * ws)14848596154Schristos signal_catchpoint_breakpoint_hit (const struct bp_location *bl,
14907163879Schristos 				  const address_space *aspace,
15048596154Schristos 				  CORE_ADDR bp_addr,
15148596154Schristos 				  const struct target_waitstatus *ws)
15248596154Schristos {
153c03b94e9Schristos   const struct signal_catchpoint *c
154c03b94e9Schristos     = (const struct signal_catchpoint *) bl->owner;
15507163879Schristos   gdb_signal signal_number;
15648596154Schristos 
15748596154Schristos   if (ws->kind != TARGET_WAITKIND_STOPPED)
15848596154Schristos     return 0;
15948596154Schristos 
16048596154Schristos   signal_number = ws->value.sig;
16148596154Schristos 
16248596154Schristos   /* If we are catching specific signals in this breakpoint, then we
16348596154Schristos      must guarantee that the called signal is the same signal we are
16448596154Schristos      catching.  */
16507163879Schristos   if (!c->signals_to_be_caught.empty ())
16648596154Schristos     {
16707163879Schristos       for (gdb_signal iter : c->signals_to_be_caught)
16848596154Schristos 	if (signal_number == iter)
1697af5a897Schristos 	  return 1;
17048596154Schristos       /* Not the same.  */
17148596154Schristos       return 0;
17248596154Schristos     }
1737af5a897Schristos   else
17448596154Schristos     return c->catch_all || !INTERNAL_SIGNAL (signal_number);
17548596154Schristos }
17648596154Schristos 
17748596154Schristos /* Implement the "print_it" breakpoint_ops method for signal
17848596154Schristos    catchpoints.  */
17948596154Schristos 
18048596154Schristos static enum print_stop_action
signal_catchpoint_print_it(bpstat bs)18148596154Schristos signal_catchpoint_print_it (bpstat bs)
18248596154Schristos {
18348596154Schristos   struct breakpoint *b = bs->breakpoint_at;
18448596154Schristos   struct target_waitstatus last;
18548596154Schristos   const char *signal_name;
186c03b94e9Schristos   struct ui_out *uiout = current_uiout;
18748596154Schristos 
188*1424dfb3Schristos   get_last_target_status (nullptr, nullptr, &last);
18948596154Schristos 
19048596154Schristos   signal_name = signal_to_name_or_int (last.value.sig);
19148596154Schristos 
19248596154Schristos   annotate_catchpoint (b->number);
193c03b94e9Schristos   maybe_print_thread_hit_breakpoint (uiout);
19448596154Schristos 
195c03b94e9Schristos   printf_filtered (_("Catchpoint %d (signal %s), "), b->number, signal_name);
19648596154Schristos 
19748596154Schristos   return PRINT_SRC_AND_LOC;
19848596154Schristos }
19948596154Schristos 
20048596154Schristos /* Implement the "print_one" breakpoint_ops method for signal
20148596154Schristos    catchpoints.  */
20248596154Schristos 
20348596154Schristos static void
signal_catchpoint_print_one(struct breakpoint * b,struct bp_location ** last_loc)20448596154Schristos signal_catchpoint_print_one (struct breakpoint *b,
20548596154Schristos 			     struct bp_location **last_loc)
20648596154Schristos {
207c03b94e9Schristos   struct signal_catchpoint *c = (struct signal_catchpoint *) b;
20848596154Schristos   struct value_print_options opts;
20948596154Schristos   struct ui_out *uiout = current_uiout;
21048596154Schristos 
21148596154Schristos   get_user_print_options (&opts);
21248596154Schristos 
21348596154Schristos   /* Field 4, the address, is omitted (which makes the columns
21448596154Schristos      not line up too nicely with the headers, but the effect
21548596154Schristos      is relatively readable).  */
21648596154Schristos   if (opts.addressprint)
2171c468f90Schristos     uiout->field_skip ("addr");
21848596154Schristos   annotate_field (5);
21948596154Schristos 
22007163879Schristos   if (c->signals_to_be_caught.size () > 1)
2211c468f90Schristos     uiout->text ("signals \"");
22248596154Schristos   else
2231c468f90Schristos     uiout->text ("signal \"");
22448596154Schristos 
22507163879Schristos   if (!c->signals_to_be_caught.empty ())
22648596154Schristos     {
2271c468f90Schristos       std::string text;
22848596154Schristos 
22907163879Schristos       bool first = true;
23007163879Schristos       for (gdb_signal iter : c->signals_to_be_caught)
23148596154Schristos         {
23248596154Schristos 	  const char *name = signal_to_name_or_int (iter);
23348596154Schristos 
23407163879Schristos 	  if (!first)
2351c468f90Schristos 	    text += " ";
23607163879Schristos 	  first = false;
23707163879Schristos 
2381c468f90Schristos 	  text += name;
23948596154Schristos         }
2401c468f90Schristos       uiout->field_string ("what", text.c_str ());
24148596154Schristos     }
24248596154Schristos   else
2431c468f90Schristos     uiout->field_string ("what",
244*1424dfb3Schristos 			 c->catch_all ? "<any signal>" : "<standard signals>",
245*1424dfb3Schristos 			 metadata_style.style ());
2461c468f90Schristos   uiout->text ("\" ");
24748596154Schristos 
2481c468f90Schristos   if (uiout->is_mi_like_p ())
2491c468f90Schristos     uiout->field_string ("catch-type", "signal");
25048596154Schristos }
25148596154Schristos 
25248596154Schristos /* Implement the "print_mention" breakpoint_ops method for signal
25348596154Schristos    catchpoints.  */
25448596154Schristos 
25548596154Schristos static void
signal_catchpoint_print_mention(struct breakpoint * b)25648596154Schristos signal_catchpoint_print_mention (struct breakpoint *b)
25748596154Schristos {
258c03b94e9Schristos   struct signal_catchpoint *c = (struct signal_catchpoint *) b;
25948596154Schristos 
26007163879Schristos   if (!c->signals_to_be_caught.empty ())
26148596154Schristos     {
26207163879Schristos       if (c->signals_to_be_caught.size () > 1)
26348596154Schristos         printf_filtered (_("Catchpoint %d (signals"), b->number);
26448596154Schristos       else
26548596154Schristos         printf_filtered (_("Catchpoint %d (signal"), b->number);
26648596154Schristos 
26707163879Schristos       for (gdb_signal iter : c->signals_to_be_caught)
26848596154Schristos         {
26948596154Schristos 	  const char *name = signal_to_name_or_int (iter);
27048596154Schristos 
27148596154Schristos 	  printf_filtered (" %s", name);
27248596154Schristos         }
27348596154Schristos       printf_filtered (")");
27448596154Schristos     }
27548596154Schristos   else if (c->catch_all)
27648596154Schristos     printf_filtered (_("Catchpoint %d (any signal)"), b->number);
27748596154Schristos   else
27848596154Schristos     printf_filtered (_("Catchpoint %d (standard signals)"), b->number);
27948596154Schristos }
28048596154Schristos 
28148596154Schristos /* Implement the "print_recreate" breakpoint_ops method for signal
28248596154Schristos    catchpoints.  */
28348596154Schristos 
28448596154Schristos static void
signal_catchpoint_print_recreate(struct breakpoint * b,struct ui_file * fp)28548596154Schristos signal_catchpoint_print_recreate (struct breakpoint *b, struct ui_file *fp)
28648596154Schristos {
287c03b94e9Schristos   struct signal_catchpoint *c = (struct signal_catchpoint *) b;
28848596154Schristos 
28948596154Schristos   fprintf_unfiltered (fp, "catch signal");
29048596154Schristos 
29107163879Schristos   if (!c->signals_to_be_caught.empty ())
29248596154Schristos     {
29307163879Schristos       for (gdb_signal iter : c->signals_to_be_caught)
29448596154Schristos 	fprintf_unfiltered (fp, " %s", signal_to_name_or_int (iter));
29548596154Schristos     }
29648596154Schristos   else if (c->catch_all)
29748596154Schristos     fprintf_unfiltered (fp, " all");
29826a53354Schristos   fputc_unfiltered ('\n', fp);
29948596154Schristos }
30048596154Schristos 
30148596154Schristos /* Implement the "explains_signal" breakpoint_ops method for signal
30248596154Schristos    catchpoints.  */
30348596154Schristos 
3047af5a897Schristos static int
signal_catchpoint_explains_signal(struct breakpoint * b,enum gdb_signal sig)30548596154Schristos signal_catchpoint_explains_signal (struct breakpoint *b, enum gdb_signal sig)
30648596154Schristos {
3077af5a897Schristos   return 1;
30848596154Schristos }
30948596154Schristos 
31048596154Schristos /* Create a new signal catchpoint.  TEMPFLAG is true if this should be
31148596154Schristos    a temporary catchpoint.  FILTER is the list of signals to catch; it
31207163879Schristos    can be empty, meaning all signals.  CATCH_ALL is a flag indicating
31348596154Schristos    whether signals used internally by gdb should be caught; it is only
31407163879Schristos    valid if FILTER is NULL.  If FILTER is empty and CATCH_ALL is zero,
31548596154Schristos    then internal signals like SIGTRAP are not caught.  */
31648596154Schristos 
31748596154Schristos static void
create_signal_catchpoint(int tempflag,std::vector<gdb_signal> && filter,bool catch_all)31807163879Schristos create_signal_catchpoint (int tempflag, std::vector<gdb_signal> &&filter,
31907163879Schristos 			  bool catch_all)
32048596154Schristos {
32148596154Schristos   struct gdbarch *gdbarch = get_current_arch ();
32248596154Schristos 
32307163879Schristos   std::unique_ptr<signal_catchpoint> c (new signal_catchpoint ());
32407163879Schristos   init_catchpoint (c.get (), gdbarch, tempflag, NULL, &signal_catchpoint_ops);
32507163879Schristos   c->signals_to_be_caught = std::move (filter);
32648596154Schristos   c->catch_all = catch_all;
32748596154Schristos 
32807163879Schristos   install_breakpoint (0, std::move (c), 1);
32948596154Schristos }
33048596154Schristos 
33148596154Schristos 
33207163879Schristos /* Splits the argument using space as delimiter.  Returns a filter
33307163879Schristos    list, which is empty if no filtering is required.  */
33448596154Schristos 
33507163879Schristos static std::vector<gdb_signal>
catch_signal_split_args(const char * arg,bool * catch_all)33607163879Schristos catch_signal_split_args (const char *arg, bool *catch_all)
33748596154Schristos {
33807163879Schristos   std::vector<gdb_signal> result;
33907163879Schristos   bool first = true;
34048596154Schristos 
34148596154Schristos   while (*arg != '\0')
34248596154Schristos     {
34348596154Schristos       int num;
34407163879Schristos       gdb_signal signal_number;
34507163879Schristos       char *endptr;
34648596154Schristos 
34707163879Schristos       std::string one_arg = extract_arg (&arg);
34807163879Schristos       if (one_arg.empty ())
34948596154Schristos 	break;
35048596154Schristos 
35148596154Schristos       /* Check for the special flag "all".  */
35207163879Schristos       if (one_arg == "all")
35348596154Schristos 	{
35448596154Schristos 	  arg = skip_spaces (arg);
35548596154Schristos 	  if (*arg != '\0' || !first)
35648596154Schristos 	    error (_("'all' cannot be caught with other signals"));
35707163879Schristos 	  *catch_all = true;
35807163879Schristos 	  gdb_assert (result.empty ());
35907163879Schristos 	  return result;
36048596154Schristos 	}
36148596154Schristos 
36207163879Schristos       first = false;
36348596154Schristos 
36448596154Schristos       /* Check if the user provided a signal name or a number.  */
36507163879Schristos       num = (int) strtol (one_arg.c_str (), &endptr, 0);
36648596154Schristos       if (*endptr == '\0')
36748596154Schristos 	signal_number = gdb_signal_from_command (num);
36848596154Schristos       else
36948596154Schristos 	{
37007163879Schristos 	  signal_number = gdb_signal_from_name (one_arg.c_str ());
37148596154Schristos 	  if (signal_number == GDB_SIGNAL_UNKNOWN)
37207163879Schristos 	    error (_("Unknown signal name '%s'."), one_arg.c_str ());
37348596154Schristos 	}
37448596154Schristos 
37507163879Schristos       result.push_back (signal_number);
37648596154Schristos     }
37748596154Schristos 
37807163879Schristos   result.shrink_to_fit ();
37948596154Schristos   return result;
38048596154Schristos }
38148596154Schristos 
38248596154Schristos /* Implement the "catch signal" command.  */
38348596154Schristos 
38448596154Schristos static void
catch_signal_command(const char * arg,int from_tty,struct cmd_list_element * command)38507163879Schristos catch_signal_command (const char *arg, int from_tty,
38648596154Schristos 		      struct cmd_list_element *command)
38748596154Schristos {
38807163879Schristos   int tempflag;
38907163879Schristos   bool catch_all = false;
39007163879Schristos   std::vector<gdb_signal> filter;
39148596154Schristos 
39248596154Schristos   tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
39348596154Schristos 
39448596154Schristos   arg = skip_spaces (arg);
39548596154Schristos 
39648596154Schristos   /* The allowed syntax is:
39748596154Schristos      catch signal
39848596154Schristos      catch signal <name | number> [<name | number> ... <name | number>]
39948596154Schristos 
40048596154Schristos      Let's check if there's a signal name.  */
40148596154Schristos 
40248596154Schristos   if (arg != NULL)
40348596154Schristos     filter = catch_signal_split_args (arg, &catch_all);
40448596154Schristos 
40507163879Schristos   create_signal_catchpoint (tempflag, std::move (filter), catch_all);
40648596154Schristos }
40748596154Schristos 
40848596154Schristos static void
initialize_signal_catchpoint_ops(void)40948596154Schristos initialize_signal_catchpoint_ops (void)
41048596154Schristos {
41148596154Schristos   struct breakpoint_ops *ops;
41248596154Schristos 
41348596154Schristos   initialize_breakpoint_ops ();
41448596154Schristos 
41548596154Schristos   ops = &signal_catchpoint_ops;
41648596154Schristos   *ops = base_breakpoint_ops;
41748596154Schristos   ops->insert_location = signal_catchpoint_insert_location;
41848596154Schristos   ops->remove_location = signal_catchpoint_remove_location;
41948596154Schristos   ops->breakpoint_hit = signal_catchpoint_breakpoint_hit;
42048596154Schristos   ops->print_it = signal_catchpoint_print_it;
42148596154Schristos   ops->print_one = signal_catchpoint_print_one;
42248596154Schristos   ops->print_mention = signal_catchpoint_print_mention;
42348596154Schristos   ops->print_recreate = signal_catchpoint_print_recreate;
42448596154Schristos   ops->explains_signal = signal_catchpoint_explains_signal;
42548596154Schristos }
42648596154Schristos 
427*1424dfb3Schristos void _initialize_break_catch_sig ();
42848596154Schristos void
_initialize_break_catch_sig()429*1424dfb3Schristos _initialize_break_catch_sig ()
43048596154Schristos {
43148596154Schristos   initialize_signal_catchpoint_ops ();
43248596154Schristos 
43348596154Schristos   signal_catch_counts = XCNEWVEC (unsigned int, GDB_SIGNAL_LAST);
43448596154Schristos 
43548596154Schristos   add_catch_command ("signal", _("\
43648596154Schristos Catch signals by their names and/or numbers.\n\
43748596154Schristos Usage: catch signal [[NAME|NUMBER] [NAME|NUMBER]...|all]\n\
43848596154Schristos Arguments say which signals to catch.  If no arguments\n\
43948596154Schristos are given, every \"normal\" signal will be caught.\n\
44048596154Schristos The argument \"all\" means to also catch signals used by GDB.\n\
44148596154Schristos Arguments, if given, should be one or more signal names\n\
44248596154Schristos (if your system supports that), or signal numbers."),
44348596154Schristos 		     catch_signal_command,
44448596154Schristos 		     signal_completer,
44548596154Schristos 		     CATCH_PERMANENT,
44648596154Schristos 		     CATCH_TEMPORARY);
44748596154Schristos }
448