diff --git a/ChangeLog b/ChangeLog
index 7b09d1904ae32e700b02d5900f42ed3c5fe0d03e..22bc33b9d9cc0006153a20acea67b223f3bb27b3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,11 @@ Changes in version 0.2.1.11-alpha - 2009-01-??
       keys in those obsolete descriptors when building circuits. Bugfix
       on 0.2.0.x. Fixes bug 887.
 
+  o Minor features:
+    - Try to make sure that the version of Libevent we're running with
+      is binary-compatible with the one we built with.  May address bug
+      897 and others.
+
   o Minor bugfixes:
     - Make outbound DNS packets respect the OutboundBindAddress setting.
       Fixes the bug part of bug 798. Bugfix on 0.1.2.2-alpha.
diff --git a/configure.in b/configure.in
index aa59e776a51eaad2cea3449b3bbfc55dbabf1479..8cd44288533135c4efcd0eebd619709f9d3dfb9e 100644
--- a/configure.in
+++ b/configure.in
@@ -264,6 +264,10 @@ LIBS="-levent $TOR_LIB_WS32 $LIBS"
 LDFLAGS="$TOR_LDFLAGS_libevent $LDFLAGS"
 CPPFLAGS="$TOR_CPPFLAGS_libevent $CPPFLAGS"
 AC_CHECK_FUNCS(event_get_version event_get_method event_set_log_callback)
+AC_CHECK_MEMBERS([struct event.min_heap_idx], , ,
+[#include <event.h>
+])
+
 LIBS="$save_LIBS"
 LDFLAGS="$save_LDFLAGS"
 CPPFLAGS="$save_CPPFLAGS"
diff --git a/src/or/config.c b/src/or/config.c
index f733c362f7617f9eb0a20b96de23b358b58bfb35..02b9793737c1d2a44e9fa8e6d78cc2c4aafa4e1d 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -702,10 +702,12 @@ typedef enum {
   /* Note: we compare these, so it's important that "old" precede everything,
    * and that "other" come last. */
   LE_OLD=0, LE_10C, LE_10D, LE_10E, LE_11, LE_11A, LE_11B, LE_12, LE_12A,
-  LE_13, LE_13A, LE_13B, LE_13C, LE_13D,
+  LE_13, LE_13A, LE_13B, LE_13C, LE_13D, LE_13E,
+  LE_140, LE_141, LE_142, LE_143, LE_144, LE_145, LE_146, LE_147, LE_148,
+  LE_1499,
   LE_OTHER
 } le_version_t;
-static le_version_t decode_libevent_version(void);
+static le_version_t decode_libevent_version(const char *v, int *bincompat_out);
 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
 static void check_libevent_version(const char *m, int server);
 #endif
@@ -4741,10 +4743,71 @@ init_libevent(void)
    */
   suppress_libevent_log_msg("Function not implemented");
 #ifdef __APPLE__
-  if (decode_libevent_version() < LE_11B) {
+  if (decode_libevent_version(event_get_version()) < LE_11B) {
     setenv("EVENT_NOKQUEUE","1",1);
   }
 #endif
+
+  /* In libevent versions before 2.0, it's hard to keep binary compatibility
+   * between upgrades, and unpleasant to detect when the version we compiled
+   * against is unlike the version we have linked against. Here's how. */
+#if defined(_EVENT_VERSION) && defined(HAVE_EVENT_GET_VERSION)
+  /* We have a header-file version and a function-call version. Easy. */
+  if (strcmp(_EVENT_VERSION, event_get_version())) {
+    int compat1 = -1, compat2 = -1;
+    int verybad, prettybad ;
+    decode_libevent_version(_EVENT_VERSION, &compat1);
+    decode_libevent_version(event_get_version(), &compat2);
+    verybad = compat1 != compat2;
+    prettybad = (compat1 == -1 || compat2 == -1) && compat1 != compat2;
+
+    log(verybad ? LOG_WARN : (prettybad ? LOG_NOTICE : LOG_INFO),
+        LD_GENERAL, "We were compiled with headers from version %s "
+        "of Libevent, but we're using a Libevent library that says it's "
+        "version %s.", _EVENT_VERSION, event_get_version());
+    if (verybad)
+      log_warn(LD_GENERAL, "This will almost certainly make Tor crash.");
+    else if (prettybad)
+      log_notice(LD_GENERAL, "If Tor crashes, this might be why.");
+    else
+      log_info(LD_GENERAL, "I think these versions are binary-compatible.");
+  }
+#elif defined(HAVE_EVENT_GET_VERSION)
+  /* event_get_version but no _EVENT_VERSION.  We might be in 1.4.0-beta or
+     earlier, where that's normal.  To see whether we were compiled with an
+     earlier version, let's see whether the struct event defines MIN_HEAP_IDX.
+  */
+#ifdef HAVE_STRUCT_EVENT_MIN_HEAP_IDX
+  /* The header files are 1.4.0-beta or later. If the version is not
+   * 1.4.0-beta, we are incompatible. */
+  {
+    if (strcmp(event_get_version(), "1.4.0-beta")) {
+      log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
+               "Libevent 1.4.0-beta header files, whereas you have linked "
+               "against Libevent %s.  This will probably make Tor crash.",
+               event_get_version());
+    }
+  }
+#else
+  /* Our headers are 1.3e or earlier. If the library version is not 1.4.x or
+     later, we're probably fine. */
+  {
+    const char *v = event_get_version();
+    if ((v[0] == '1' && v[2] == '.' && v[3] > '3') || v[0] > '1') {
+      log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
+               "Libevent header file from 1.3e or earlier, whereas you have "
+               "linked against Libevent %s.  This will probably make Tor "
+               "crash.", event_get_version());
+    }
+  }
+#endif
+
+#elif defined(_EVENT_VERSION)
+#warn "_EVENT_VERSION is defined but not get_event_version(): Libevent is odd."
+#else
+  /* Your libevent is ancient. */
+#endif
+
   event_init();
   suppress_libevent_log_msg(NULL);
 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
@@ -4763,44 +4826,60 @@ init_libevent(void)
 #endif
 }
 
-#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
 /** Table mapping return value of event_get_version() to le_version_t. */
 static const struct {
-  const char *name; le_version_t version;
+  const char *name; le_version_t version; int bincompat;
 } le_version_table[] = {
   /* earlier versions don't have get_version. */
-  { "1.0c", LE_10C },
-  { "1.0d", LE_10D },
-  { "1.0e", LE_10E },
-  { "1.1",  LE_11 },
-  { "1.1a", LE_11A },
-  { "1.1b", LE_11B },
-  { "1.2",  LE_12 },
-  { "1.2a", LE_12A },
-  { "1.3",  LE_13 },
-  { "1.3a", LE_13A },
-  { "1.3b", LE_13B },
-  { "1.3c", LE_13C },
-  { "1.3d", LE_13D },
-  { NULL, LE_OTHER }
+  { "1.0c", LE_10C, 1},
+  { "1.0d", LE_10D, 1},
+  { "1.0e", LE_10E, 1},
+  { "1.1",  LE_11,  1 },
+  { "1.1a", LE_11A, 1 },
+  { "1.1b", LE_11B, 1 },
+  { "1.2",  LE_12,  1 },
+  { "1.2a", LE_12A, 1 },
+  { "1.3",  LE_13,  1 },
+  { "1.3a", LE_13A, 1 },
+  { "1.3b", LE_13B, 1 },
+  { "1.3c", LE_13C, 1 },
+  { "1.3d", LE_13D, 1 },
+  { "1.3e", LE_13E, 1 },
+  { "1.4.0-beta", LE_140, 2 },
+  { "1.4.1-beta", LE_141, 2 },
+  { "1.4.2-rc",   LE_142, 2 },
+  { "1.4.3-stable", LE_143, 2 },
+  { "1.4.4-stable", LE_144, 2 },
+  { "1.4.5-stable", LE_145, 2 },
+  { "1.4.6-stable", LE_146, 2 },
+  { "1.4.7-stable", LE_147, 2 },
+  { "1.4.8-stable", LE_148, 2 },
+  { "1.4.99-trunk", LE_1499, 3 },
+  { NULL, LE_OTHER, 0 }
 };
 
 /** Return the le_version_t for the current version of libevent.  If the
  * version is very new, return LE_OTHER.  If the version is so old that it
  * doesn't support event_get_version(), return LE_OLD. */
 static le_version_t
-decode_libevent_version(void)
+decode_libevent_version(const char *v, int *bincompat_out)
 {
-  const char *v = event_get_version();
   int i;
   for (i=0; le_version_table[i].name; ++i) {
     if (!strcmp(le_version_table[i].name, v)) {
+      if (bincompat_out)
+        *bincompat_out = le_version_table[i].bincompat;
       return le_version_table[i].version;
     }
   }
+  if (v[0] != '1' && bincompat_out)
+    *bincompat_out = 100;
+  else if (!strcmpstart(v, "1.4") && bincompat_out)
+    *bincompat_out = 2;
   return LE_OTHER;
 }
 
+#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
 /**
  * Compare the given libevent method and version to a list of versions
  * which are known not to work.  Warn the user as appropriate.
@@ -4814,7 +4893,7 @@ check_libevent_version(const char *m, int server)
   const char *badness = NULL;
   const char *sad_os = "";
 
-  version = decode_libevent_version();
+  version = decode_libevent_version(v, NULL);
 
   /* XXX Would it be worthwhile disabling the methods that we know
    * are buggy, rather than just warning about them and then proceeding
@@ -4888,12 +4967,6 @@ check_libevent_version(const char *m, int server)
   }
 
 }
-#else
-static le_version_t
-decode_libevent_version(void)
-{
-  return LE_OLD;
-}
 #endif
 
 /** Return the persistent state struct for this Tor. */