Skip to content

Instantly share code, notes, and snippets.

@MostHated
Created March 23, 2025 00:05
Show Gist options
  • Save MostHated/d441cae73419e116180d5543cd73c8f8 to your computer and use it in GitHub Desktop.
Save MostHated/d441cae73419e116180d5543cd73c8f8 to your computer and use it in GitHub Desktop.
QT Debug for Ubuntu 24.04
#!/usr/bin/env bash
# filepath: qt_debug.sh
APP_PATH="/usr/share/backintime/qt/app.py"
LOG_DIR="$HOME/qt_debug_logs"
TIMEOUT_DURATION=30 # Seconds to wait before killing app
# Create log directory
mkdir -p "$LOG_DIR"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
RESET='\033[0m'
# Track which variables to unset
declare -A vars_to_unset
qt_vars=(
"XDG_RUNTIME_DIR"
"QT_QPA_PLATFORM"
"QT_QPA_PLATFORMTHEME"
"QTWEBENGINE_DICTIONARIES_PATH"
"QT_IM_MODULE"
"QT_ACCESSIBILITY"
"GTK3_MODULES"
"GTK_MODULES"
"WAYLAND_DISPLAY"
"XDG_SESSION_TYPE"
)
# Initialize all to not unset
for var in "${qt_vars[@]}"; do
vars_to_unset[$var]=0
done
# Function to toggle a variable's unset status
toggle_var() {
if [[ ${vars_to_unset[$1]} -eq 0 ]]; then
vars_to_unset[$1]=1
echo -e "${GREEN}Will unset $1${RESET}"
else
vars_to_unset[$1]=0
echo -e "${RED}Will keep $1${RESET}"
fi
}
# Function to run the app with current unset variables
run_app() {
local timestamp=$(date +"%Y%m%d_%H%M%S")
local log_file="$LOG_DIR/qt_debug_$timestamp.log"
local cmd="python3 $APP_PATH"
local unset_cmd=""
echo -e "${BLUE}Running with the following environment:${RESET}"
for var in "${!vars_to_unset[@]}"; do
if [[ ${vars_to_unset[$var]} -eq 1 ]]; then
echo -e "${YELLOW}Unsetting: $var${RESET}"
unset_cmd="$unset_cmd unset $var &&"
else
echo -e "Keeping: $var = ${!var}"
fi
done
echo -e "${BLUE}Starting application...${RESET}"
echo "Command: $unset_cmd $cmd" | tee -a "$log_file"
# Run the command with timeout to prevent hanging
(
eval "$unset_cmd $cmd" >> "$log_file" 2>&1 &
app_pid=$!
# Monitor memory usage and log it
(
while ps -p $app_pid >/dev/null 2>&1; do
mem_usage=$(ps -o rss= -p $app_pid 2>/dev/null)
if [[ -n "$mem_usage" ]]; then
echo "[$(date +"%H:%M:%S")] Memory usage: $((mem_usage/1024)) MB" >> "$log_file"
fi
sleep 2
done
) &
monitor_pid=$!
# Wait for timeout or completion
if ! wait -n $app_pid 2>/dev/null; then
echo -e "${RED}Application crashed or failed to start${RESET}" | tee -a "$log_file"
fi
# Kill the monitoring process
kill $monitor_pid 2>/dev/null
)
echo -e "${GREEN}Test completed. Log saved to: $log_file${RESET}"
echo "Press Enter to continue..."
read
}
# Function to toggle all variables at once
toggle_all() {
local state=$1
for var in "${qt_vars[@]}"; do
vars_to_unset[$var]=$state
done
if [[ $state -eq 1 ]]; then
echo -e "${GREEN}All variables will be unset${RESET}"
else
echo -e "${RED}All variables will be kept${RESET}"
fi
}
# Function to run with root-like environment
run_with_root_env() {
local timestamp=$(date +"%Y%m%d_%H%M%S")
local log_file="$LOG_DIR/qt_debug_root_env_$timestamp.log"
# Save current environment
echo -e "${BLUE}Setting up root-like environment...${RESET}"
# Create a temporary environment with only root-like Qt variables
(
# Unset all QT variables
for var in "${qt_vars[@]}"; do
unset $var
done
# Set only the Qt variables that root has
export QT_QPA_PLATFORMTHEME=qt5ct
echo -e "${GREEN}Running with root-like environment${RESET}"
echo "Environment:" >> "$log_file"
env | grep -i "qt\|gtk\|xdg" >> "$log_file"
python3 $APP_PATH >> "$log_file" 2>&1
)
echo -e "${GREEN}Test completed. Log saved to: $log_file${RESET}"
echo "Press Enter to continue..."
read
}
# Main menu
while true; do
clear
echo -e "${BLUE}=== QT Application Environment Debugger ===${RESET}"
echo -e "${YELLOW}Current Application: $APP_PATH${RESET}"
echo ""
echo "Select an option:"
echo "1) Toggle variables to unset"
echo "2) Run application with current settings"
echo "3) Unset all variables"
echo "4) Keep all variables"
echo "5) Run with root-like environment"
echo "6) Common troubleshooting combinations"
echo "7) View logs"
echo "q) Quit"
echo ""
read -p "Enter choice: " choice
case $choice in
1)
clear
echo -e "${BLUE}Select variables to toggle:${RESET}"
for i in "${!qt_vars[@]}"; do
var=${qt_vars[$i]}
status=${vars_to_unset[$var]}
status_text=$([ $status -eq 1 ] && echo "${GREEN}[UNSET]${RESET}" || echo "${RED}[KEEP]${RESET}")
echo "$((i+1))) $var $status_text (Current: ${!var})"
done
echo "a) Toggle all"
echo "b) Back to main menu"
read -p "Enter choice: " var_choice
if [[ $var_choice == "a" ]]; then
# If any variables are set to keep, toggle all to unset, otherwise toggle all to keep
local all_unset=1
for var in "${qt_vars[@]}"; do
if [[ ${vars_to_unset[$var]} -eq 0 ]]; then
all_unset=0
break
fi
done
if [[ $all_unset -eq 1 ]]; then
toggle_all 0
else
toggle_all 1
fi
elif [[ $var_choice == "b" ]]; then
continue
elif [[ $var_choice -ge 1 && $var_choice -le ${#qt_vars[@]} ]]; then
toggle_var "${qt_vars[$((var_choice-1))]}"
echo "Press Enter to continue..."
read
fi
;;
2)
run_app
;;
3)
toggle_all 1
echo "Press Enter to continue..."
read
;;
4)
toggle_all 0
echo "Press Enter to continue..."
read
;;
5)
run_with_root_env
;;
6)
clear
echo -e "${BLUE}Common troubleshooting combinations:${RESET}"
echo "1) Minimal Qt (unset all Qt variables)"
echo "2) Force X11 (unset Wayland, set DISPLAY)"
echo "3) Basic rendering (no GPU acceleration)"
echo "b) Back to main menu"
read -p "Enter choice: " combo_choice
case $combo_choice in
1)
toggle_all 1
run_app
;;
2)
toggle_all 0
vars_to_unset["WAYLAND_DISPLAY"]=1
vars_to_unset["QT_QPA_PLATFORM"]=1
export QT_QPA_PLATFORM=xcb
echo -e "${GREEN}Set QT_QPA_PLATFORM=xcb (force X11)${RESET}"
run_app
;;
3)
toggle_all 0
export QT_OPENGL=software
export QT_XCB_GL_INTEGRATION=none
echo -e "${GREEN}Set basic rendering options${RESET}"
run_app
unset QT_OPENGL
unset QT_XCB_GL_INTEGRATION
;;
esac
;;
7)
clear
echo -e "${BLUE}Available logs:${RESET}"
ls -lt "$LOG_DIR" | head -n 10
echo ""
read -p "Enter log filename to view (or 'b' to go back): " log_choice
if [[ $log_choice != "b" ]]; then
if [[ -f "$LOG_DIR/$log_choice" ]]; then
less "$LOG_DIR/$log_choice"
else
echo -e "${RED}Log file not found${RESET}"
sleep 2
fi
fi
;;
q|Q)
echo "Exiting..."
exit 0
;;
*)
echo -e "${RED}Invalid option${RESET}"
sleep 1
;;
esac
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment