• Keine Ergebnisse gefunden

Programme - ELF Programme Inhalt Programme, Prozesse, Speicher

N/A
N/A
Protected

Academic year: 2021

Aktie "Programme - ELF Programme Inhalt Programme, Prozesse, Speicher"

Copied!
8
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Foliensatz 7

Programme, Prozesse, Speicher

Inhalt

• Programme

• Prozesse

• Speichermanagement

Programme

• Ein Programm besteht aus Dateien, die Anweisungen für den Prozessor enthalten. Normalerweise haben die Programme keine Dateierweiterung (wie z.B. .exe unter Windows).

• Es gibt auch Bibliotheken – Sammlungen von Anweisungen –, die von Programmen verwendet werden können. Diese Bibliotheken findet man üblicherweise in /lib und /usr/lib und haben die Dateiendung .o oder .so.

• Unix-ähnliche Systeme verwenden meist das ELF-Format für ausführbare Binärprogramme und Bibliotheken.

• Darüber hinaus erlaubt der Linux-Kernel das Ausführen von Textdateien (müssen mit dem sogenannten Shebang beginnen) und durch das binfmt_misc Kernelmodul auch das direkte Ausführen von beliebigen Programmtypen, wie z.B. Java JAR-Dateien.

Programme - ELF

Beispiel ELF-Binärprogramm ls:

$ file /bin/ls

/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24,

BuildID[sha1]=0x214a38d0db472db559f0dabf0ae97f82fea83e03, stripped

$ readelf -h /bin/ls ELF Header:

  Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00   Class: ELF64

  Data: 2's complement, little endian   Version: 1 (current)

  OS/ABI: UNIX - System V   ABI Version: 0

  Type: EXEC (Executable file)

  Machine: Advanced Micro Devices X86-64   Version: 0x1

  Entry point address: 0x4045a4

  Start of program headers: 64 (bytes into file)   Start of section headers: 104048 (bytes into file)

(2)

  Flags: 0x0   ...

Programme - Skripts

• Ein ausführbares Skript muss mit dem sogenannten Shebang beginnen, das ist die Zeichenfolge #!.

Der Rest der Zeile gibt den Pfad zum Programm (und optional Argumente) an, mit dem das Skript ausgeführt werden soll (z.B. /bin/sh, /usr/bin/env ruby, …).

• Dadurch können Skripte transparent und genauso einfach wie echte Binärprogramme ausgeführt werden. Die Shell selbst (Shell-Skripts) und viele Programmiersprachen (z.B. Ruby, Python, Perl, …) verwenden diesen Mechanismus.

• Beispiel für ein ausführbares Skript in der Programmiersprache Ruby:

$ file scripts/hallo_welt.rb

hallo_welt.rb: a ruby script, ASCII text executable

$ cat scripts/hallo_welt.rb

#!/usr/bin/env ruby

puts "Hallo Welt!"

$ scripts/hallo_welt.rb Hallo Welt!

Programme - Andere Binärdateien

• Quelltextdateien einiger Programmiersprachen werden in ein Zwischenformat übersetzt, das nicht direkt auf der CPU ausführbar, dafür aber sehr portabel ist. Zu diesen Programmiersprachen gehört z.B. Java. Dieses Zwischenformat wird dann von einer „virtuellen Maschine“, einem speziellen Binärprogramm, interpretiert (bei Java ist das die JVM).

• Das binfmt_misc Kernelmodul erlaubt das Registrieren solcher Binärformate und damit die transparente Ausführung von Programmen in diesen Formaten.

• Beispiel: Registriertes Java-JAR-Format

$ ls /proc/sys/fs/binfmt_misc/

cli jar python2.7 register status wine

$ cat /proc/sys/fs/binfmt_misc/jar enabled

interpreter /usr/bin/jexec flags:

offset 0 magic 504b0304

$ hexdump -n 4 -e '4/1 "%02X " 1/ "\n"' \

> /usr/lib/jvm/java-7-openjdk-common/jre/lib/charsets.jar 50 4B 03 04

Prozesse

• Ein Prozess ist eine Instanz eines Programms. Es kann daher ein Programm mehrmals gestartet werden und es so mehrere Instanzen eines Programmes gleichzeitig geben. Auch können mehrere verschiedene Programme gleichzeitig ausgeführt werden (Multitasking).

• Zu einem Prozess gehört die Prozessumgebung (auch Prozesskontext genannt), welche unter

(3)

anderem folgende Inhalte umfasst:

• Die Prozess-ID (PID) und die Elternprozess-ID (PPID)

• Ein gewisser Speicherbereich

• Die UID des Besitzers des Prozesses

• Die EUID (effektive UID), welche den Zugang zu Ressourcen regelt

• Die Umgebungsvariablen

• Der Kernel stellt über das proc-Dateisystem Informationen zu jedem Prozess in dem Verzeichnis /proc/PID dar.

Prozesse - Lebenszyklus 1

• Beim Booten des Betriebssystem wird der sogenannte init-Prozess gestartet. Er ist die Wurzel des Prozessbaums.

• Das Starten eines neuen Prozesses funktioniert über das fork-Modell:

• Der aktuelle Prozess benutzt den Systemaufruf fork(), um eine Kopie von sich selbst mit neuer PID und neuer Prozessumgebung anzulegen (manche Inhalte der Prozessumgebung, wie die Umgebungsvariablen, werden vererbt, andere, wie der Speicherbereich, nicht).

• Der aktuelle Prozess (der Elternprozess) bekommt als Rückgabewert des Systemaufrufs die PID des Kindprozesses, der Kindprozess den Wert 0 zurück.

• Der Kindprozess kann jetzt entweder den Code des Elternprozesses weiter ausführen oder neuen Programmcode mittels des Systemaufrufs exec() (oder einer seiner Varianten) ausführen.

Prozesse - Lebenszyklus 2

• Um die Zuordnung eines Kindprozesses zu einem Elternprozess zu gewährleisten, gibt es die Parent PID (PPID). Dadurch entsteht ein Prozessbaum, an dessen Wurzel der init-Prozess steht.

• Wenn ein Prozess beendet wird, endet die Ausführung des Prozesses, aber es bleibt etwas von dem Prozess noch übrig, unter anderem der Rückgabewert. Der Elternprozess ist dafür verantwortlich, auf seine Kindprozesse zu warten (mittels des Systemaufrufs wait() und seiner Varianten).

Terminiert ein Kindprozess und wurde kein wait() ausgeführt, so ist der Kindprozess zu einem Zombieprozess geworden. Solche Zombieprozesse werden nach der Terminierung des Elternprozesses an den init-Prozess übergeben, der automatisch auf sie wartet und sie damit entfernt.

Prozesse - Berechtigungen

• Jeder Prozess hat mehrere, verschiedene UIDs/GIDs (siehe Manpage credentials(7)): die reale, effektive, gespeicherte und (nur unter Linux) Dateisystem-UID/GID.

• Die reale UID/GID beschreibt den Besitzer des Prozesses (üblicherweise der Benutzer, der den Prozess gestartet hat).

• Die effektive UID/GID wird allgemein für Zugriffsrechte benutzt, die Dateisystem-UID/GID für den Zugriff auf Dateien (ist aber fast immer ident mit der effektiven UID/GID).

Ein unpriviligierter Benutzer darf die effektive UID/GID nur auf die reale, effektive oder

(4)

gespeicherte UID/GID setzen!

• In der gespeicherten UID/GID wird die vorherige, effektive UID/GID beim Setzen einer neuen gespeichert.

Das wird unter anderem dazu benutzt, um kurzzeitig (z.B. während sicherheitskritischer Operationen) die effektive UID/GID auf einen unpriviligierten Benutzer zu setzen und danach auf die gespeicherte UID/GID zurückzukehren.

Prozesse - Scheduling, Interrupts und Prioritäten 1

• Da auf einer CPU nicht mehrere Prozesse gleichzeitig ausgeführt werden können, müssen die Prozesse für kurze Zeitabschnitte hintereinander ausgeführt werden.

• Die Hardware kann mittels Interrupts die Ausführung von Prozessen unterbrechen und kurzzeitig die Kontrolle an das Betriebssystem übergeben. Solche Interrupts werden zum Beispiel durch IO- Aktivitäten ausgelöst (Maus, Tastatur, Festplatte, …), aber es gibt auch periodische Interrupts. Das Betriebssystem wertet den Interrupt aus und reicht die Informationen an die entsprechenden Prozesse weiter.

• Ein periodischer Interrupt wird vom Kernel dazu genutzt, um allen Prozessen Rechenzeit gerecht zur Verfügung zu stellen (Scheduling, preemptives Multitasking). Es gibt dabei mehrere auswählbare Strategien, je nachdem ob es sich um ein Serversystem, ein Desktopsystem oder z.B. ein Echtzeitsystem handelt.

Anmerkung: Es gibt auch kooperatives Multitasking, d.h. jeder Prozess muss sich selbst unterbrechen, damit ein anderer Prozess ausgeführt werden kann. Funktionierte das nicht, friert das System ein.

Prozesse - Scheduling, Interrupts und Prioritäten 2

• Um unabhängig vom Scheduling Prozessen mehr oder weniger Rechenzeit zu geben, ist jedem Prozess eine sogenannte Scheduling-Priorität (der nice-Wert) zugeordnet. Diese reicht von -20 bis 20 mit einem Standardwert für normale Benutzer von 0.

• Je negativer die Scheduling-Priorität ist, desto mehr Rechenzeit bekommt der Prozess. Umgekehrt:

je positiver, desto weniger Rechenzeit. Bei eine Scheduling-Priorität von 20 läuft der Prozess praktisch nur mehr dann, wenn kein anderer Prozess Rechenzeit braucht.

• Ein normaler Benutzer kann seine Prozesse nur herabstufen, d.h. ihnen geringere Priorität mittels einem höheren Wert für die Scheduling-Priorität einräumen (er ist freundlicher – nicer – zu anderen Prozessen). Der root-Benutzer darf beliebigen Scheduling-Prioritäten setzen.

• Die Scheduling-Priorität kann entweder beim Starten eines Programmes mit Hilfe von nice festgelegt werden oder im nachhinein mittels renice.

Prozesse - Signale

• Eine Möglichkeit, mit Prozessen zu kommunizieren, ist das Schicken von Signalen. Damit kann man Prozessen z.B. mitteilen, dass sie sich beenden sollen.

• Signale können von einem Prozess abgefangen und verarbeitet/ignoriert werden. Wird nichts davon gemacht, wird die Standardaktion für das Signal ausgeführt.

• Ein Signal hat einen Namen und eine Nummer. Ein Liste aller Signale findet man in der Manpage

(5)

(man 7 signal). Hier ist eine Tabelle der oft benötigten Signale:

Name Nummer Bemerkung

HUP 1 Hangup (Prozess wird beendet) INT 2 Interrupt (Prozess wird beendet)

KILL 9 Prozess beenden (kann nicht abgefangen/ignoriert werden)

TERM 15 Prozess beenden

CONT 18 Gestoppten Prozess wieder starten

STOP 19 Prozess stoppen (kann nicht abgefangen/ignoriert werden)

• Mit Hilfe des Befehls kill werden Signale an Prozesse gesendet.

Hintergrundprozesse in der Bash

• Die Bash hat auch Befehle zur Steuerung von (Kind)Prozessen (genannt Jobs, siehe auch „JOB CONTROL“ in der Manpage). Dabei können Jobs angehalten bzw. wieder gestartet werden und es besteht auch die Möglichkeit, Jobs im Hintergrund laufen zu lassen.

• Der Abschluss eines Befehls mit & lässt den Befehl im Hintergrund laufen. Ein im Vordergrund laufender Prozess kann mit „Strg-z“ angehalten werden (Signal STOP). Es kann natürlich nur ein Prozess im Vordergrund laufen, aber beliebig viele können im Hintergrund laufen oder angehalten sein.

• Alle aktuellen Jobs können über den Befehl jobs angezeigt. Soll ein angehaltener Job fortgesetzt werden, kann er mit dem Befehl bg im Hintergrund, mit dem Befehl fg im Vordergrund fortgesetzt werden. Mit Hilfe von %Job (wobei Job die angezeigte Jobnummer ist) kann ein bestimmter Job angegeben werden.

• Prozesse, die im Hintergrund laufen, können zwar weiterhin auf das Terminal schreiben (abhängig von der „tostop“ Terminal-Einstellung), aber nicht mehr vom Terminal lesen (sobald ein Hintergrundprozess versucht vom Terminal zu lesen, wird vom Kernel das Signal TTIN geschickt und der Prozess angehalten).

Befehle für Prozesse 1 (ps)

ps - Zeigt Prozessinformationen an.

» Viele unterschiedliche Ausgabe- und Prozessselektionsmöglichkeiten, z.B.:

• ps → Informationen zu eigenen Prozessen im aktuellen Terminal

• ps ax → Informationen zu allen Prozessen

• Zusätzlich mit l oder u → Selektion wie oben, nur noch mehr Informationen

» $ ps l

F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 0 1515 2383 2344 20 0 17788 1164 poll_s Ss+ pts/1 0:00 tmux attach

0 1515 2387 2385 20 0 4392 612 wait Ss+ pts/3 0:00 sh -c weechat- curses

0 1515 2388 2385 20 0 32512 13852 wait Ss pts/4 0:00 -bash

0 1515 2389 2387 20 0 344108 37176 poll_s Sl+ pts/3 0:00 weechat-curses

(6)

0 1515 4447 2385 20 0 32472 13764 n_tty_ Ss+ pts/0 0:00 -bash 0 1515 4942 2388 20 0 9744 1044 - R+ pts/4 0:00 ps l

$ ps u

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND thomas 2383 0.0 0.0 17788 1164 pts/1 Ss+ 07:29 0:00 tmux attach

thomas 2387 0.0 0.0 4392 612 pts/3 Ss+ 07:29 0:00 sh -c weechat- curses

thomas 2388 0.0 0.1 32512 13852 pts/4 Ss 07:29 0:00 -bash

thomas 2389 0.0 0.4 344108 37176 pts/3 Sl+ 07:29 0:00 weechat-curses thomas 4447 0.0 0.1 32472 13764 pts/0 Ss+ 08:19 0:00 -bash

thomas 4949 0.0 0.0 18176 1276 pts/4 R+ 08:31 0:00 ps u

Befehle für Prozesse 2 (pstree, kill)

pstree - Zeigt die Prozesshierarchie an.

» Ohne Argument wird vom init-Prozess aus angezeigt, sonst von dem Prozess mit der angegebenen PID.

» Optionen: -p → PID anzeigen, -a → Befehlsargumente anzeigen, -n → numerisch, nicht nach Namen sortieren, -s → Elternprozesse des angegeben Prozesses anzeigen.

» $ pstree -aps $$

init,1

└─tmux,2385 attach     └─bash,2388

        └─pstree,5329 -aps 2388

kill - Sendet ein Signal an einen oder mehrere Prozesse.

» Signale können entweder über die Nummer oder den Namen angegeben werden.

» Prozesse werden über die PID angegeben.

» Nur eine Option wichtig: -signal (also z.B. numerisch -9 oder mit Namen -KILL)

» $ kill -9 2389

Befehle für Prozesse 3 (pgrep, pkill, top)

pgrep, pkill - Sucht Prozesse oder schickt ihnen ein Signal.

» Gesucht wird nach Prozessen, auf deren Namen der reguläre Ausdruck passt.

» Optionen: -f → Die gesamte Kommandozeile eines Befehls verwenden, nicht nur den Namen, -u → Nur Prozesse mit der angegebenen effektiven UID

» $ pgrep bash 2388

4447

$ pkill -9 bash

top - Zeigt Prozesse interaktiv an.

» Zeigt alle Prozesse an und aktualisiert die Liste laufend.

» Mit Hilfe von < und > kann man die Sortierung ändern, R dreht die Sortierreihenfolge um, q beendet man das Programm, h zeigt die Hilfe an.

Befehle für Prozesse 4 (nice, renice)

nice - Programm mit anderer Scheduling-Priorität laufen lassen.

» Argumente sind der Programmname und die Parameter für das Programm.

» Option -n gibt die Änderung in Relation zur aktuellen Priorität an (default 10).

» Ohne Optionen und Argumente wird die aktuelle Priorität ausgegeben.

(7)

» $ nice 0

$ nice nice 10

$ nice -n 3 nice 3

$ nice -n -3 nice

nice: cannot set niceness: Permission denied 0

renice - Scheduling-Priorität laufender Programme ändern.

» Erstes Argument (mit optionalen -n davor) ist die neue Priorität, danach kommen die PIDs.

» $ sleep 10 &

[1] 5727

$ renice 10 5727

5727 (process ID) old priority 0, new priority 10

Speichermanagement 1

• Der Arbeitsspeicher (RAM) wird vom Kernel verwaltet und den Prozessen zugeteilt. Dabei benutzt der Kernel das Konzept eines virtuellen Speichers.

Virtuelle Speicheradressen werden von der CPU mit Unterstützung des Kernels auf physische Adressen abgebildet, damit die CPU direkt mit ihnen umgehen kann. Falls einer virtuellen Speicheradresse noch keine physische zugeordnet ist, informiert die CPU durch einen page fault (ein spezieller Interrupt) den Kernel, der die Daten dann in den physischen Speicher lädt.

• Beim Starten eines Programmes, wird der Prozess in den Arbeitsspeicher geladen, der viel schneller als permanente Medien wie Festplatten ist. Der Kernel reserviert dabei einen genügend großen Bereich für den Prozess.

• Jeder Prozess glaubt, den ganzen Speicher für sich alle zu haben, und für den Prozess spielt es keine Rolle, wo seine Daten im physischen Speicher geladen sind bzw. ob sie überhaupt schon geladen sind.

• Gemeinsam benutzte Ressourcen wie Bibliotheken oder der Programmcode von einem Programm, das mehrmals gestartet worden ist, werden einmal geladen und die Prozesse greifen transparent durch den virtuellen Speicherbereich darauf zu.

Speichermanagement 2

• Der Kernel kann auch nicht benötigten Speicher auf die Festplatte in eine Swap-Partition oder Swap-Datei auslagern. Sobald der Speicher wieder benötigt wird (angezeigt durch einen page fault), lädt der Kernel diesen Speicher wieder.

• Zusätzlich benutzt der Kernel den freien physischen Arbeitsspeicher zum Zwischenspeichern (cachen) von schon einmal geladenen Daten von der Festplatte und anderen Daten. Damit ist der wiederholte Zugriff auf diese Daten viel schneller.

• Durch das Benutzen eines virtuellen Speicherbereichs erhöht sich auch die Sicherheit, weil Prozesse nicht außerhalb davon Speicher manipulieren können.

(8)

Befehle für Speichermanagement (free, swapon, swapoff)

free - Zeigt den freien und benutzten Speicher an.

» Optionen: -b/-k/-m/-g → Anzeige in Byte, Kilobyte (default), Megabyte oder Gigabyte

» $ free

       total used free shared buffers cached Mem: 7969624 3488688 4480936 0 291712 1172900 -/+ buffers/cache: 2024076 5945548

Swap: 3905532 0 3905532

swapon, swapoff - Aktiviert bzw. deaktiviert Swap-Speicher.

» Nur der root-Benutzer kann Änderungen vornehmen.

» Option -s von swapon zeigt die aktuellen Swap-Speicher an.

» $ swapon -s

Filename Type Size Used Priority /dev/sda5 partition 3905532 0 -1

$ sudo swapoff /dev/sda5

$ swapon -s

Filename Type Size Used Priority

$ sudo swapon /dev/sda5

Copyright und Lizenz

• Copyright: Thomas Leitner thomas.leitner@univie.ac.at

• Basiert teilweise auf den Folien von Harald Schilly harald.schilly@univie.ac.at

• Lizenz: Creative Commons CC BY-NC-SA

„Namensnennung-Keine kommerzielle Nutzung-Weitergabe unter gleichen Bedingungen 3.0 Österreich.“ - http://creativecommons.org/licenses/by-nc-sa/3.0/at/

Referenzen

ÄHNLICHE DOKUMENTE

Déplacement du Palais de l’Alcazar à l’Audiorama pour l’échange d’expériences des Cités de l’énergie Départ du bus spécial pour la gare de Montreux pour ceux qui

Les mesures doivent contribuer à faire tomber les obstacles chez les installateurs et les consommateurs finaux grâce à des campagnes d’information et de communica- tion appropriées

❙ (Asymptotische) Komplexität von Algorithmen.

Pour autant qu'elle reste simultanement attentive au temps et a l'espace, la geographie sait bien que dans les periodes de mutations profondes, le vieux et le neuf sont et

*/ begrenzt /* Das ist ein längerer - können über mehrere Zeilen gehen Kommentar, der über - dürfen nicht geschachtelt werden mehrere Zeilen geht */.. -

Die Moderatorinnen des Workshops (Prof. Ellen Euler, Prof. Antje Michel und Prof. Heike Neuroth) sind alle relativ neu an der FHP und engagieren sich in

Erhard Hinrichs, Germany Sandra Kübler, USA Jonas Kuhn, Germany Anna Kup´s´c, France Anke Lüdeling, Germany Simonetta Montemagni, Italy Petya Osenova, Bulgaria Kiril Simov,

2 ) kui on antud ainult long-marker, siis konstandi tüüp on long int juhul, kui tema väärtus kuulub vastava tüübi väärtuste hulka ja unsigned long int vastasel