diff --git a/gdb/NEWS b/gdb/NEWS
index c6fe297..ef5e348 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -656,6 +656,9 @@ show max-value-size
 * Support for reading/writing memory and extracting values on architectures
   whose memory is addressable in units of any integral multiple of 8 bits.
 
+catch handle
+  Allows to break when an Ada exception is handled.
+
 * New remote packets
 
 exec stop reason
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 9e637eb..373a9a3 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11833,6 +11833,10 @@ struct exception_support_info
       a catchpoint on failed assertions.  */
    const char *catch_assert_sym;
 
+   /* The name of the symbol to break on in order to insert
+      a catchpoint on exception handling.  */
+   const char *catch_handle_sym;
+
    /* Assuming that the inferior just triggered an unhandled exception
       catchpoint, this function is responsible for returning the address
       in inferior memory where the name of that exception is stored.
@@ -11852,6 +11856,7 @@ static const struct exception_support_info default_exception_support_info =
   "__gnat_debug_raise_exception", /* catch_exception_sym */
   "__gnat_unhandled_exception", /* catch_exception_unhandled_sym */
   "__gnat_debug_raise_assert_failure", /* catch_assert_sym */
+  "__gnat_begin_handler", /* catch_handle_sym */
   ada_unhandled_exception_name_addr
 };
 
@@ -11864,6 +11869,7 @@ static const struct exception_support_info exception_support_info_fallback =
   "__gnat_raise_nodefer_with_msg", /* catch_exception_sym */
   "__gnat_unhandled_exception", /* catch_exception_unhandled_sym */
   "system__assertions__raise_assert_failure",  /* catch_assert_sym */
+  "__gnat_begin_handler", /* catch_handle_sym */
   ada_unhandled_exception_name_addr_from_raise
 };
 
@@ -12132,7 +12138,12 @@ ada_exception_name_addr_1 (enum ada_exception_catchpoint_kind ex,
       case ada_catch_exception_unhandled:
         return data->exception_info->unhandled_exception_name_addr ();
         break;
-      
+
+      case ada_catch_handle:
+        return 0;  /* The runtimes does not provide access to the exception
+		      name.  */
+        break;
+
       case ada_catch_assert:
         return 0;  /* Exception name is not relevant in this case.  */
         break;
@@ -12238,7 +12249,8 @@ ada_exception_name_addr (enum ada_exception_catchpoint_kind ex,
   return result;
 }
 
-static char *ada_exception_catchpoint_cond_string (const char *excep_string);
+static char *ada_exception_catchpoint_cond_string (const char *excep_string,
+                                                   enum ada_exception_catchpoint_kind ex);
 
 /* Ada catchpoints.
 
@@ -12301,7 +12313,8 @@ struct ada_catchpoint : public breakpoint
    catchpoint's locations, and store them for later evaluation.  */
 
 static void
-create_excep_cond_exprs (struct ada_catchpoint *c)
+create_excep_cond_exprs (struct ada_catchpoint *c,
+                         enum ada_exception_catchpoint_kind ex)
 {
   struct cleanup *old_chain;
   struct bp_location *bl;
@@ -12317,7 +12330,7 @@ create_excep_cond_exprs (struct ada_catchpoint *c)
 
   /* Compute the condition expression in text form, from the specific
      expection we want to catch.  */
-  cond_string = ada_exception_catchpoint_cond_string (c->excep_string);
+  cond_string = ada_exception_catchpoint_cond_string (c->excep_string, ex);
   old_chain = make_cleanup (xfree, cond_string);
 
   /* Iterate over all the catchpoint's locations, and parse an
@@ -12385,7 +12398,7 @@ re_set_exception (enum ada_exception_catchpoint_kind ex, struct breakpoint *b)
 
   /* Reparse the exception conditional expressions.  One for each
      location.  */
-  create_excep_cond_exprs (c);
+  create_excep_cond_exprs (c, ex);
 }
 
 /* Returns true if we should stop for this breakpoint hit.  If the
@@ -12474,6 +12487,7 @@ print_it_exception (enum ada_exception_catchpoint_kind ex, bpstat bs)
     {
       case ada_catch_exception:
       case ada_catch_exception_unhandled:
+      case ada_catch_handle:
 	{
 	  const CORE_ADDR addr = ada_exception_name_addr (ex, b);
 	  char exception_name[256];
@@ -12557,22 +12571,36 @@ print_one_exception (enum ada_exception_catchpoint_kind ex,
       case ada_catch_exception:
         if (c->excep_string != NULL)
           {
-            char *msg = xstrprintf (_("`%s' Ada exception"), c->excep_string);
+            char *info = xstrprintf (_("`%s' Ada exception"), c->excep_string);
+            struct cleanup *old_chain = make_cleanup (xfree, info);
 
-            uiout->field_string ("what", msg);
-            xfree (msg);
+            uiout->text (info);
+            do_cleanups (old_chain);
           }
         else
-          uiout->field_string ("what", "all Ada exceptions");
+          uiout->text (_("all Ada exceptions"));
         
         break;
 
       case ada_catch_exception_unhandled:
-        uiout->field_string ("what", "unhandled Ada exceptions");
+	uiout->text (_("unhandled Ada exceptions"));
         break;
-      
+
+      case ada_catch_handle:
+        if (c->excep_string != NULL)
+          {
+            char *info = xstrprintf (_("`%s' Ada exception hanlder"), c->excep_string);
+            struct cleanup *old_chain = make_cleanup (xfree, info);
+
+            uiout->text (info);
+            do_cleanups (old_chain);
+          }
+        else
+	  uiout->text (_("all Ada exceptions handler"));
+        break;
+
       case ada_catch_assert:
-        uiout->field_string ("what", "failed Ada assertions");
+	uiout->text (_("failed Ada assertions"));
         break;
 
       default:
@@ -12614,7 +12642,21 @@ print_mention_exception (enum ada_exception_catchpoint_kind ex,
       case ada_catch_exception_unhandled:
         uiout->text (_("unhandled Ada exceptions"));
         break;
-      
+
+      case ada_catch_handle:
+        if (c->excep_string != NULL)
+	  {
+	    char *info = xstrprintf (_("`%s' Ada exception handler"),
+                                     c->excep_string);
+	    struct cleanup *old_chain = make_cleanup (xfree, info);
+
+	    uiout->text (info);
+	    do_cleanups (old_chain);
+	  }
+        else
+          uiout->text (_("all Ada exceptions handler"));
+        break;
+
       case ada_catch_assert:
         uiout->text (_("failed Ada assertions"));
         break;
@@ -12646,6 +12688,10 @@ print_recreate_exception (enum ada_exception_catchpoint_kind ex,
 	fprintf_filtered (fp, "catch exception unhandled");
 	break;
 
+      case ada_catch_handle:
+	fprintf_filtered (fp, "catch handle");
+	break;
+
       case ada_catch_assert:
 	fprintf_filtered (fp, "catch assert");
 	break;
@@ -12796,6 +12842,54 @@ print_recreate_catch_assert (struct breakpoint *b, struct ui_file *fp)
 
 static struct breakpoint_ops catch_assert_breakpoint_ops;
 
+/* Virtual table for "catch handle" breakpoints.  */
+
+static struct bp_location *
+allocate_location_catch_handle (struct breakpoint *self)
+{
+  return allocate_location_exception (ada_catch_handle, self);
+}
+
+static void
+re_set_catch_handle (struct breakpoint *b)
+{
+  re_set_exception (ada_catch_handle, b);
+}
+
+static void
+check_status_catch_handle (bpstat bs)
+{
+  check_status_exception (ada_catch_handle, bs);
+}
+
+static enum print_stop_action
+print_it_catch_handle (bpstat bs)
+{
+  return print_it_exception (ada_catch_handle, bs);
+}
+
+static void
+print_one_catch_handle (struct breakpoint *b,
+			struct bp_location **last_loc)
+{
+  print_one_exception (ada_catch_handle, b, last_loc);
+}
+
+static void
+print_mention_catch_handle (struct breakpoint *b)
+{
+  print_mention_exception (ada_catch_handle, b);
+}
+
+static void
+print_recreate_catch_handle (struct breakpoint *b,
+			     struct ui_file *fp)
+{
+  print_recreate_exception (ada_catch_handle, b, fp);
+}
+
+static struct breakpoint_ops catch_handle_breakpoint_ops;
+
 /* Return a newly allocated copy of the first space-separated token
    in ARGSP, and then adjust ARGSP to point immediately after that
    token.
@@ -12834,6 +12928,8 @@ ada_get_next_arg (const char **argsp)
    Set EX to the appropriate catchpoint type.
    Set EXCEP_STRING to the name of the specific exception if
    specified by the user.
+   HANDLE: Nonzero if the arguments are for a "catch handle" command.
+   Zero otherwise.
    If a condition is found at the end of the arguments, the condition
    expression is stored in COND_STRING (memory must be deallocated
    after use).  Otherwise COND_STRING is set to NULL.  */
@@ -12842,7 +12938,7 @@ static void
 catch_ada_exception_command_split (const char *args,
                                    enum ada_exception_catchpoint_kind *ex,
 				   char **excep_string,
-				   char **cond_string)
+				   char **cond_string, int handle)
 {
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   char *exception_name;
@@ -12885,7 +12981,13 @@ catch_ada_exception_command_split (const char *args,
 
   discard_cleanups (old_chain);
 
-  if (exception_name == NULL)
+  if (handle)
+    {
+      /* Catch handling of exceptions.  */
+      *ex = ada_catch_handle;
+      *excep_string = exception_name;
+    }
+  else if (exception_name == NULL)
     {
       /* Catch all exceptions.  */
       *ex = ada_catch_exception;
@@ -12927,6 +13029,9 @@ ada_exception_sym_name (enum ada_exception_catchpoint_kind ex)
       case ada_catch_assert:
         return (data->exception_info->catch_assert_sym);
         break;
+      case ada_catch_handle:
+        return (data->exception_info->catch_handle_sym);
+        break;
       default:
         internal_error (__FILE__, __LINE__,
                         _("unexpected catchpoint kind (%d)"), ex);
@@ -12950,6 +13055,9 @@ ada_exception_breakpoint_ops (enum ada_exception_catchpoint_kind ex)
       case ada_catch_assert:
         return (&catch_assert_breakpoint_ops);
         break;
+      case ada_catch_handle:
+        return (&catch_handle_breakpoint_ops);
+        break;
       default:
         internal_error (__FILE__, __LINE__,
                         _("unexpected catchpoint kind (%d)"), ex);
@@ -12960,14 +13068,18 @@ ada_exception_breakpoint_ops (enum ada_exception_catchpoint_kind ex)
    being raised with the exception that the user wants to catch.  This
    assumes that this condition is used when the inferior just triggered
    an exception catchpoint.
+   EX: the type of catchpoints used for catching Ada exceptions.
    
    The string returned is a newly allocated string that needs to be
    deallocated later.  */
 
 static char *
-ada_exception_catchpoint_cond_string (const char *excep_string)
+ada_exception_catchpoint_cond_string (const char *excep_string,
+                                      enum ada_exception_catchpoint_kind ex)
 {
-  int i;
+  int i, is_standard_exc;
+  const char *actual_exc_expr;
+  char *ref_exc_expr;
 
   /* The standard exceptions are a special case.  They are defined in
      runtime units that have been compiled without debugging info; if
@@ -12988,15 +13100,32 @@ ada_exception_catchpoint_cond_string (const char *excep_string)
      breakpoint condition is to use its fully-qualified named:
      e.g. my_package.constraint_error.  */
 
+  if (ex == ada_catch_handle)
+    /* For exception handler catchpoints, the condition string does
+       not use the same parameter as for the other exceptions.  */
+    actual_exc_expr
+      = "long_integer (\
+GNAT_GCC_exception_Access(gcc_exception).all.occurrence.id)";
+  else
+    actual_exc_expr = "long_integer (e)";
+
   for (i = 0; i < sizeof (standard_exc) / sizeof (char *); i++)
     {
       if (strcmp (standard_exc [i], excep_string) == 0)
 	{
-          return xstrprintf ("long_integer (e) = long_integer (&standard.%s)",
-                             excep_string);
+	  is_standard_exc = 1;
+	  break;
 	}
     }
-  return xstrprintf ("long_integer (e) = long_integer (&%s)", excep_string);
+
+  if (is_standard_exc)
+    ref_exc_expr = xstrprintf ("long_integer (&standard.%s)", excep_string);
+  else
+    ref_exc_expr = xstrprintf ("long_integer (&%s)", excep_string);
+
+  //xfree (ref_exc_expr);
+
+  return xstrprintf ("%s = %s", actual_exc_expr, ref_exc_expr);
 }
 
 /* Return the symtab_and_line that should be used to insert an exception
@@ -13079,7 +13208,7 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
   init_ada_exception_breakpoint (c.get (), gdbarch, sal, addr_string,
 				 ops, tempflag, disabled, from_tty);
   c->excep_string = excep_string;
-  create_excep_cond_exprs (c.get ());
+  create_excep_cond_exprs (c.get (), ex_kind);
   if (cond_string != NULL)
     set_breakpoint_condition (c.get (), cond_string, from_tty);
   install_breakpoint (0, std::move (c), 1);
@@ -13103,7 +13232,32 @@ catch_ada_exception_command (const char *arg_entry, int from_tty,
   if (!arg)
     arg = "";
   catch_ada_exception_command_split (arg, &ex_kind, &excep_string,
-				     &cond_string);
+				     &cond_string, 0);
+  create_ada_exception_catchpoint (gdbarch, ex_kind,
+				   excep_string, cond_string,
+				   tempflag, 1 /* enabled */,
+				   from_tty);
+}
+
+/* Implement the "catch handle" command.  */
+
+static void
+catch_ada_handle_command (const char *arg_entry, int from_tty,
+			     struct cmd_list_element *command)
+{
+  const char *arg = arg_entry;
+  struct gdbarch *gdbarch = get_current_arch ();
+  int tempflag;
+  enum ada_exception_catchpoint_kind ex_kind;
+  char *excep_string = NULL;
+  char *cond_string = NULL;
+
+  tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
+
+  if (!arg)
+    arg = "";
+  catch_ada_exception_command_split (arg, &ex_kind, &excep_string,
+				     &cond_string, 1);
   create_ada_exception_catchpoint (gdbarch, ex_kind,
 				   excep_string, cond_string,
 				   tempflag, 1 /* enabled */,
@@ -14217,6 +14371,16 @@ initialize_ada_catchpoint_ops (void)
   ops->print_one = print_one_catch_assert;
   ops->print_mention = print_mention_catch_assert;
   ops->print_recreate = print_recreate_catch_assert;
+
+  ops = &catch_handle_breakpoint_ops;
+  *ops = bkpt_breakpoint_ops;
+  ops->allocate_location = allocate_location_catch_handle;
+  ops->re_set = re_set_catch_handle;
+  ops->check_status = check_status_catch_handle;
+  ops->print_it = print_it_catch_handle;
+  ops->print_one = print_one_catch_handle;
+  ops->print_mention = print_mention_catch_handle;
+  ops->print_recreate = print_recreate_catch_handle;
 }
 
 /* This module's 'new_objfile' observer.  */
@@ -14277,6 +14441,14 @@ With an argument, catch only exceptions with the given name."),
                      NULL,
 		     CATCH_PERMANENT,
 		     CATCH_TEMPORARY);
+
+  add_catch_command ("handle", _("\
+Catch Ada exceptions, when handled.\n\
+With an argument, catch only exceptions with the given name."),
+		     catch_ada_handle_command,
+                     NULL,
+		     CATCH_PERMANENT,
+		     CATCH_TEMPORARY);
   add_catch_command ("assert", _("\
 Catch failed Ada assertions, when raised.\n\
 With an argument, catch only exceptions with the given name."),
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 0530e9a..4e9850e 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -108,7 +108,8 @@ enum ada_exception_catchpoint_kind
 {
   ada_catch_exception,
   ada_catch_exception_unhandled,
-  ada_catch_assert
+  ada_catch_assert,
+  ada_catch_handle
 };
 
 /* Ada task structures.  */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 062f01d..85e71e5 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -4453,6 +4453,25 @@ called @code{Constraint_Error} is defined in package @code{Pck}, then
 the command to use to catch such exceptions is @kbd{catch exception
 Pck.Constraint_Error}.
 
+@item handle
+@kindex catch handle
+@cindex Ada exception handle catching
+@cindex catch Ada exceptions when handled
+An Ada exception being handled.  If an exception name is
+specified at the end of the command (eg @code{catch exception Program_Error}),
+the debugger will stop only when this specific exception is handled.
+Otherwise, the debugger stops execution when any Ada exception is handled.
+
+When inserting an handle catchpoint on a user-defined
+exception whose name is identical to one of the exceptions
+defined by the language, the fully qualified name must be used
+as the exception name.  Otherwise, @value{GDBN} will assume that it
+should stop on the pre-defined exception rather than the
+user-defined one.  For instance, assuming an exception called
+ @code{Constraint_Error} is defined in package @code{Pck}, then the
+command to use to catch such exceptions handling is
+@kbd{catch handle Pck.Constraint_Error}.
+
 @item exception unhandled
 @kindex catch exception unhandled
 An exception that was raised but is not handled by the program.
diff --git a/gdb/testsuite/gdb.ada/excep_handle.exp b/gdb/testsuite/gdb.ada/excep_handle.exp
new file mode 100644
index 0000000..ec63d98
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/excep_handle.exp
@@ -0,0 +1,159 @@
+# Copyright 2017 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+load_lib "ada.exp"
+
+standard_ada_testfile foo
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional_flags=-gnata ]] != "" } {
+  return -1
+}
+
+clean_restart ${testfile}
+
+# Some global variables used to simplify the maintenance of some of
+# the regular expressions below.
+set eol "\[\r\n\]+"
+set sp "\[ \t\]*"
+
+set when "when"
+set catchpoint_constraint_error_msg \
+  "Catchpoint $decimal, exception at $hex in foo \\\(\\\).*at .*foo.adb:$decimal$eol$decimal$sp$when Constraint_Error =>"
+
+set catchpoint_program_error_msg \
+  "Catchpoint $decimal, exception at $hex in foo \\\(\\\).*at .*foo.adb:$decimal$eol$decimal$sp$when Program_Error =>"
+
+set catchpoint_storage_error_msg \
+  "Catchpoint $decimal, exception at $hex in foo \\\(\\\).*at .*foo.adb:$decimal$eol$decimal$sp$when Storage_Error =>"
+
+############################################
+# Check that runtime supports catchpoint.  #
+############################################
+
+if ![runto_main] then {
+   fail "Cannot run to main, testcase aborted"
+   return 0
+}
+
+set msg "insert catchpoint on all Ada exceptions handle"
+gdb_test_multiple "catch handle" $msg {
+-re "Catchpoint $decimal: all Ada exceptions handler$eol$gdb_prompt $" {
+	pass $msg
+    }
+    -re "Your Ada runtime appears to be missing some debugging information.*$eol$gdb_prompt $" {
+	# If the runtime was not built with enough debug information,
+	# or if it was stripped, we can not test exception handler
+	# catchpoints.
+	unsupported $msg
+	return -1
+    }
+}
+
+############################################
+# 1. Try catching all exceptions handler.  #
+############################################
+
+# Continue. The program should stop at first exception handling.
+
+gdb_test "continue" \
+         "Continuing\.$eol$catchpoint_constraint_error_msg$eol.*" \
+         "continuing to Constraint_Error exception handle"
+
+# Check that when no exception is raised, the program does not
+# stop in the exception handling.
+
+gdb_test "continue" \
+         "Continuing\.$eol$catchpoint_storage_error_msg$eol.*" \
+         "continuing without stopping to Storage_Error exception handle"
+
+gdb_test_no_output "delete 2" "disable catchpoint 1"
+
+##################################################
+# 2. Try catching some named exception handler.  #
+##################################################
+
+# Insert Program_Error Ada exception handler
+
+gdb_test "catch handle Program_Error" \
+         "Catchpoint $decimal: `Program_Error' Ada exception handler" \
+         "insert catchpoint on Program_Error Ada exception handler"
+
+# Continue, we should not stop at ABORT_SIGNAL but as Program_Error one
+
+gdb_test "continue" \
+         "Continuing\.$eol$catchpoint_program_error_msg$eol.*" \
+         "continuing without stopping to Program_Error exception handle"
+
+gdb_test_no_output "delete 3" "disable catchpoint 2"
+
+# Insert Storage_Error Ada exception handler
+
+gdb_test "catch handle Storage_Error" \
+         "Catchpoint $decimal: `Storage_Error' Ada exception handler" \
+         "insert catchpoint on Storage_Error Ada exception handler"
+
+# Continue, we should stop at Storage_Error handler
+
+gdb_test "continue" \
+         "Continuing\.$eol$catchpoint_storage_error_msg$eol.*" \
+         "continuing without stopping to Storage_Error exception handle"
+
+gdb_test_no_output "delete 4" "disable catchpoint 3"
+
+########################################################################
+# 3. Try catching with condition and without named exception handler.  #
+########################################################################
+
+# Insert Ada all exceptions handler with condition
+
+gdb_test "catch handle if Global_Var = 2" \
+         "Catchpoint $decimal: all Ada exceptions handler" \
+         "insert catchpoint on all Ada exception handler with condition"
+
+# Check that condition is stored and properly displayed
+
+gdb_test "info breakpoint" ".*stop only if Global_Var = 2" \
+         "Check catch handle with condition"
+
+# Continue, we should not stop at ABORT_SIGNAL but as Program_Error one
+
+gdb_test "continue" \
+         "Continuing\.$eol$catchpoint_constraint_error_msg$eol.*" \
+         "continuing to Constraint_Error exception handle"
+
+gdb_test_no_output "delete 5" "disable catchpoint 4"
+
+################################################################
+# 4. Try catching with condition and named exception handler.  #
+################################################################
+
+# Insert Program_Error Ada exception handler with condition
+
+gdb_test "catch handle Program_Error if Global_Var = 4" \
+         "Catchpoint $decimal: `Program_Error' Ada exception handler" \
+         "insert catchpoint on Program_Error Ada exception handler with condition"
+
+# Continue, we should not stop at first Program_Error handler but at
+# the second one.
+
+gdb_test "continue" \
+         "Continuing\.$eol$catchpoint_program_error_msg$eol.*" \
+         "continuing to Program_Error exception handle"
+
+# Continue, the program should exit properly.
+
+gdb_test "continue" \
+         "Continuing\..*$inferior_exited_re.*" \
+         "continuing to program completion"
diff --git a/gdb/testsuite/gdb.ada/excep_handle/foo.adb b/gdb/testsuite/gdb.ada/excep_handle/foo.adb
new file mode 100644
index 0000000..887e339
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/excep_handle/foo.adb
@@ -0,0 +1,103 @@
+--  Copyright 2017 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+with Pck; use Pck;
+
+procedure Foo is
+begin
+
+   -- Part 1 of the test
+
+   begin
+      raise Constraint_Error;
+   exception
+      when Constraint_Error =>
+         null;
+   end;
+
+   begin
+      null;
+   exception
+      when others =>
+         null;
+   end;
+
+   begin
+      raise Storage_Error;
+   exception
+      when Storage_Error =>
+         null;
+   end;
+
+   -- Part 2 of the test
+
+   begin
+      raise ABORT_SIGNAL;
+   exception
+      when others =>
+         null;
+   end;
+
+   begin
+      raise Program_Error;
+   exception
+      when Program_Error =>
+         null;
+   end;
+
+   begin
+      raise Storage_Error;
+   exception
+      when Storage_Error =>
+         null;
+   end;
+
+  -- Part 3 of the test
+
+   begin
+      Global_Var := Global_Var + 1;
+      raise ABORT_SIGNAL;
+   exception
+      when others =>
+         null;
+   end;
+
+   begin
+      Global_Var := Global_Var + 1;
+      raise Constraint_Error;
+   exception
+      when Constraint_Error =>
+         null;
+   end;
+
+   -- Part 4 of the test
+
+   begin
+      Global_Var := Global_Var + 1;
+      raise Program_Error;
+   exception
+      when others =>
+         null;
+   end;
+
+   begin
+      Global_Var := Global_Var + 1;
+      raise Program_Error;
+   exception
+      when Program_Error =>
+         null;
+   end;
+
+end Foo;
diff --git a/gdb/testsuite/gdb.ada/excep_handle/pck.ads b/gdb/testsuite/gdb.ada/excep_handle/pck.ads
new file mode 100644
index 0000000..1b438fc
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/excep_handle/pck.ads
@@ -0,0 +1,19 @@
+--  Copyright 2017 Free Software Foundation, Inc.
+--
+--  This program is free software; you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License as published by
+--  the Free Software Foundation; either version 3 of the License, or
+--  (at your option) any later version.
+--
+--  This program is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+package Pck is
+   Global_Var : Integer := 0;
+   ABORT_SIGNAL : exception;
+end Pck;
