MINOR: tasks/debug: add some extra controls of use-after-free in DEBUG_TASK

It's pretty easy to pre-initialize the index, change it on free() and check
it during the wakeup, so let's do this to ease detection of any accidental
task_wakeup() after a task_free() or tasklet_wakeup() after a tasklet_free().
If this would ever happen we'd then get a backtrace and a core now. The
index's parity is respected so that the call history remains exploitable.
diff --git a/include/haproxy/task.h b/include/haproxy/task.h
index abe923d..f774ba2 100644
--- a/include/haproxy/task.h
+++ b/include/haproxy/task.h
@@ -196,6 +196,8 @@
 	while (!(state & (TASK_RUNNING | TASK_QUEUED))) {
 		if (_HA_ATOMIC_CAS(&t->state, &state, state | TASK_QUEUED)) {
 #ifdef DEBUG_TASK
+			if ((unsigned int)t->debug.caller_idx > 1)
+				ABORT_NOW();
 			t->debug.caller_idx = !t->debug.caller_idx;
 			t->debug.caller_file[t->debug.caller_idx] = file;
 			t->debug.caller_line[t->debug.caller_idx] = line;
@@ -349,6 +351,8 @@
 
 	/* at this point we're the first ones to add this task to the list */
 #ifdef DEBUG_TASK
+	if ((unsigned int)tl->debug.caller_idx > 1)
+		ABORT_NOW();
 	tl->debug.caller_idx = !tl->debug.caller_idx;
 	tl->debug.caller_file[tl->debug.caller_idx] = file;
 	tl->debug.caller_line[tl->debug.caller_idx] = line;
@@ -439,6 +443,9 @@
 	t->cpu_time = 0;
 	t->lat_time = 0;
 	t->expire = TICK_ETERNITY;
+#ifdef DEBUG_TASK
+	t->debug.caller_idx = 0;
+#endif
 	return t;
 }
 
@@ -453,6 +460,9 @@
 	t->state = 0;
 	t->process = NULL;
 	t->tid = -1;
+#ifdef DEBUG_TASK
+	t->debug.caller_idx = 0;
+#endif
 	LIST_INIT(&t->list);
 }
 
@@ -495,6 +505,13 @@
 		__ha_barrier_store();
 	}
 	BUG_ON(task_in_wq(t) || task_in_rq(t));
+
+#ifdef DEBUG_TASK
+	if ((unsigned int)t->debug.caller_idx > 1)
+		ABORT_NOW();
+	t->debug.caller_idx |= 2; // keep parity and make sure to crash if used after free
+#endif
+
 	pool_free(pool_head_task, t);
 	if (unlikely(stopping))
 		pool_flush(pool_head_task);
@@ -532,6 +549,11 @@
 	if (MT_LIST_DEL((struct mt_list *)&tl->list))
 		_HA_ATOMIC_SUB(&tasks_run_queue, 1);
 
+#ifdef DEBUG_TASK
+	if ((unsigned int)tl->debug.caller_idx > 1)
+		ABORT_NOW();
+	tl->debug.caller_idx |= 2; // keep parity and make sure to crash if used after free
+#endif
 	pool_free(pool_head_tasklet, tl);
 	if (unlikely(stopping))
 		pool_flush(pool_head_tasklet);