diff --git a/gdb/NEWS b/gdb/NEWS
index 13da2f1..d0786b0 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -84,6 +84,12 @@ SH-5/SH64 running OpenBSD 	SH-5/SH64 support in sh*-*-openbsd*
   the tradeoff that there is a possibility of false hits being
   reported.
 
+* Dynamic printf argument evaluation error changes
+
+  When GDB fails to evaluate an expression passed as an argument to a dynamic
+  printf, it will print an error and the dynamic printf will cause a stop.  In
+  MI, this stop is reported using the new "dprintf-error" stop reason.
+
 *** Changes in GDB 8.1
 
 * GDB now supports dynamically creating arbitrary register groups specified
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f20bc50..db44bf8 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5677,8 +5677,10 @@ bpstat_what (bpstat bs_head)
 	  break;
 
 	case bp_dprintf:
+	  /* We may stop on a dprintf if we failed to evaluate the expressions to
+	     print.  */
 	  if (bs->stop)
-	    this_action = BPSTAT_WHAT_STOP_SILENT;
+	    this_action = BPSTAT_WHAT_STOP_NOISY;
 	  else
 	    this_action = BPSTAT_WHAT_SINGLE;
 	  break;
@@ -12993,6 +12995,31 @@ dprintf_re_set (struct breakpoint *b)
     update_dprintf_command_list (b);
 }
 
+/* Implement the "print_it" breakpoint_ops method for dprintf.  */
+
+static enum print_stop_action
+dprintf_print_it (bpstat bs)
+{
+  struct ui_out *uiout = current_uiout;
+  gdb_assert (bs->bp_location_at != NULL);
+  breakpoint *bp = bs->breakpoint_at;
+
+  maybe_print_thread_hit_breakpoint (uiout);
+
+  uiout->text ("Dprintf ");
+  if (uiout->is_mi_like_p ())
+    {
+      uiout->field_string ("reason",
+			   async_reason_lookup (EXEC_ASYNC_DPRINTF_ERROR));
+    }
+  uiout->field_int ("bkptno", bp->number);
+  uiout->text (", failed to evaluate: ");
+  uiout->field_string ("error-message", bs->dprintf_error);
+  uiout->text ("\n");
+
+  return PRINT_SRC_AND_LOC;
+}
+
 /* Implement the "print_recreate" breakpoint_ops method for dprintf.  */
 
 static void
@@ -13032,7 +13059,17 @@ dprintf_after_condition_true (struct bpstats *bs)
   tmp_bs.commands = bs->commands;
   bs->commands = NULL;
 
-  bpstat_do_actions_1 (&tmp_bs_p);
+  TRY
+    {
+      bpstat_do_actions_1 (&tmp_bs_p);
+    }
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      /* Stop the inferior if we fail to evaluate an expression.  */
+      bs->stop = 1;
+      bs->dprintf_error = ex.message;
+    }
+  END_CATCH
 
   /* 'tmp_bs.commands' will usually be NULL by now, but
      bpstat_do_actions_1 may return early without processing the whole
@@ -15504,7 +15541,7 @@ initialize_breakpoint_ops (void)
   *ops = bkpt_base_breakpoint_ops;
   ops->re_set = dprintf_re_set;
   ops->resources_needed = bkpt_resources_needed;
-  ops->print_it = bkpt_print_it;
+  ops->print_it = dprintf_print_it;
   ops->print_mention = bkpt_print_mention;
   ops->print_recreate = dprintf_print_recreate;
   ops->after_condition_true = dprintf_after_condition_true;
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 4223158..2aead5c 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -1167,6 +1167,10 @@ struct bpstats
     /* Tell bpstat_print and print_bp_stop_message how to print stuff
        associated with this element of the bpstat chain.  */
     enum bp_print_how print_it;
+
+    /* When we stop due to a failed dprintf evaluation (e.g. referenced an
+       unknown symbol), this contains a meaningful error message.  */
+    std::string dprintf_error;
   };
 
 enum inf_context
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 2b56b5a..da15f53 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -5170,6 +5170,12 @@ may be the values of local variables, but if that is the case, then
 all enabled dynamic prints must be at locations within the scope of
 those locals.  If evaluation fails, @value{GDBN} will report an error.
 
+When using @code{dprintf-style} values @code{gdb} or @code{call}, if
+@value{GDBN} fails to evaluate an expression passed as an argument (a reference
+to an unknown symbol or an access to an invalid memory location, for example),
+it will report the error and the dynamic printf will cause a stop, as if it was
+a breakpoint.
+
 @node Save Breakpoints
 @subsection How to save breakpoints to a file
 
@@ -27338,6 +27344,9 @@ The inferior returned from a system call.  This is reported when
 @item exec
 The inferior called @code{exec}.  This is reported when @code{catch exec}
 (@pxref{Set Catchpoints}) has been used.
+@item dprintf-error
+GDB failed to evaluate the argument of a dynamic printf (@xref{Dynamic Printf}).
+An error message is available in the @code{error-message} field.
 @end table
 
 The @var{id} field identifies the global thread ID of the thread
diff --git a/gdb/mi/mi-common.c b/gdb/mi/mi-common.c
index 1724f32..d4c95e3 100644
--- a/gdb/mi/mi-common.c
+++ b/gdb/mi/mi-common.c
@@ -39,6 +39,7 @@ static const char * const async_reason_string_lookup[] =
   "syscall-entry",
   "syscall-return",
   "exec",
+  "dprintf-error",
   NULL
 };
 
diff --git a/gdb/mi/mi-common.h b/gdb/mi/mi-common.h
index c8ad0d2..4af43eb 100644
--- a/gdb/mi/mi-common.h
+++ b/gdb/mi/mi-common.h
@@ -46,6 +46,7 @@ enum async_reply_reason
   EXEC_ASYNC_SYSCALL_ENTRY,
   EXEC_ASYNC_SYSCALL_RETURN,
   EXEC_ASYNC_EXEC,
+  EXEC_ASYNC_DPRINTF_ERROR,
   /* This is here only to represent the number of enums.  */
   EXEC_ASYNC_LAST
 };
diff --git a/gdb/testsuite/gdb.base/dprintf-error.c b/gdb/testsuite/gdb.base/dprintf-error.c
new file mode 100644
index 0000000..7203f7a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dprintf-error.c
@@ -0,0 +1,27 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 2018 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/>.  */
+
+static void
+foo (void)
+{
+}
+
+int
+main (void)
+{
+  foo ();
+}
diff --git a/gdb/testsuite/gdb.base/dprintf-error.exp b/gdb/testsuite/gdb.base/dprintf-error.exp
new file mode 100644
index 0000000..7841362
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dprintf-error.exp
@@ -0,0 +1,27 @@
+#   Copyright (C) 2018 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/>.
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
+    return -1
+}
+
+if ![runto main] {
+    return -1
+}
+
+gdb_test "dprintf foo, \"Hello %d\", doesnt_exist" "Dprintf $decimal at .*"
+gdb_test "continue" ".*Dprintf $decimal, failed to evaluate: No symbol \"doesnt_exist\" in current context.*"
diff --git a/gdb/testsuite/gdb.mi/mi-dprintf-error.c b/gdb/testsuite/gdb.mi/mi-dprintf-error.c
new file mode 100644
index 0000000..7203f7a
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-dprintf-error.c
@@ -0,0 +1,27 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright (C) 2018 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/>.  */
+
+static void
+foo (void)
+{
+}
+
+int
+main (void)
+{
+  foo ();
+}
diff --git a/gdb/testsuite/gdb.mi/mi-dprintf-error.exp b/gdb/testsuite/gdb.mi/mi-dprintf-error.exp
new file mode 100644
index 0000000..551350a
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-dprintf-error.exp
@@ -0,0 +1,38 @@
+#   Copyright (C) 2018 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 mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+standard_testfile
+
+if {[build_executable $testfile.exp $testfile $srcfile {debug}] == -1} {
+    untested "failed to compile"
+    return -1
+}
+
+mi_delete_breakpoints
+mi_run_to_main
+
+mi_gdb_test "-dprintf-insert foo \"Hello %d\" doesnt_exist" \
+    "\\^done,.*" "insert dprintf"
+
+set extra [list "" {bkptno="[0-9]+",error-message="No symbol \\"doesnt_exist\\" in current context.".*}]
+mi_execute_to exec-continue dprintf-error foo "" "mi-dprintf-error.c" $decimal $extra "continue to failed dprintf"
