diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp
--- a/compiler-rt/lib/asan/asan_allocator.cpp
+++ b/compiler-rt/lib/asan/asan_allocator.cpp
@@ -745,6 +745,9 @@
   // -------------------------- Chunk lookup ----------------------
 
   // Assumes alloc_beg == allocator.GetBlockBegin(alloc_beg).
+  // Returns nullptr if AsanChunk is not yet initialized just after
+  // get_allocator().Allocate(), or is being destroyed just before
+  // get_allocator().Deallocate().
   AsanChunk *GetAsanChunk(void *alloc_beg) {
     if (!alloc_beg)
       return nullptr;
@@ -756,7 +759,7 @@
     uptr *alloc_magic = reinterpret_cast<uptr *>(alloc_beg);
     if (alloc_magic[0] == kAllocBegMagic)
       return reinterpret_cast<AsanChunk *>(alloc_magic[1]);
-    // FIXME: This is either valid small chunk with tiny redzine or invalid
+    // FIXME: This is either valid small chunk with tiny redzone or invalid
     // chunk which is beeing allocated/deallocated. The latter case should
     // return nullptr like secondary allocator does.
     return reinterpret_cast<AsanChunk *>(alloc_beg);
@@ -1112,26 +1115,17 @@
 
 uptr GetUserBegin(uptr chunk) {
   __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(chunk);
-  if (!m) {
-    Printf(
-        "ASAN is about to crash with a CHECK failure.\n"
-        "The ASAN developers are trying to chase down this bug,\n"
-        "so if you've encountered this bug please let us know.\n"
-        "See also: https://github.com/google/sanitizers/issues/1193\n"
-        "Internal ref b/149237057\n"
-        "chunk: %p caller %p __lsan_current_stage %s\n",
-        chunk, GET_CALLER_PC(), __lsan_current_stage);
-    GetUserBeginDebug(chunk);
-  }
-  CHECK(m);
-  return m->Beg();
+  return m ? m->Beg() : 0;
 }
 
 LsanMetadata::LsanMetadata(uptr chunk) {
-  metadata_ = reinterpret_cast<void *>(chunk - __asan::kChunkHeaderSize);
+  metadata_ =
+      chunk ? reinterpret_cast<void *>(chunk - __asan::kChunkHeaderSize) : 0;
 }
 
 bool LsanMetadata::allocated() const {
+  if (!metadata_)
+    return false;
   __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
   return atomic_load(&m->chunk_state, memory_order_relaxed) ==
          __asan::CHUNK_ALLOCATED;
diff --git a/compiler-rt/test/asan/TestCases/lsan_crash.cpp b/compiler-rt/test/asan/TestCases/lsan_crash.cpp
new file mode 100644
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/lsan_crash.cpp
@@ -0,0 +1,31 @@
+// RUN: %clangxx_asan -O2 %s -o %t && %run %t
+
+#include <atomic>
+#include <memory>
+#include <sanitizer/lsan_interface.h>
+#include <thread>
+#include <vector>
+
+std::atomic<bool> done;
+
+void foo() {
+  std::unique_ptr<char[]> mem;
+
+  while (!done)
+    mem.reset(new char[1000000]);
+}
+
+int main() {
+  std::vector<std::thread> threads;
+  for (int i = 0; i < 10; ++i)
+    threads.emplace_back(foo);
+
+  for (int i = 0; i < 100; ++i)
+    __lsan_do_recoverable_leak_check();
+
+  done = true;
+  for (auto &t : threads)
+    t.join();
+
+  return 0;
+}