to 'max-value-size', GDB will now still print the array, however only
   'max-value-size' worth of data will be added into the value history.
 
+* For both the break and watch commands, it is now invalid to use both
+  the 'thread' and 'task' keywords within the same command.  For
+  example the following commnds will now give an error:
+    break foo thread 1 task 1
+    watch var thread 2 task 3
+
 * New commands
 
 maintenance print record-instruction [ N ]
 
     gdb::observers::breakpoint_modified.notify (b);
 }
 
-/* Set the thread for this breakpoint.  If THREAD is -1, make the
-   breakpoint work for any thread.  */
+/* See breakpoint.h.  */
 
 void
 breakpoint_set_thread (struct breakpoint *b, int thread)
 {
+  /* It is invalid to set the thread field to anything other than -1 (which
+     means no thread restriction) if a task restriction is already in
+     place.  */
+  gdb_assert (thread == -1 || b->task == 0);
+
   int old_thread = b->thread;
 
   b->thread = thread;
     gdb::observers::breakpoint_modified.notify (b);
 }
 
-/* Set the task for this breakpoint.  If TASK is 0, make the
-   breakpoint work for any task.  */
+/* See breakpoint.h.  */
 
 void
 breakpoint_set_task (struct breakpoint *b, int task)
 {
+  /* It is invalid to set the task field to anything other than 0 (which
+     means no task restriction) if a thread restriction is already in
+     place.  */
+  gdb_assert (task == 0 || b->thread == -1);
+
   int old_task = b->task;
 
   b->task = task;
 
   gdb_assert (!sals.empty ());
 
+  /* At most one of thread or task can be set on any breakpoint.  */
+  gdb_assert (thread == -1 || task == 0);
   thread = thread_;
   task = task_;
 
          if (*thread != -1)
            error(_("You can specify only one thread."));
 
+         if (*task != 0)
+           error (_("You can specify only one of thread or task."));
+
          tok = end_tok + 1;
          thr = parse_thread_id (tok, &tmptok);
          if (tok == tmptok)
          if (*task != 0)
            error(_("You can specify only one task."));
 
+         if (*thread != -1)
+           error (_("You can specify only one of thread or task."));
+
          tok = end_tok + 1;
          *task = strtol (tok, &tmptok, 0);
          if (tok == tmptok)
   for (auto &sal : sals)
     {
       gdb::unique_xmalloc_ptr<char> cond;
-      int thread_id = 0;
+      int thread_id = -1;
       int task_id = 0;
       gdb::unique_xmalloc_ptr<char> remaining;
 
          find_condition_and_thread (input, sal.pc, &cond, &thread_id,
                                     &task_id, &remaining);
          *cond_string = std::move (cond);
+         /* At most one of thread or task can be set.  */
+         gdb_assert (thread_id == -1 || task_id == 0);
          *thread = thread_id;
          *task = task_id;
          *rest = std::move (remaining);
              if (thread != -1)
                error(_("You can specify only one thread."));
 
+             if (task != 0)
+               error (_("You can specify only one of thread or task."));
+
              /* Extract the thread ID from the next token.  */
              thr = parse_thread_id (value_start, &endp);
 
              if (task != 0)
                error(_("You can specify only one task."));
 
+             if (thread != -1)
+               error (_("You can specify only one of thread or task."));
+
              task = strtol (value_start, &tmp, 0);
              if (tmp == value_start)
                error (_("Junk after task keyword."));
   else
     w.reset (new watchpoint (nullptr, bp_type));
 
+  /* At most one of thread or task can be set on a watchpoint.  */
+  gdb_assert (thread == -1 || task == 0);
   w->thread = thread;
   w->task = task;
   w->disposition = disp_donttouch;
 
 
 extern void breakpoint_set_silent (struct breakpoint *b, int silent);
 
+/* Set the thread for this breakpoint.  If THREAD is -1, make the
+   breakpoint work for any thread.  Passing a value other than -1 for
+   THREAD should only be done if b->task is 0; it is not valid to try and
+   set both a thread and task restriction on a breakpoint.  */
+
 extern void breakpoint_set_thread (struct breakpoint *b, int thread);
 
+/* Set the task for this breakpoint.  If TASK is 0, make the breakpoint
+   work for any task.  Passing a value other than 0 for TASK should only be
+   done if b->thread is -1; it is not valid to try and set both a thread
+   and task restriction on a breakpoint.  */
+
 extern void breakpoint_set_task (struct breakpoint *b, int task);
 
 /* Clear the "inserted" flag in all breakpoints.  */
 
          gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
                                     _("invalid thread id"));
        }
+
+      if (bp_smob->bp->task != 0)
+       scm_misc_error (FUNC_NAME,
+                       _("cannot set both task and thread attributes"),
+                       SCM_EOL);
     }
   else if (gdbscm_is_false (newvalue))
     id = -1;
          gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
                                     _("invalid task id"));
        }
+
+      if (bp_smob->bp->thread != -1)
+       scm_misc_error (FUNC_NAME,
+                       _("cannot set both task and thread attributes"),
+                       SCM_EOL);
     }
   else if (gdbscm_is_false (newvalue))
     id = 0;
 
                           _("Invalid thread ID."));
          return -1;
        }
+
+      if (self_bp->bp->task != 0)
+       {
+         PyErr_SetString (PyExc_RuntimeError,
+                          _("Cannot set both task and thread attributes."));
+         return -1;
+       }
     }
   else if (newvalue == Py_None)
     id = -1;
                           _("Invalid task ID."));
          return -1;
        }
+
+      if (self_bp->bp->thread != -1)
+       {
+         PyErr_SetString (PyExc_RuntimeError,
+                          _("Cannot set both task and thread attributes."));
+         return -1;
+       }
     }
   else if (newvalue == Py_None)
     id = 0;
 
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 load_lib "ada.exp"
+load_lib "gdb-guile.exp"
+load_lib "gdb-python.exp"
 
 require allow_ada_tests
 
                "\r\n"] \
          "info tasks before inserting breakpoint"
 
+# Confirm that the "info threads" output lines up with the tasks list.
+gdb_test "info threads" \
+    [multi_line \
+        "\\*\\s+1\\s+\[^\r\n\]+\\s\"foo\"\\s\[^\r\n\]+" \
+        "\\s+2\\s+\[^\r\n\]+\\s\"task_list\\(1\\)\"\\s\[^\r\n\]+" \
+        "\\s+3\\s+\[^\r\n\]+\\s\"task_list\\(2\\)\"\\s\[^\r\n\]+" \
+        "\\s+4\\s+\[^\r\n\]+\\s\"task_list\\(3\\)\"\\s\[^\r\n\]+"]
+
 # Check that multiple uses of the 'task' keyword will give an error.
 gdb_test "break break_me task 1 task 3" "You can specify only one task\\."
 gdb_test "watch j task 1 task 3" "You can specify only one task\\."
 
+# Check that attempting to combine 'task' and 'thread' gives an error.
+gdb_test "break break_me task 1 thread 1" \
+    "You can specify only one of thread or task\\."
+gdb_test "break break_me thread 1 task 1" \
+    "You can specify only one of thread or task\\."
+gdb_test "watch j task 1 thread 1" \
+    "You can specify only one of thread or task\\."
+gdb_test "watch j thread 1 task 1" \
+    "You can specify only one of thread or task\\."
+
 # Insert a breakpoint that should stop only if task 1 stops.  Since
 # task 1 never calls break_me, this shouldn't actually ever trigger.
 # The fact that this breakpoint is created _before_ the next one
 gdb_test "info breakpoints" "foo.adb:${decimal}\r\n\\s+stop only in task 3" \
     "check info breakpoints for task 3 breakpoint"
 
+# Test the Python API for the breakpoint task attribute.
+if {[allow_python_tests]} {
+    gdb_test_no_output "python bp = gdb.breakpoints()\[$bp_number - 1\]" \
+       "get gdb.Breakpoint from list"
+    gdb_test "python print(bp.task)" "3"
+    gdb_test "python print(bp.thread)" "None"
+    gdb_test "python bp.thread = 1" \
+       [multi_line \
+            "RuntimeError: Cannot set both task and thread attributes\\." \
+            "Error while executing Python code\\."] \
+       "try setting the thread, but expect an error"
+    gdb_test_no_output "python bp.task = None"
+    gdb_test_no_output "python bp.thread = 1"
+    gdb_test "python bp.task = 3" \
+       [multi_line \
+            "RuntimeError: Cannot set both task and thread attributes\\." \
+            "Error while executing Python code\\."] \
+       "try setting the task, but expect an error"
+
+    # Reset the breakpoint to the state required for the rest of this
+    # test.
+    gdb_test_no_output "python bp.thread = None"
+    gdb_test_no_output "python bp.task = 3"
+}
+
+# Test the Guile API for the breakpoint task attribute.
+if {[allow_guile_tests]} {
+    gdb_install_guile_utils
+    gdb_install_guile_module
+
+    gdb_scm_test_silent_cmd "guile (define blist (breakpoints))" \
+       "get breakpoint list"
+    gdb_scm_test_silent_cmd "guile (define bp (list-ref blist (- $bp_number 1)))" \
+       "get <gdb:breakpoint> from list"
+    gdb_test "guile (print (breakpoint-task bp))" "= 3"
+    gdb_test "guile (print (breakpoint-thread bp))" "= #f"
+    gdb_test "guile (set-breakpoint-thread! bp 1)" \
+       [multi_line \
+            "ERROR: In procedure set-breakpoint-thread!:" \
+            "In procedure gdbscm_set_breakpoint_thread_x: cannot set both task and thread attributes" \
+            "Error while executing Scheme code."] \
+       "attempt to set thread, but expect an error"
+
+    gdb_scm_test_silent_cmd "guile (set-breakpoint-task! bp #f)" \
+       "clear breakpoint task attribute"
+    gdb_scm_test_silent_cmd "guile (set-breakpoint-thread! bp 1)" \
+       "set breakpoint thread now task is unset"
+    gdb_test "guile (set-breakpoint-task! bp 1)" \
+       [multi_line \
+            "ERROR: In procedure set-breakpoint-task!:" \
+            "In procedure gdbscm_set_breakpoint_task_x: cannot set both task and thread attributes" \
+            "Error while executing Scheme code."] \
+       "attempt to set task, but expect an error"
+
+    # Reset the breakpoint to the state required for the rest of this
+    # test.
+    gdb_scm_test_silent_cmd "guile (set-breakpoint-thread! bp #f)" \
+       "clear breakpoint thread attribute"
+    gdb_scm_test_silent_cmd "guile (set-breakpoint-task! bp 3)" \
+       "restore breakpoint task attribute"
+}
+
 # Continue to that breakpoint.  Task 2 should hit it first, and GDB
 # is expected to ignore that hit and resume the execution.  Only then
 # task 3 will hit our breakpoint, and GDB is expected to stop at that