diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,17 @@
 
 # Changelog
 
-## Unreleased
+## 1.0.1.0
+
+GHC 8.10 compatibility and a new troubleshooting tool.
+
+### Added
+
+- `utf8-troubleshoot` – the troubleshooting tool
+
+### Changed
+
+- Bump `base` for GHC 8.10
 
 
 ## 1.0.0.0
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -80,6 +80,16 @@
 If, for some reason, you really need to use `withFile`/`openFile` from `base`,
 do the same as in the previous step.
 
+## Troubleshooting
+
+Locales are pretty straightforward, but some people might have their terminals
+misconfigured for various reasons. To help troubleshoot any potential issues,
+this package comes with a tool called `utf8-troubleshoot`.
+
+This tool outputs some basic information about locale settings in the OS and
+what they end up being mapped to in Haskell. If you are looking for help,
+please, provide the output of this tool, or if you are helping someone,
+ask them to run this tool and provide the output.
 
 ## Contributing
 
diff --git a/app/utf8-troubleshoot/Main.hs b/app/utf8-troubleshoot/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/utf8-troubleshoot/Main.hs
@@ -0,0 +1,101 @@
+-- SPDX-FileCopyrightText: 2020 Serokell <https://serokell.io/>
+--
+-- SPDX-License-Identifier: MPL-2.0
+
+{-# LANGUAGE LambdaCase #-}
+
+module Main (main) where
+
+import Prelude hiding (print, putStr, putStrLn)
+
+import Data.Version (showVersion)
+import GHC.IO.Encoding (getLocaleEncoding, initLocaleEncoding)
+import GHC.Show (showLitString)
+import System.Directory (doesDirectoryExist, doesPathExist, listDirectory)
+import System.Environment (lookupEnv)
+import System.Info (arch, compilerName, compilerVersion, os)
+import System.IO (hGetEncoding, stderr, stdout)
+
+
+import qualified Prelude as P
+
+
+-- | Encode a 'String' to be safe to print in ASCII-only.
+protect :: String -> String
+protect s = showLitString s ""
+
+
+putStr :: String -> IO ()
+putStr = P.putStr . protect
+
+putStrLn :: String -> IO ()
+putStrLn = P.putStrLn . protect
+
+showEnvVar :: String -> IO ()
+showEnvVar name = do
+  putStr $ "  * " <> name <> " "
+  lookupEnv name >>= \case
+    Nothing -> putStrLn "is not set"
+    Just v -> putStrLn $ "= " <> v
+
+
+showSystem :: IO ()
+showSystem = do
+    putStrLn "# System"
+    putStrLn $ "  * OS = " <> os
+    putStrLn $ "  * arch = " <> arch
+    putStrLn $ "  * compiler = "
+            <> compilerName <> " " <> showVersion compilerVersion
+    showEnvVar "TERM"
+
+showGhc :: IO ()
+showGhc = do
+    putStrLn "# GHC"
+    putStrLn $ "  * initLocaleEncoding = " <> show initLocaleEncoding
+    getLocaleEncoding >>= \e -> putStrLn $ "  * locale encoding = " <> show e
+    hGetEncoding stdout >>= \e -> putStrLn $ "  * stdout = " <> show e
+    hGetEncoding stderr >>= \e -> putStrLn $ "  * stderr = " <> show e
+
+showEnv :: IO ()
+showEnv = do
+    putStrLn "# Environment"
+    mapM_ showEnvVar
+      [ "LANG"
+      , "LC_COLLATE"
+      , "LC_CTYPE"
+      , "LC_MESSAGES"
+      , "LC_MONETARY"
+      , "LC_NUMERIC"
+      , "LC_TIME"
+      , "LC_ALL="
+      ]
+
+showLocaleArchive :: IO ()
+showLocaleArchive = do
+    putStrLn "# Locale archive"
+    lookupEnv "LOCPATH" >>= \case
+      Nothing -> listDir localePath
+      Just p
+        | p == localePath -> listDir localePath
+        | otherwise -> listDir p *> listDir localePath
+  where
+    localePath :: FilePath
+    localePath = "/usr/share/locale"
+
+    listDir :: FilePath -> IO ()
+    listDir path = doesPathExist path >>= \case
+      False -> putStrLn $ "  * " <> path <> " does not exist."
+      True -> doesDirectoryExist path >>= \case
+        False -> putStrLn $ "  * " <> path <> " is not a directory."
+        True -> do
+          putStrLn $ "  * " <> path <> ":"
+          listDirectory path >>= mapM_ (\item ->
+            putStrLn $ "    * " <> item)
+
+
+main :: IO ()
+main = do
+  showSystem
+  showGhc
+  showEnv
+  showLocaleArchive
diff --git a/with-utf8.cabal b/with-utf8.cabal
--- a/with-utf8.cabal
+++ b/with-utf8.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 9386db1f384343c819e3ea257cc30e49b04d6d410978363c12d47d6e027182a8
+-- hash: adea88526f74ca2b9e81b219c5f63273f4dbfb0439eab0a2ddff978600294100
 
 name:           with-utf8
-version:        1.0.0.0
+version:        1.0.1.0
 synopsis:       Get your IO right on the first try
 description:    This minimalistic library helps you navigate the world of text encodings
                 avoiding @invalid argument (invalid byte sequence)@
@@ -50,9 +50,21 @@
       lib
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
   build-depends:
-      base >=4.10 && <4.14
+      base >=4.10 && <4.15
     , safe-exceptions >=0.1 && <0.2
     , text >=0.7 && <1.3
+  default-language: Haskell2010
+
+executable utf8-troubleshoot
+  main-is: Main.hs
+  other-modules:
+      Paths_with_utf8
+  hs-source-dirs:
+      app/utf8-troubleshoot
+  ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
+  build-depends:
+      base
+    , directory
   default-language: Haskell2010
 
 test-suite with-utf8-test
