diff --git a/NEWS b/NEWS
index bea7245cf..c89f8ef92 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@ ver 0.21 (not yet released)
 * require GCC 5.0
 
 ver 0.20.16 (not yet released)
+* fix crash in debug build on Haiku and other operating systems
 
 ver 0.20.15 (2018/01/05)
 * queue: fix crash after seek failure
diff --git a/src/thread/Thread.cxx b/src/thread/Thread.cxx
index 3453ab93e..d1f18522f 100644
--- a/src/thread/Thread.cxx
+++ b/src/thread/Thread.cxx
@@ -86,6 +86,10 @@ Thread::ThreadProc(void *ctx) noexcept
 {
 	Thread &thread = *(Thread *)ctx;
 
+#ifndef NDEBUG
+	thread.inside_handle = pthread_self();
+#endif
+
 	thread.Run();
 
 	return nullptr;
diff --git a/src/thread/Thread.hxx b/src/thread/Thread.hxx
index 0cac2314b..822943ac3 100644
--- a/src/thread/Thread.hxx
+++ b/src/thread/Thread.hxx
@@ -41,6 +41,16 @@ class Thread {
 	DWORD id;
 #else
 	pthread_t handle = pthread_t();
+
+#ifndef NDEBUG
+	/**
+	 * This handle is only used by IsInside(), and is set by the
+	 * thread function.  Since #handle is set by pthread_create()
+	 * which is racy, we need this attribute for early checks
+	 * inside the thread function.
+	 */
+	pthread_t inside_handle = pthread_t();
+#endif
 #endif
 
 public:
@@ -62,8 +72,9 @@ public:
 #else
 		return handle != pthread_t();
 #endif
-  }
+	}
 
+#ifndef NDEBUG
 	/**
 	 * Check if this thread is the current thread.
 	 */
@@ -78,9 +89,10 @@ public:
 		   default-constructed values" (comment from
 		   libstdc++) - and if both libstdc++ and libc++ get
 		   away with this, we can do it as well */
-		return pthread_self() == handle;
+		return pthread_self() == inside_handle;
 #endif
 	}
+#endif
 
 	void Start();
 	void Join() noexcept;