Application Force Close Management for macOS
Implement enterprise-grade application force close management across your MacFleet deployment with automated process termination, security validation, troubleshooting diagnostics, and comprehensive fleet-wide application control. This tutorial provides solutions for maintaining system stability while ensuring secure and efficient application process management.
Understanding macOS Application Process Management
macOS provides several methods for process termination:
killall
- Terminate all instances of a named processkill
- Terminate specific processes by PIDpkill
- Pattern-based process termination- Activity Monitor - GUI-based process management
- Force Quit - System-level application termination
Basic Force Close Operations
Simple Force Close
#!/bin/bash
# Basic force close
killall "appname"
Force Close with Verbose Output
#!/bin/bash
# Force close with PID output
killall -v "Notes"
Detailed Process Information
#!/bin/bash
# Get detailed process info without killing
killall -d "appname"
List Available Signals
#!/bin/bash
# List available signals
killall -l "appname"
Force Close with Specific Signal
#!/bin/bash
# Force close with ABRT signal
killall -abrt "Pages"
Enterprise Application Force Close Management System
Comprehensive Process Control Tool
#!/bin/bash
# MacFleet Enterprise Application Force Close Management Tool
# Advanced process termination and application control
# Configuration
CONFIG_FILE="/etc/macfleet/force_close_policy.conf"
LOG_FILE="/var/log/macfleet_force_close.log"
QUARANTINE_DIR="/Library/MacFleet/TerminatedApps"
AUDIT_LOG="/var/log/macfleet_process_audit.log"
# Create directories
mkdir -p "$(dirname "$CONFIG_FILE")" "$(dirname "$LOG_FILE")" "$QUARANTINE_DIR" "$(dirname "$AUDIT_LOG")"
# Default force close management policy
cat > "$CONFIG_FILE" 2>/dev/null << 'EOF' || true
# MacFleet Enterprise Application Force Close Management Policy
# Version: 2.0
# Force Close Policy Enforcement
ENFORCE_FORCE_CLOSE_POLICIES=true
GRACEFUL_TERMINATION_FIRST=true
ESCALATION_TIMEOUT=10
SAVE_WORK_BEFORE_TERMINATION=true
PREVENT_SYSTEM_PROCESS_TERMINATION=true
# Security and Safety
REQUIRE_ADMIN_APPROVAL=false
VALIDATE_PROCESS_LEGITIMACY=true
CHECK_PROCESS_DEPENDENCIES=true
MALWARE_DETECTION_ENABLED=true
SUSPICIOUS_BEHAVIOR_MONITORING=true
# Business Rules
BUSINESS_HOURS_PROTECTION=true
BUSINESS_HOURS_START="09:00"
BUSINESS_HOURS_END="18:00"
CRITICAL_APP_PROTECTION=true
PRODUCTIVITY_APP_MONITORING=true
# Diagnostic and Troubleshooting
DIAGNOSTIC_LOGGING=true
CRASH_REPORT_COLLECTION=true
PERFORMANCE_MONITORING=true
RESOURCE_USAGE_TRACKING=true
HANG_DETECTION_ENABLED=true
# Notification and Communication
USER_NOTIFICATION_ENABLED=true
ADMIN_NOTIFICATION_ENABLED=true
SLACK_WEBHOOK_URL=""
EMAIL_NOTIFICATION_ENABLED=false
FORCE_CLOSE_WARNINGS=true
# Compliance and Audit
AUDIT_ALL_TERMINATIONS=true
COMPLIANCE_REPORTING=true
INCIDENT_DOCUMENTATION=true
ESCALATION_PROCEDURES=true
AUTOMATED_RECOVERY=true
# Recovery and Restart
AUTO_RESTART_CRITICAL_APPS=true
RESTART_DELAY=5
CRASH_RECOVERY_ENABLED=true
STATE_PRESERVATION=true
USER_SESSION_PROTECTION=true
EOF
# Source configuration
source "$CONFIG_FILE" 2>/dev/null || true
# Logging function
log_action() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Audit logging function
audit_log() {
local action="$1"
local process_name="$2"
local result="$3"
local details="$4"
echo "$(date '+%Y-%m-%d %H:%M:%S') - ACTION:$action PROCESS:$process_name RESULT:$result DETAILS:$details USER:$(whoami)" >> "$AUDIT_LOG"
}
# Get comprehensive process information
get_process_info() {
local process_name="$1"
echo "=== Process Information Analysis ==="
# Check if process exists
if ! pgrep -f "$process_name" >/dev/null 2>&1; then
echo "Process not found: $process_name"
return 1
fi
# Get process details
echo "Process Name: $process_name"
# Get PIDs
local pids
pids=$(pgrep -f "$process_name" | tr '\n' ' ')
echo "Process IDs: $pids"
# Get CPU and memory usage
echo "Resource Usage:"
ps -p $(pgrep -f "$process_name" | head -1) -o pid,pcpu,pmem,time,command 2>/dev/null | tail -1
# Get process tree
echo "Process Tree:"
pstree $(pgrep -f "$process_name" | head -1) 2>/dev/null || echo " Process tree not available"
# Get open files
echo "Open Files Count:"
lsof -p $(pgrep -f "$process_name" | head -1) 2>/dev/null | wc -l || echo " Unable to determine"
# Get network connections
echo "Network Connections:"
lsof -i -p $(pgrep -f "$process_name" | head -1) 2>/dev/null | wc -l || echo " 0"
# Check if process is hanging
local cpu_usage
cpu_usage=$(ps -p $(pgrep -f "$process_name" | head -1) -o pcpu= 2>/dev/null | xargs)
if [[ -n "$cpu_usage" ]] && (( $(echo "$cpu_usage < 0.1" | bc -l) )); then
echo "Status: Potentially hung (very low CPU usage)"
else
echo "Status: Active"
fi
}
# Check if process termination is safe
check_termination_safety() {
local process_name="$1"
local force="${2:-false}"
echo "=== Validating Process Termination Safety ==="
# Check if process exists
if ! pgrep -f "$process_name" >/dev/null 2>&1; then
echo "✅ Process not running: $process_name"
return 0
fi
# Prevent system process termination
if [[ "$PREVENT_SYSTEM_PROCESS_TERMINATION" == "true" ]]; then
local system_processes=(
"kernel"
"launchd"
"WindowServer"
"loginwindow"
"SystemUIServer"
"Dock"
"Finder"
"cfprefsd"
"CoreServicesUIAgent"
)
for system_process in "${system_processes[@]}"; do
if [[ "$process_name" == "$system_process" ]]; then
echo "❌ Cannot terminate critical system process: $process_name"
audit_log "TERMINATION_BLOCKED" "$process_name" "SYSTEM_PROCESS" "System process protection active"
return 1
fi
done
fi
# Business hours protection for critical apps
if [[ "$BUSINESS_HOURS_PROTECTION" == "true" && "$force" != "true" ]]; then
local current_hour
current_hour=$(date +%H)
local start_hour
start_hour=$(echo "$BUSINESS_HOURS_START" | cut -d':' -f1)
local end_hour
end_hour=$(echo "$BUSINESS_HOURS_END" | cut -d':' -f1)
if [[ $current_hour -ge $start_hour && $current_hour -lt $end_hour ]]; then
local critical_apps=(
"Microsoft Word"
"Microsoft Excel"
"Microsoft PowerPoint"
"Slack"
"Microsoft Teams"
"Zoom"
"Safari"
"Google Chrome"
)
for critical_app in "${critical_apps[@]}"; do
if [[ "$process_name" == *"$critical_app"* ]]; then
echo "❌ Termination blocked: Critical productivity app during business hours"
audit_log "TERMINATION_BLOCKED" "$process_name" "BUSINESS_HOURS" "Critical app protection during business hours"
return 1
fi
done
fi
fi
# Check for unsaved work
if [[ "$SAVE_WORK_BEFORE_TERMINATION" == "true" ]]; then
echo "⚠️ Checking for unsaved work..."
# Check for document apps with potential unsaved changes
local document_apps=(
"TextEdit"
"Pages"
"Numbers"
"Keynote"
"Microsoft Word"
"Microsoft Excel"
"Microsoft PowerPoint"
)
for doc_app in "${document_apps[@]}"; do
if [[ "$process_name" == *"$doc_app"* ]]; then
echo "📝 Document application detected - attempting to save work"
try_save_work "$process_name"
break
fi
done
fi
# Check process dependencies
if [[ "$CHECK_PROCESS_DEPENDENCIES" == "true" ]]; then
local child_processes
child_processes=$(pgrep -P $(pgrep -f "$process_name" | head -1) 2>/dev/null | wc -l)
if [[ $child_processes -gt 0 ]]; then
echo "⚠️ Process has $child_processes child processes"
if [[ "$force" != "true" ]]; then
echo "❌ Termination blocked: Process has dependencies. Use force option to proceed."
audit_log "TERMINATION_BLOCKED" "$process_name" "DEPENDENCIES" "Process has $child_processes child processes"
return 1
fi
fi
fi
echo "✅ Process termination safety validated"
audit_log "SAFETY_CHECK" "$process_name" "PASSED" "All safety checks passed"
return 0
}
# Try to save work in document applications
try_save_work() {
local process_name="$1"
echo "=== Attempting to Save Work ==="
# Send save command via AppleScript for common applications
local save_commands=(
"osascript -e 'tell application \"System Events\" to keystroke \"s\" using command down'"
"osascript -e 'tell application \"$process_name\" to save every document'"
)
for cmd in "${save_commands[@]}"; do
eval "$cmd" 2>/dev/null || true
sleep 1
done
# Wait a moment for save operations to complete
sleep 3
echo "💾 Save attempt completed"
log_action "Work save attempt completed for $process_name"
}
# Detect suspicious or malware processes
detect_suspicious_process() {
local process_name="$1"
if [[ "$MALWARE_DETECTION_ENABLED" != "true" ]]; then
return 0
fi
echo "=== Suspicious Process Detection ==="
local suspicious_indicators=(
"crypto"
"miner"
"trojan"
"virus"
"malware"
"ransomware"
"keylogger"
"backdoor"
)
# Check process name for suspicious keywords
for indicator in "${suspicious_indicators[@]}"; do
if [[ "$process_name" == *"$indicator"* ]]; then
echo "🚨 Suspicious process detected: $process_name (matches: $indicator)"
log_action "SECURITY ALERT: Suspicious process detected: $process_name"
audit_log "SUSPICIOUS_PROCESS" "$process_name" "DETECTED" "Matches indicator: $indicator"
# Quarantine process information
quarantine_process_info "$process_name"
return 1
fi
done
# Check for unusual resource consumption
local cpu_usage
cpu_usage=$(ps -p $(pgrep -f "$process_name" | head -1) -o pcpu= 2>/dev/null | xargs)
if [[ -n "$cpu_usage" ]] && (( $(echo "$cpu_usage > 80" | bc -l) )); then
echo "⚠️ High CPU usage detected: ${cpu_usage}%"
log_action "High CPU usage detected for $process_name: ${cpu_usage}%"
fi
return 0
}
# Quarantine suspicious process information
quarantine_process_info() {
local process_name="$1"
echo "=== Quarantining Process Information ==="
local quarantine_file="$QUARANTINE_DIR/suspicious_process_$(date +%Y%m%d_%H%M%S).json"
mkdir -p "$QUARANTINE_DIR"
# Gather comprehensive process information
local pid
pid=$(pgrep -f "$process_name" | head -1)
cat > "$quarantine_file" << EOF
{
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"process_name": "$process_name",
"pid": "$pid",
"detection_reason": "suspicious_indicators",
"system_info": {
"hostname": "$(hostname)",
"user": "$(whoami)",
"os_version": "$(sw_vers -productVersion)"
},
"process_details": {
"command_line": "$(ps -p $pid -o command= 2>/dev/null || echo 'unknown')",
"cpu_usage": "$(ps -p $pid -o pcpu= 2>/dev/null || echo 'unknown')",
"memory_usage": "$(ps -p $pid -o pmem= 2>/dev/null || echo 'unknown')",
"start_time": "$(ps -p $pid -o lstart= 2>/dev/null || echo 'unknown')"
}
}
EOF
echo "🔒 Process information quarantined: $quarantine_file"
log_action "Suspicious process information quarantined: $quarantine_file"
}
# Send termination notification
send_termination_notification() {
local process_name="$1"
local operation="$2"
local result="$3"
local reason="$4"
if [[ "$USER_NOTIFICATION_ENABLED" != "true" ]]; then
return 0
fi
echo "=== Sending Termination Notifications ==="
local notification_title="MacFleet Process Management"
local notification_message="Process $operation: $process_name ($result)"
if [[ -n "$reason" ]]; then
notification_message="$notification_message - Reason: $reason"
fi
# Display notification to logged-in users
local logged_users
logged_users=$(who | awk '{print $1}' | sort -u)
for user in $logged_users; do
if [[ -n "$user" ]]; then
sudo -u "$user" osascript -e "display notification \"$notification_message\" with title \"$notification_title\"" 2>/dev/null || true
echo "📱 Notification sent to user: $user"
fi
done
# Slack notification
if [[ -n "$SLACK_WEBHOOK_URL" ]]; then
local slack_payload="{\"text\":\"🖥️ *$(hostname)*: $notification_title\\n$notification_message\"}"
curl -s -X POST -H 'Content-type: application/json' --data "$slack_payload" "$SLACK_WEBHOOK_URL" >/dev/null 2>&1 || true
echo "📢 Slack notification sent"
fi
log_action "Termination notifications sent for $process_name ($operation - $result)"
}
# Enterprise force close with escalation
enterprise_force_close() {
local process_name="$1"
local force="${2:-false}"
local signal="${3:-TERM}"
echo "=== Enterprise Force Close Initiated ==="
if [[ -z "$process_name" ]]; then
echo "❌ Process name required"
return 1
fi
# Get process information
echo "Analyzing process: $process_name"
get_process_info "$process_name"
# Detect suspicious processes
if detect_suspicious_process "$process_name"; then
echo "⚠️ Suspicious process detected - proceeding with caution"
fi
# Safety checks
if ! check_termination_safety "$process_name" "$force"; then
return 1
fi
log_action "ENTERPRISE FORCE CLOSE: Starting termination of $process_name"
audit_log "FORCE_CLOSE" "$process_name" "INITIATED" "Signal: $signal Force: $force"
# Graceful termination first (if enabled)
if [[ "$GRACEFUL_TERMINATION_FIRST" == "true" && "$force" != "true" ]]; then
echo "🔄 Attempting graceful termination first..."
if killall -TERM "$process_name" 2>/dev/null; then
echo "Graceful termination signal sent, waiting ${ESCALATION_TIMEOUT}s..."
sleep "$ESCALATION_TIMEOUT"
# Check if process is still running
if ! pgrep -f "$process_name" >/dev/null 2>&1; then
echo "✅ Process terminated gracefully"
send_termination_notification "$process_name" "graceful termination" "success"
audit_log "FORCE_CLOSE" "$process_name" "SUCCESS" "Graceful termination successful"
return 0
else
echo "⚠️ Graceful termination failed, escalating to force termination"
fi
fi
fi
# Force termination
echo "🚨 Executing force termination..."
case "$signal" in
"TERM")
if killall "$process_name" 2>/dev/null; then
echo "✅ Process force closed successfully with TERM signal"
termination_result="success"
else
echo "❌ Failed to force close process with TERM signal"
termination_result="failed"
fi
;;
"KILL")
if killall -KILL "$process_name" 2>/dev/null; then
echo "✅ Process force killed successfully with KILL signal"
termination_result="success"
else
echo "❌ Failed to force kill process with KILL signal"
termination_result="failed"
fi
;;
"ABRT")
if killall -ABRT "$process_name" 2>/dev/null; then
echo "✅ Process aborted successfully with ABRT signal"
termination_result="success"
else
echo "❌ Failed to abort process with ABRT signal"
termination_result="failed"
fi
;;
*)
if killall -"$signal" "$process_name" 2>/dev/null; then
echo "✅ Process terminated successfully with $signal signal"
termination_result="success"
else
echo "❌ Failed to terminate process with $signal signal"
termination_result="failed"
fi
;;
esac
# Send notifications
send_termination_notification "$process_name" "force close" "$termination_result" "Signal: $signal"
# Auto-restart critical applications if configured
if [[ "$AUTO_RESTART_CRITICAL_APPS" == "true" && "$termination_result" == "success" ]]; then
restart_if_critical "$process_name"
fi
if [[ "$termination_result" == "success" ]]; then
log_action "Process force closed successfully: $process_name"
audit_log "FORCE_CLOSE" "$process_name" "SUCCESS" "Signal: $signal"
return 0
else
log_action "FAILED: Could not force close process: $process_name"
audit_log "FORCE_CLOSE" "$process_name" "FAILED" "Signal: $signal"
return 1
fi
}
# Restart critical applications
restart_if_critical() {
local process_name="$1"
local critical_apps=(
"Finder"
"Dock"
"SystemUIServer"
"Spotlight"
)
for critical_app in "${critical_apps[@]}"; do
if [[ "$process_name" == *"$critical_app"* ]]; then
echo "🔄 Restarting critical application: $critical_app"
log_action "Auto-restarting critical application: $critical_app"
sleep "$RESTART_DELAY"
case "$critical_app" in
"Finder")
open -a Finder &
;;
"Dock")
killall Dock &
;;
"SystemUIServer")
killall SystemUIServer &
;;
"Spotlight")
mdutil -E / &
;;
esac
break
fi
done
}
# Bulk force close operations
bulk_force_close() {
local process_list_file="$1"
local force="${2:-false}"
local signal="${3:-TERM}"
echo "=== Bulk Force Close Operations ==="
if [[ ! -f "$process_list_file" ]]; then
echo "❌ Process list file not found: $process_list_file"
return 1
fi
local success_count=0
local failure_count=0
local total_count=0
while IFS= read -r process_name; do
# Skip empty lines and comments
if [[ -z "$process_name" || "$process_name" == \#* ]]; then
continue
fi
((total_count++))
echo "Processing ($total_count): $process_name"
if enterprise_force_close "$process_name" "$force" "$signal"; then
((success_count++))
else
((failure_count++))
fi
echo "---"
sleep 1 # Brief pause between operations
done < "$process_list_file"
echo "=== Bulk Force Close Summary ==="
echo "Total processes: $total_count"
echo "Successful terminations: $success_count"
echo "Failed terminations: $failure_count"
log_action "Bulk force close completed: $success_count/$total_count successful"
audit_log "BULK_FORCE_CLOSE" "MULTIPLE" "COMPLETED" "Success: $success_count Failed: $failure_count Total: $total_count Signal: $signal"
}
# Hang detection and automatic recovery
detect_and_recover_hangs() {
echo "=== Hang Detection and Recovery ==="
if [[ "$HANG_DETECTION_ENABLED" != "true" ]]; then
echo "Hang detection is disabled"
return 0
fi
local hang_threshold=0.1 # CPU usage below this for extended time indicates hang
local hang_duration=30 # Seconds of low activity to consider hung
# Find processes with very low CPU usage
local potentially_hung
potentially_hung=$(ps -A -o pid,pcpu,time,command | awk -v threshold="$hang_threshold" '$2 < threshold && $2 > 0 {print $1 ":" $4}')
if [[ -n "$potentially_hung" ]]; then
echo "Potentially hung processes detected:"
echo "$potentially_hung" | while IFS=':' read -r pid command; do
echo " PID $pid: $command"
# Check if it's a user application (not system process)
if [[ "$command" == *".app"* ]]; then
local app_name
app_name=$(basename "$command")
echo "🔄 Attempting recovery of hung application: $app_name"
log_action "Hang detected and recovery attempted: $app_name (PID: $pid)"
audit_log "HANG_RECOVERY" "$app_name" "ATTEMPTED" "PID: $pid"
# Try graceful recovery first
kill -USR1 "$pid" 2>/dev/null || true
sleep 5
# If still hanging, force close
if ps -p "$pid" >/dev/null 2>&1; then
enterprise_force_close "$app_name" "true" "TERM"
fi
fi
done
else
echo "No hung processes detected"
fi
}
# Generate comprehensive process management report
generate_process_report() {
local report_file="/Library/MacFleet/Reports/process_management_report_$(date +%Y%m%d_%H%M%S).json"
echo "=== Generating Process Management Report ==="
mkdir -p "$(dirname "$report_file")"
# Count recent operations from audit log
local recent_terminations=0
local recent_hangs=0
local suspicious_processes=0
if [[ -f "$AUDIT_LOG" ]]; then
recent_terminations=$(grep -c "ACTION:FORCE_CLOSE.*RESULT:SUCCESS" "$AUDIT_LOG" 2>/dev/null || echo 0)
recent_hangs=$(grep -c "ACTION:HANG_RECOVERY" "$AUDIT_LOG" 2>/dev/null || echo 0)
suspicious_processes=$(grep -c "ACTION:SUSPICIOUS_PROCESS" "$AUDIT_LOG" 2>/dev/null || echo 0)
fi
# Get current system load
local load_average
load_average=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ',')
# Count running processes
local total_processes
total_processes=$(ps -A | wc -l)
# Create JSON report
cat > "$report_file" << EOF
{
"report_type": "process_management",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"device_info": {
"hostname": "$(hostname)",
"os_version": "$(sw_vers -productVersion)",
"serial_number": "$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F: '{print $2}' | xargs)"
},
"system_status": {
"load_average": "$load_average",
"total_processes": $total_processes,
"recent_terminations": $recent_terminations,
"hang_recoveries": $recent_hangs,
"suspicious_processes_detected": $suspicious_processes
},
"policy_configuration": {
"graceful_termination_first": $GRACEFUL_TERMINATION_FIRST,
"business_hours_protection": $BUSINESS_HOURS_PROTECTION,
"hang_detection_enabled": $HANG_DETECTION_ENABLED,
"malware_detection_enabled": $MALWARE_DETECTION_ENABLED
},
"security_status": {
"system_process_protection": $PREVENT_SYSTEM_PROCESS_TERMINATION,
"suspicious_behavior_monitoring": $SUSPICIOUS_BEHAVIOR_MONITORING,
"audit_enabled": $AUDIT_ALL_TERMINATIONS
}
}
EOF
echo "Process management report saved to: $report_file"
log_action "Process management report generated: $report_file"
}
# Main function with argument handling
main() {
log_action "=== MacFleet Process Management Tool Started ==="
case "${1:-help}" in
"close")
enterprise_force_close "$2" "$3" "$4"
;;
"bulk")
bulk_force_close "$2" "$3" "$4"
;;
"info")
get_process_info "$2"
;;
"detect-hangs")
detect_and_recover_hangs
;;
"report")
generate_process_report
;;
*)
echo "MacFleet Enterprise Application Force Close Management Tool"
echo "Usage: $0 [command] [options]"
echo ""
echo "Commands:"
echo " close [process_name] [force] [signal] - Force close application with safety checks"
echo " bulk [list_file] [force] [signal] - Bulk force close from file list"
echo " info [process_name] - Get detailed process information"
echo " detect-hangs - Detect and recover hung applications"
echo " report - Generate process management report"
echo ""
echo "Signals:"
echo " TERM (default) - Graceful termination signal"
echo " KILL - Immediate termination (cannot be ignored)"
echo " ABRT - Abort with core dump generation"
echo " HUP - Hang up signal"
echo " INT - Interrupt signal"
echo ""
echo "Examples:"
echo " $0 close \"Safari\" - Safe force close of Safari"
echo " $0 close \"Notes\" true KILL - Force kill Notes (bypass safety)"
echo " $0 bulk hung_processes.txt - Bulk close from list"
echo " $0 info \"Google Chrome\" - Get Chrome process information"
echo " $0 detect-hangs - Scan for and recover hung apps"
;;
esac
log_action "=== Process management operation completed ==="
}
# Execute main function
main "$@"
## Advanced Process Management Features
### Intelligent Hang Detection
```bash
#!/bin/bash
# Advanced hang detection with machine learning patterns
detect_application_patterns() {
local process_name="$1"
echo "=== Application Behavior Pattern Analysis ==="
# Monitor CPU and memory usage over time
local cpu_samples=()
local memory_samples=()
for i in {1..10}; do
local pid
pid=$(pgrep -f "$process_name" | head -1)
if [[ -n "$pid" ]]; then
local cpu_usage
local mem_usage
cpu_usage=$(ps -p "$pid" -o pcpu= | xargs)
mem_usage=$(ps -p "$pid" -o pmem= | xargs)
cpu_samples+=("$cpu_usage")
memory_samples+=("$mem_usage")
fi
sleep 2
done
# Analyze patterns
local avg_cpu=0
local cpu_variance=0
for cpu in "${cpu_samples[@]}"; do
avg_cpu=$(echo "$avg_cpu + $cpu" | bc -l)
done
avg_cpu=$(echo "scale=2; $avg_cpu / ${#cpu_samples[@]}" | bc -l)
echo "Average CPU Usage: ${avg_cpu}%"
# Detect hang patterns
if (( $(echo "$avg_cpu < 0.5" | bc -l) )); then
echo "🚨 Pattern indicates potential hang: Very low CPU activity"
return 1
elif (( $(echo "$avg_cpu > 90" | bc -l) )); then
echo "🚨 Pattern indicates potential infinite loop: Sustained high CPU"
return 1
else
echo "✅ Process behavior appears normal"
return 0
fi
}
# Resource leak detection
detect_resource_leaks() {
local process_name="$1"
echo "=== Resource Leak Detection ==="
local pid
pid=$(pgrep -f "$process_name" | head -1)
if [[ -z "$pid" ]]; then
echo "Process not found: $process_name"
return 1
fi
# Check memory growth
local initial_memory
initial_memory=$(ps -p "$pid" -o rss= | xargs)
sleep 60 # Monitor for 1 minute
local final_memory
final_memory=$(ps -p "$pid" -o rss= | xargs)
local memory_growth
memory_growth=$((final_memory - initial_memory))
echo "Memory Growth: ${memory_growth} KB in 60 seconds"
if [[ $memory_growth -gt 50000 ]]; then # More than 50MB growth
echo "🚨 Potential memory leak detected"
log_action "Memory leak detected in $process_name: ${memory_growth}KB growth"
return 1
fi
# Check file descriptor leaks
local open_files
open_files=$(lsof -p "$pid" 2>/dev/null | wc -l)
echo "Open File Descriptors: $open_files"
if [[ $open_files -gt 1000 ]]; then
echo "🚨 Potential file descriptor leak detected"
log_action "File descriptor leak detected in $process_name: $open_files open files"
return 1
fi
echo "✅ No resource leaks detected"
return 0
}
## Important Configuration Notes
### macOS Process Control Commands
- **`killall`** - Terminate all processes by name (case-sensitive)
- **`kill`** - Terminate specific process by PID
- **`pkill`** - Pattern-based process termination
- **Signals** - TERM (graceful), KILL (immediate), ABRT (with core dump)
### Enterprise Integration Points
- **Security Information and Event Management (SIEM)** - Process termination logging
- **Application Performance Monitoring** - Integration with APM platforms
- **Incident Management Systems** - Automated ticket creation for hangs
- **Change Management** - Documentation of process interventions
### Best Practices for Enterprise Process Management
1. **Safety and Validation**
- Always attempt graceful termination before force killing
- Protect critical system processes from accidental termination
- Implement business hours restrictions for productivity applications
- Maintain comprehensive audit trails
2. **User Experience**
- Attempt to save user work before terminating applications
- Provide clear notifications about process terminations
- Auto-restart critical applications when possible
- Minimize disruption during business hours
3. **Security and Monitoring**
- Detect and quarantine suspicious processes
- Monitor for unusual resource consumption patterns
- Implement hang detection and automatic recovery
- Track process behavior for security analysis
4. **Troubleshooting and Diagnostics**
- Collect detailed process information before termination
- Generate crash reports for analysis
- Monitor system performance impact
- Provide comprehensive reporting capabilities
### Troubleshooting Common Issues
- **Process won't terminate** - Escalate through signal hierarchy (TERM → KILL)
- **System stability issues** - Avoid terminating critical system processes
- **Data loss concerns** - Implement work-saving procedures before termination
- **Resource leaks** - Monitor memory and file descriptor usage
- **Hang detection false positives** - Tune detection thresholds based on application behavior
Remember to test process management procedures thoroughly in a controlled environment before implementing across your entire MacFleet to ensure system stability and user productivity.