]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
sched: Implement SCHED_BUG()
authorDavid Goulet <dgoulet@torproject.org>
Tue, 3 Oct 2017 17:58:22 +0000 (13:58 -0400)
committerDavid Goulet <dgoulet@torproject.org>
Tue, 3 Oct 2017 18:43:09 +0000 (14:43 -0400)
Signed-off-by: David Goulet <dgoulet@torproject.org>
src/or/scheduler.c
src/or/scheduler.h

index 22a9b574ac94e490ceacc0046a5e0712f9d88600..c656c80e9c0a3ffd36b8e409406696dfa7ae0fb7 100644 (file)
@@ -9,6 +9,9 @@
 #define SCHEDULER_KIST_PRIVATE
 #include "scheduler.h"
 #include "main.h"
+#include "buffers.h"
+#define TOR_CHANNEL_INTERNAL_
+#include "channeltls.h"
 
 #include <event2/event.h>
 
@@ -667,6 +670,32 @@ scheduler_channel_wants_writes(channel_t *chan)
   }
 }
 
+/* Log warn the given channel and extra scheduler context as well. This is
+ * used by SCHED_BUG() in order to be able to extract as much information as
+ * we can when we hit a bug. Channel chan can be NULL. */
+void
+scheduler_bug_occurred(const channel_t *chan)
+{
+  char buf[128];
+
+  if (chan != NULL) {
+    const size_t outbuf_len =
+      buf_datalen(TO_CONN(BASE_CHAN_TO_TLS((channel_t *) chan)->conn)->outbuf);
+    tor_snprintf(buf, sizeof(buf),
+                 "Channel %" PRIu64 " in state %s and scheduler state %d."
+                 " Num cells on cmux: %d. Connection outbuf len: %lu.",
+                 chan->global_identifier,
+                 channel_state_to_string(chan->state),
+                 chan->scheduler_state, circuitmux_num_cells(chan->cmux),
+                 outbuf_len);
+  }
+
+  log_warn(LD_BUG, "%s Num pending channels: %d. Channel in pending list: %s",
+           (chan != NULL) ? buf : "No channel in bug context.",
+           smartlist_len(channels_pending),
+           (smartlist_pos(channels_pending, chan) == -1) ? "no" : "yes");
+}
+
 #ifdef TOR_UNIT_TESTS
 
 /*
index 0ec24db931c466a67e74e42b76d171f4f970f3b1..47c98f096ab4074f3da0420fc3c4306f283d73c8 100644 (file)
@@ -143,6 +143,14 @@ MOCK_DECL(void, scheduler_channel_has_waiting_cells, (channel_t *chan));
 /*********************************
  * Defined in scheduler.c
  *********************************/
+
+/* Triggers a BUG() and extra information with chan if available. */
+#define SCHED_BUG(cond, chan) \
+  (PREDICT_UNLIKELY(cond) ? \
+   ((BUG(cond)) ? (scheduler_bug_occurred(chan), 1) : 0) : 0)
+
+void scheduler_bug_occurred(const channel_t *chan);
+
 smartlist_t *get_channels_pending(void);
 MOCK_DECL(int, scheduler_compare_channels,
           (const void *c1_v, const void *c2_v));