diff --git a/core/lib/Drupal/Core/ExceptionController.php b/core/lib/Drupal/Core/ExceptionController.php
index 92d4454..7d73c84 100644
--- a/core/lib/Drupal/Core/ExceptionController.php
+++ b/core/lib/Drupal/Core/ExceptionController.php
@@ -225,8 +225,12 @@ public function on404Html(FlattenException $exception, Request $request) {
   public function on500Html(FlattenException $exception, Request $request) {
     $error = $this->decodeException($exception);
 
-    // Because the kernel doesn't run until full bootstrap, we know that
-    // most subsystems are already initialized.
+    // Backtrace array is not a valid replacement value for t().
+    $backtrace = array();
+    if (isset($error['backtrace'])) {
+      $backtrace = $error['backtrace'];
+      unset($error['backtrace']);
+    }
 
     $headers = array();
 
@@ -258,13 +262,35 @@ public function on500Html(FlattenException $exception, Request $request) {
       $class = 'error';
 
       // If error type is 'User notice' then treat it as debug information
-      // instead of an error message, see dd().
+      // instead of an error message.
+      // @see debug()
       if ($error['%type'] == 'User notice') {
         $error['%type'] = 'Debug';
         $class = 'status';
       }
 
-      drupal_set_message(t('%type: !message in %function (line %line of %file).', $error), $class);
+      // Attempt to reduce verbosity by removing DRUPAL_ROOT from the file path
+      // in the message. This does not happen for (false) security.
+      $root_length = strlen(DRUPAL_ROOT);
+      if (substr($error['%file'], 0, $root_length) == DRUPAL_ROOT) {
+        $error['%file'] = substr($error['%file'], $root_length + 1);
+      }
+      // Should not translate the string to avoid errors producing more errors.
+      $message = format_string('%type: !message in %function (line %line of %file).', $error);
+
+      // Check if verbose error reporting is on.
+      $error_level = config('system.logging')->get('error_level');
+
+      if ($error_level == ERROR_REPORTING_DISPLAY_VERBOSE) {
+        // First trace is the error itself, already contained in the message.
+        // While the second trace is the error source and also contained in the
+        // message, the message doesn't contain argument values, so we output it
+        // once more in the backtrace.
+        array_shift($backtrace);
+        // Generate a backtrace containing only scalar argument values.
+        $message .= '<pre class="backtrace">' . format_backtrace($backtrace) . '</pre>';
+      }
+      drupal_set_message($message, $class, TRUE);
     }
 
     drupal_set_title(t('Error'));
@@ -369,6 +395,7 @@ protected function decodeException(FlattenException $exception) {
       '%file' => $caller['file'],
       '%line' => $caller['line'],
       'severity_level' => WATCHDOG_ERROR,
+      'backtrace' => $backtrace,
     );
   }
 
@@ -380,12 +407,12 @@ protected function decodeException(FlattenException $exception) {
    * and not one of our debug functions.
    *
    * @param $backtrace
-   *   A standard PHP backtrace.
+   *   A standard PHP backtrace. Passed by reference.
    *
    * @return
    *   An associative array with keys 'file', 'line' and 'function'.
    */
-  protected function getLastCaller($backtrace) {
+  protected function getLastCaller(&$backtrace) {
     // Ignore black listed error handling functions.
     $blacklist = array('debug', '_drupal_error_handler', '_drupal_exception_handler');
 
