fd refcount debugging
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 5a7180a..65dff84 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -109,12 +109,28 @@
   gpr_free(fd);
 }
 
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__)
+#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
+static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file, int line) {
+  gpr_log(GPR_DEBUG, "FD %d   ref %d %d -> %d [%s; %s:%d]", fd->fd, n, fd->refst, fd->refst + n, reason, file, line);
+#else
+#define REF_BY(fd, n, reason) ref_by(fd, n)
+#define UNREF_BY(fd, n, reason) unref_by(fd, n)
 static void ref_by(grpc_fd *fd, int n) {
+#endif
   GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0);
 }
 
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file, int line) {
+  gpr_atm old;
+  gpr_log(GPR_DEBUG, "FD %d unref %d %d -> %d [%s; %s:%d]", fd->fd, n, fd->refst, fd->refst - n, reason, file, line);
+#else
 static void unref_by(grpc_fd *fd, int n) {
-  gpr_atm old = gpr_atm_full_fetch_add(&fd->refst, -n);
+  gpr_atm old;
+#endif
+  old = gpr_atm_full_fetch_add(&fd->refst, -n);
   if (old == n) {
     close(fd->fd);
     grpc_iomgr_add_callback(fd->on_done, fd->on_done_user_data);
@@ -182,17 +198,31 @@
   fd->on_done = on_done ? on_done : do_nothing;
   fd->on_done_user_data = user_data;
   shutdown(fd->fd, SHUT_RDWR);
-  ref_by(fd, 1); /* remove active status, but keep referenced */
+  REF_BY(fd, 1, "orphan"); /* remove active status, but keep referenced */
   gpr_mu_lock(&fd->watcher_mu);
   wake_all_watchers_locked(fd);
   gpr_mu_unlock(&fd->watcher_mu);
-  unref_by(fd, 2); /* drop the reference */
+  UNREF_BY(fd, 2, "orphan"); /* drop the reference */
 }
 
 /* increment refcount by two to avoid changing the orphan bit */
-void grpc_fd_ref(grpc_fd *fd) { ref_by(fd, 2); }
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+void grpc_fd_ref(grpc_fd *fd, const char *reason, const char *file, int line) { 
+  ref_by(fd, 2, reason, file, line); 
+}
 
-void grpc_fd_unref(grpc_fd *fd) { unref_by(fd, 2); }
+void grpc_fd_unref(grpc_fd *fd, const char *reason, const char *file, int line) { 
+  unref_by(fd, 2, reason, file, line); 
+}
+#else
+void grpc_fd_ref(grpc_fd *fd) { 
+  ref_by(fd, 2); 
+}
+
+void grpc_fd_unref(grpc_fd *fd) { 
+  unref_by(fd, 2); 
+}
+#endif
 
 static void make_callback(grpc_iomgr_cb_func cb, void *arg, int success,
                           int allow_synchronous_callback) {
@@ -316,7 +346,7 @@
   gpr_uint32 mask = 0;
   /* keep track of pollers that have requested our events, in case they change
    */
-  grpc_fd_ref(fd);
+  GRPC_FD_REF(fd, "poll");
 
   gpr_mu_lock(&fd->watcher_mu);
   /* if there is nobody polling for read, but we need to, then start doing so */
@@ -371,7 +401,7 @@
   }
   gpr_mu_unlock(&fd->watcher_mu);
 
-  grpc_fd_unref(fd);
+  GRPC_FD_UNREF(fd, "poll");
 }
 
 void grpc_fd_become_readable(grpc_fd *fd, int allow_synchronous_callback) {