4.3 Prozesse und Prozesszustände analysieren Ein Betriebssystemdienst wird letztlich durch einen oder mehrere Prozesse ausgeführt. Auch wenn die Dienstverwaltung den Zustand „läuft“ meldet, kann der zugehörige Prozess blockiert sein, ungewöhnlich viele Ressourcen verbrauchen oder fortlaufend beendet und neu gestartet werden. Grundsatz: Ein vorhandener Prozess beweist nur, dass eine Prozessinstanz existiert. Er beweist nicht, dass der Dienst Anfragen korrekt verarbeitet. Ziele dieser Seite Nach dieser Seite sollst du: einen Dienst seinem Prozess zuordnen können, PID und Elternprozess bestimmen können, Benutzerkonto, Startzeit und Befehlszeile prüfen können, CPU- und Speicherverbrauch richtig bewerten können, Prozesszustände unter Windows, Linux und macOS einordnen können, Zombies und blockierte Prozesse erkennen können, Prozessneustarts und wechselnde PIDs feststellen können, Threads, Handles und geöffnete Dateien prüfen können, Diagnoseinformationen vor einer Prozessbeendigung sichern können. 1. Dienst, Prozess, Thread und PID unterscheiden Begriff Bedeutung Dienst Vom Betriebssystem verwaltete Hintergrundfunktion Prozess Laufende Instanz eines Programms PID Eindeutige Prozess-ID innerhalb des aktuell laufenden Systems PPID PID des Elternprozesses Thread Ausführungsstrang innerhalb eines Prozesses Handle Windows-Verweis auf eine verwendete Systemressource Dateideskriptor Unix-Verweis auf Datei, Socket, Pipe oder andere Ressource Elternprozess Prozess, der einen anderen Prozess erzeugt hat Kindprozess Von einem anderen Prozess erzeugter Prozess Prozessbaum Hierarchische Darstellung von Eltern- und Kindprozessen Ein Dienst kann: genau einen Prozess verwenden, mehrere Prozesse starten, Kindprozesse erzeugen, mehrere Dienste in einem gemeinsamen Prozess ausführen, bedarfsgesteuert ohne dauerhaften Prozess arbeiten, nach einem Absturz automatisch eine neue PID erhalten. Eine PID ist nicht dauerhaft. Nach dem Ende eines Prozesses kann dieselbe Nummer später einem anderen Prozess zugewiesen werden. 2. Prozesse unter Windows suchen und anzeigen Die Platzhalter und müssen ersetzt werden. Prozess nach Namen suchen: [RO] Get-Process -Name "" -ErrorAction SilentlyContinue Die Dateiendung .exe wird bei Get-Process -Name normalerweise nicht angegeben. Prozess über die PID suchen: [RO] Get-Process -Id -ErrorAction SilentlyContinue Ausgewählte Prozessinformationen anzeigen: [RO] Get-Process -Id | Select-Object Id, ProcessName, StartTime, CPU, WorkingSet64, PrivateMemorySize64, VirtualMemorySize64, HandleCount, Responding Alle Prozesse nach CPU-Zeit sortieren: [RO] Get-Process | Sort-Object CPU -Descending | Select-Object -First 15 Id, ProcessName, CPU, WorkingSet64 Alle Prozesse nach belegtem Arbeitsspeicher sortieren: [RO] Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 15 Id, ProcessName, WorkingSet64, CPU Klassische Prozessübersicht: [RO] tasklist Bestimmten Prozess mit tasklist suchen: [RO] tasklist /FI "PID eq " Eigenschaften wie StartTime oder Path können bei geschützten Prozessen oder ohne ausreichende Rechte einen Zugriffsfehler verursachen. 3. Dienst einem Windows-Prozess zuordnen Dienstname, Status und PID ermitteln: [RO] Get-CimInstance Win32_Service -Filter "Name=''" | Select-Object Name, DisplayName, State, StartName, ProcessId Alle laufenden Dienste mit ihrer PID anzeigen: [RO] Get-CimInstance Win32_Service | Where-Object State -eq "Running" | Select-Object Name, DisplayName, ProcessId, StartName | Sort-Object ProcessId Alle Dienste innerhalb einer bestimmten PID suchen: [RO] Get-CimInstance Win32_Service -Filter "ProcessId=" | Select-Object Name, DisplayName, State, StartName Erweiterte Dienstabfrage mit sc.exe : [RO] sc.exe queryex "" Dienstinformationen mit Prozessinformationen verbinden: [RO][SENS] $service = Get-CimInstance Win32_Service -Filter "Name=''" Get-CimInstance Win32_Process -Filter "ProcessId=$($service.ProcessId)" | Select-Object ProcessId, ParentProcessId, Name, ExecutablePath, CommandLine Mehrere Windows-Dienste können sich einen gemeinsamen Hostprozess teilen. Das ist beispielsweise bei bestimmten svchost.exe -Instanzen üblich. Deshalb darf nicht allein anhand des Prozessnamens entschieden werden, welcher Dienst betroffen ist. 4. Windows-Prozessdetails mit CIM prüfen Prozessname, Elternprozess, Pfad und Befehlszeile anzeigen: [RO][SENS] Get-CimInstance Win32_Process -Filter "ProcessId=" | Select-Object ProcessId, ParentProcessId, Name, ExecutablePath, CommandLine, CreationDate Elternprozess ermitteln: [RO] $process = Get-CimInstance Win32_Process -Filter "ProcessId=" Get-CimInstance Win32_Process -Filter "ProcessId=$($process.ParentProcessId)" | Select-Object ProcessId, ParentProcessId, Name, CreationDate Direkte Kindprozesse anzeigen: [RO][SENS] Get-CimInstance Win32_Process -Filter "ParentProcessId=" | Select-Object ProcessId, ParentProcessId, Name, CommandLine Anzahl der Threads und Handles prüfen: [RO] Get-Process -Id | Select-Object Id, ProcessName, HandleCount, @{Name="ThreadCount";Expression={$_.Threads.Count}} Ausführungskonto des Prozesses abfragen: [RO][PRIV] Invoke-CimMethod ` -InputObject (Get-CimInstance Win32_Process -Filter "ProcessId=") ` -MethodName GetOwner [SENS] : Befehlszeilen können interne Pfade, Benutzernamen, Serveradressen oder unsicher übergebene Zugangsdaten enthalten. Die Ausgabe darf nicht ungeprüft weitergegeben werden. 5. Prozesse unter Linux suchen und anzeigen Prozess nach Namen suchen: [RO] pgrep -a "" Exakte Übereinstimmung des Prozessnamens verwenden: [RO] pgrep -x -a "" Vollständige Befehlszeile durchsuchen: [RO][SENS] pgrep -f -a "" Bestimmte PID untersuchen: [RO][SENS] ps -p \ -o user,pid,ppid,lstart,etime,stat,%cpu,%mem,rss,vsz,cmd Alle Prozesse ausführlich anzeigen: [RO][SENS] ps -eo user,pid,ppid,lstart,etime,stat,%cpu,%mem,rss,vsz,cmd Nach CPU-Auslastung sortieren: [RO] ps -eo pid,ppid,user,stat,%cpu,%mem,etime,comm \ --sort=-%cpu | head -n 16 Nach residentem Speicher sortieren: [RO] ps -eo pid,ppid,user,stat,%cpu,%mem,rss,etime,comm \ --sort=-rss | head -n 16 Interaktive Prozessübersicht: [RO] top Falls installiert: [RO] htop htop gehört nicht auf jeder Linux-Distribution zur Standardinstallation. 6. Linux-Prozessdetails über das proc-Dateisystem prüfen Linux stellt Prozessinformationen normalerweise unter /proc/ bereit. Ausführbare Datei bestimmen: [RO][PRIV] sudo readlink -f "/proc//exe" Arbeitsverzeichnis anzeigen: [RO][PRIV] sudo readlink -f "/proc//cwd" Prozessstatus anzeigen: [RO][FILE][SENS] cat "/proc//status" Befehlszeile lesbar darstellen: [RO][FILE][SENS] tr '\0' ' ' < "/proc//cmdline" Umgebungsvariablen anzeigen: [RO][FILE][SENS][PRIV] sudo tr '\0' '\n' < "/proc//environ" Grenzwerte des Prozesses anzeigen: [RO][FILE] cat "/proc//limits" Eingehängte Ressourcen des Prozesses anzeigen: [RO][FILE][SENS] cat "/proc//mountinfo" Anzahl geöffneter Dateideskriptoren ermitteln: [RO][PRIV] sudo find "/proc//fd" -mindepth 1 -maxdepth 1 -printf '.' | wc -c /proc//environ kann Kennwörter, Token oder andere geheime Werte enthalten. Diese Abfrage darf nur bei berechtigtem Diagnosebedarf erfolgen. Die Ausgabe gehört nicht ungefiltert in ein Ticket. 7. systemd-Dienst einem Linux-Prozess zuordnen Hauptprozess eines Dienstes anzeigen: [RO] systemctl show "" \ --property=MainPID,ControlPID,ExecMainPID,ExecMainStartTimestamp Prozessbaum der Unit im Status anzeigen: [RO] systemctl status "" --no-pager Prozesse innerhalb der Unit beziehungsweise Control Group anzeigen: [RO] systemd-cgls --unit "" Ressourcennutzung von Control Groups beobachten: [RO] systemd-cgtop Hauptprozess anschließend mit ps untersuchen: [RO][SENS] ps -p \ -o user,pid,ppid,lstart,etime,stat,%cpu,%mem,rss,vsz,cmd Wichtig: MainPID=0 kann bedeuten, dass aktuell kein Hauptprozess vorhanden ist. Eine Unit kann mehrere Prozesse enthalten. Ein Kindprozess kann weiterlaufen, obwohl der ursprüngliche Startprozess bereits beendet wurde. Bei Type=oneshot kann eine erfolgreiche Unit aktiv sein, obwohl kein dauerhafter Prozess läuft. Der systemd-Status der gesamten Unit ist aussagekräftiger als die isolierte Betrachtung nur einer PID. 8. Prozesse unter macOS suchen und anzeigen Prozess nach Namen oder Befehlszeile suchen: [RO][SENS] pgrep -alf "" Exakten Prozessnamen suchen: [RO] pgrep -x "" Bestimmte PID ausführlich anzeigen: [RO][SENS] ps -p \ -o user,pid,ppid,lstart,etime,state,%cpu,%mem,rss,vsz,command Alle Prozesse ausführlich anzeigen: [RO][SENS] ps -axo user,pid,ppid,lstart,etime,state,%cpu,%mem,rss,vsz,command Prozesse nach aktueller CPU-Nutzung sortiert anzeigen: [RO] ps -Arcwwxo pid,ppid,user,state,%cpu,%mem,rss,etime,command Prozesse nach Speicherverbrauch sortiert anzeigen: [RO] ps -Amcwwxo pid,ppid,user,state,%cpu,%mem,rss,etime,command Interaktive Prozessübersicht nach CPU-Nutzung: [RO] top -o cpu Drei Messungen für eine bestimmte PID ausgeben: [RO] top -l 3 -pid \ -stats pid,command,cpu,mem,threads,state,time Bei top -l ist die erste CPU-Messung möglicherweise noch nicht aussagekräftig, weil für eine belastbare Prozentberechnung ein zeitlicher Vergleich benötigt wird. 9. launchd-Dienst einem macOS-Prozess zuordnen Systemweiten launchd-Dienst prüfen: [RO] launchctl print "system/