Log Qt callback queue drops to error log

ober

63c767fff748c034095c961db28a4387c7d3fe33

diff --git a/support/vendor-overrides/qt_chez_shim.c b/support/vendor-overrides/qt_chez_shim.c
index fb120d9..f0b21fa 100644
--- a/support/vendor-overrides/qt_chez_shim.c
+++ b/support/vendor-overrides/qt_chez_shim.c
@@ -46,11 +46,34 @@ static _Atomic unsigned int cb_head = 0;  /* written by producer (Qt thread) */
 static _Atomic unsigned int cb_tail = 0;  /* written by consumer (primordial) */
 static _Atomic unsigned int cb_dropped = 0;
 
+static void cb_log_drop_to_file(unsigned int n) {
+    const char *home = getenv("HOME");
+    char path[4096];
+    int wrote;
+
+    if (home && home[0] != '\0') {
+        wrote = snprintf(path, sizeof(path), "%s/.jemacs-errors.log", home);
+    } else {
+        wrote = snprintf(path, sizeof(path), "/tmp/.jemacs-errors.log");
+    }
+    if (wrote < 0 || (size_t)wrote >= sizeof(path)) {
+        return;
+    }
+
+    FILE *fp = fopen(path, "a");
+    if (!fp) {
+        return;
+    }
+    fprintf(fp, "jemacs: Qt callback queue full; dropped %u callback(s)\n", n);
+    fclose(fp);
+}
+
 static inline void cb_note_drop(void) {
     unsigned int n = atomic_fetch_add_explicit(&cb_dropped, 1, memory_order_relaxed) + 1;
     if (n == 1 || (n & (n - 1)) == 0) {
         fprintf(stderr, "jemacs: Qt callback queue full; dropped %u callback(s)\n", n);
         fflush(stderr);
+        cb_log_drop_to_file(n);
     }
 }