Immer größere Datenmassen sicher zu speichern ist eine Herausforderung für jede IT-Infrastruktur. Schon mit Gigabit-Ethernet lassen sich aber ... (mehr)

C-Code

Listing 6 zeigt ein kleines C-Programm, das ungefähr das Gleiche macht wie das Perl-Skript vom Anfang. Um es zu kompilieren, geben Sie »cc -o helloworld helloworld.c« ein. Ausführen können Sie es einfach mit »./helloworld« . Wenn Sie es mit »strace -o strace_c.out ./helloworld« starten, sieht das Ergebnis ungefähr so aus wie Listing 7.

Listing 7

Strace von Hello in C

01 execve("./helloworld", ["./helloworld"], [/* 20 vars */]) = 0
02 uname({sys="Linux", node="the.earth.li", ...}) = 0
03 brk(0)                                  = 0x501000
04 access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
05 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2afb0be09000
06 access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
07 open("/etc/ld.so.cache", O_RDONLY)      = 3
08 fstat(3, {st_mode=S_IFREG|0644, st_size=43270, ...}) = 0
09 mmap(NULL, 43270, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2afb0be0b000
10 close(3)                                = 0
11 access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
12 open("/lib/libc.so.6", O_RDONLY)        = 3
13 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\305"..., 640) = 640
14 lseek(3, 624, SEEK_SET)                 = 624
15 read(3, "\4\0\0\0\20\0\0\0\1\0\0\0GNU\0\0\0\0\0\2\0\0\0\6\0\0\0"..., 32) = 32
16 fstat(3, {st_mode=S_IFREG|0755, st_size=1286104, ...}) = 0
17 mmap(NULL, 2344904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2afb0bf0a000
18 mprotect(0x2afb0c02b000, 1161160, PROT_NONE) = 0
19 mmap(0x2afb0c12b000, 98304, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0
20 x121000) = 0x2afb0c12b000
21 mmap(0x2afb0c143000, 14280, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1,
22 0) = 0x2afb0c143000
23 close(3)                                = 0
24 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2afb0c147000
25 mprotect(0x2afb0c12b000, 86016, PROT_READ) = 0
26 arch_prctl(ARCH_SET_FS, 0x2afb0c1476d0) = 0
27 munmap(0x2afb0be0b000, 43270)           = 0
28 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 51), ...}) = 0
29 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2afb0be0b000
30 write(1, "Hello World", 11)             = 11
31 munmap(0x2afb0be0b000, 4096)            = 0
32 exit_group(11)                          = ?

Listing 6

helloworld.c

01 #include<stdio.h>
02
03 main()
04 {
05     printf("Hello World");
06 }

Der Anfang des Logs ähnelt dem des Perl-Beispiels. Es gibt Aufrufe von »execve()« , »uname()« , »access()« für den Linker-Cache »ld.so.cache« , schließlich »mmap()« , »mprotect()« und »munmap()« . Weil das Programm selbst schon ausführbar ist und nicht etwa zur Ausführung des Skripts ein Interpreter gestartet werden muss, fehlt ein Check von User- oder Gruppen-ID. Deshalb gibt es auch keinen Readlink-Aufruf, denn man braucht keinen Interpreter, genauso wenig die ganzen Read-Aufrufe, die den Skript-Code einlesen.

Am Ende ist dann jedoch wieder ein Write-Aufruf zu sehen, der den gewünschten String "Hello World" ausgibt. Der Unterschied ist nur, dass er im Perl-Fall vom Interpreter kommt, der das Skript übersetzt hat, während in der C-Version das Programm selbst beziehungsweise die C-Bibliothek Glibc »write()« aufruft. Außerdem läuft wieder »exit_group()« ab, das im Gegensatz zu »exit()« nicht nur den Prozess beendet, sondern auch alle zugehörigen Threads.

Speichertricks

Ein ziemlich häufig auftretender Systemaufruf ist »mmap()« , der Dateien oder Geräte auf den Hauptspeicher mappt, um damit den Zugriff zu beschleunigen. Listing 7 bietet dafür einige Beispiele, so in Zeile 9. Das erste Argument ist eine Speicheradresse, die dem System mitteilt, wo das Mapping beginnen soll. Eine Null überlässt ihm die Auswahl selbst. Die folgende Zahl gibt die Größe des Speicherbereichs an. Hier entsprechen die 43270 Bytes der Größe der Stat-Struktur im davor erfolgten Fstat-Aufruf.

Die mit »PROT_« beginnenden Flags stehen für die zu vergebenden Rechte, hier nur Lese- und Ausführungsrechte. Die folgenden Flags geben die Art des Mapping an. So legt »MAP_PRIVATE« fest, dass der Speicherbereich nicht mit anderen Anwendungen geteilt werden und Änderungen im Speicher nicht in die Datei zurückfließen sollen.

Das folgende Argument ist wieder der Dateideskriptor, gefolgt vom Offset, der hier 0 ist. Nach dem Aufruf gibt Mmap die Adresse zurück, an der das Mapping startet. Munmap nimmt später diese Adresse entgegen, um den Speicher wieder aufzuräumen.

Ähnliche Artikel

comments powered by Disqus

Artikel der Woche

OpenSSL

Als Protokoll ist SSL/TLS täglich im Einsatz. Mozilla und Google haben kürzlich erklärt, dass mehr als 50 Prozent der HTTP-Verbindungen verschlüsselt aufgebaut werden. Googles Chrome soll ab 2017 sogar vor unverschlüsselten Verbindungen warnen, wenn Sie dort sensible Daten eingeben können. In unserem Security-Tipp werfen wir einen Blick hinter die Kulissen von OpenSSL und zeigen dessen vielfältige Möglichkeiten auf. (mehr)
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Linux-Distro

Welche Linux-Distribution setzen Sie vorwiegend auf dem Server ein?

  • Arch Linux
  • CentOS
  • Debian
  • Fedora
  • openSUSE
  • Oracle Linux
  • Red Hat Enterprise Linux
  • SUSE Linux Enterprise Server
  • Ubuntu
  • andere Linux-Distribution
  • FreeBSD
  • OpenBSD

Google+

Ausgabe /2017

Microsite