#!/usr/bin/env bash
# mdev_41885_repro.sh
# Reproduces MDEV-41885: close_connections() may miss a connection thread
# parked/reused in the 10.5+ thread-cache path, causing shutdown to hang.
#
# Assumes a mariadbd server is ALREADY RUNNING, built with the DBUG hook
# already patched in (sql/sql_connect.cc, park/wakeup reuse path):
#
#     delete connect;
#     DBUG_EXECUTE_IF("mdev_41885_delay_register", my_sleep(3000000););
#
# Usage:
#   ./mdev_41885_repro.sh [SOCKET]
#   (prompts if not given)

set -u

SOCKET="${1:-}"
[ -z "$SOCKET" ] && read -rp "Socket path of running server: " SOCKET

echo ""
echo "=== MDEV-41885 repro (running-server mode) ==="

# --- Validate socket ---
if [ ! -S "$SOCKET" ]; then
  echo "FAILED: socket not found at: $SOCKET (is the server actually running?)"
  exit 1
fi

# --- Find a usable client binary on PATH ---
CLIENT=$(command -v mariadb || command -v mysql)
if [ -z "$CLIENT" ]; then
  echo "FAILED: no 'mariadb' or 'mysql' client found on PATH."
  exit 1
fi
echo "[info] Using client: $CLIENT"

# --- Query server for version + pid_file ---
VERSION_STRING=$("$CLIENT" --no-defaults -uroot --socket="$SOCKET" -N -e "SELECT VERSION()" 2>/dev/null)
if [ -z "$VERSION_STRING" ]; then
  echo "FAILED: could not connect to server via socket: $SOCKET"
  exit 1
fi
echo "[check] Server version: $VERSION_STRING"
if ! echo "$VERSION_STRING" | grep -qi 'debug'; then
  echo "FAILED: running server does not appear to be a debug build (no '-debug' in version)."
  exit 1
fi

PIDFILE=$("$CLIENT" --no-defaults -uroot --socket="$SOCKET" -N -e "SHOW VARIABLES LIKE 'pid_file'" 2>/dev/null | awk '{print $2}')
if [ -z "$PIDFILE" ] || [ ! -f "$PIDFILE" ]; then
  echo "FAILED: could not resolve pid_file from server (got: '$PIDFILE')"
  exit 1
fi
SERVER_PID=$(cat "$PIDFILE")
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
  echo "FAILED: pid_file points to PID $SERVER_PID, but no such process is running."
  exit 1
fi
echo "[info] Resolved server PID: $SERVER_PID (from $PIDFILE)"

# --- Confirm debug symbols present in the running binary ---
SERVER_BIN="/proc/$SERVER_PID/exe"
if [ -r "$SERVER_BIN" ]; then
  DBUG_SYMBOL_COUNT=$(strings "$SERVER_BIN" 2>/dev/null | grep -c 'DBUG_EXECUTE_IF\|debug_dbug')
  if [ "$DBUG_SYMBOL_COUNT" -eq 0 ]; then
    echo "FAILED: no DBUG_EXECUTE_IF/debug_dbug symbols found in running binary."
    exit 1
  fi
  echo "    Confirmed debug build (DBUG symbol count: $DBUG_SYMBOL_COUNT)"
else
  echo "WARNING: could not read /proc/$SERVER_PID/exe to verify debug build (continuing anyway)."
fi

echo "=== Using running server, PID $SERVER_PID ==="
echo ""

cleanup() {
  if [ -n "${CONN2_PID:-}" ] && kill -0 "$CONN2_PID" 2>/dev/null; then
    kill -9 "$CONN2_PID" 2>/dev/null
  fi
}
trap cleanup EXIT

echo "[1/5] Arming DBUG sync point mdev_41885_delay_register..."
"$CLIENT" --no-defaults -uroot --socket="$SOCKET" -e \
  "SET GLOBAL debug_dbug='+d,mdev_41885_delay_register'"

echo "[2/5] Connection 1: parking a worker thread..."
"$CLIENT" --no-defaults -uroot --socket="$SOCKET" -e "SELECT 1" > /dev/null

echo "[3/5] Connection 2: reusing parked thread, holding it live with SLEEP(60)..."
"$CLIENT" --no-defaults -uroot --socket="$SOCKET" -e "SELECT SLEEP(60)" > /dev/null 2>&1 &
CONN2_PID=$!

echo "[4/5] Waiting 1s (mid-delay window), then sending SIGTERM..."
sleep 1
kill -TERM "$SERVER_PID"

echo "[5/5] Checking shutdown status after 10s..."
sleep 10

if kill -0 "$SERVER_PID" 2>/dev/null; then
  echo ""
  echo "=== RESULT: HANG REPRODUCED ==="
  echo "Server PID $SERVER_PID is STILL RUNNING 10s after SIGTERM."
  echo "(check the server's own log file for the stalled shutdown sequence)"
  echo "Killing it now for cleanup (kill -9)."
  kill -9 "$SERVER_PID" 2>/dev/null
  EXIT_CODE=1
else
  echo ""
  echo "=== RESULT: NO HANG (clean shutdown) ==="
  EXIT_CODE=0
fi

kill -9 "${CONN2_PID:-0}" 2>/dev/null

exit $EXIT_CODE
