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

Skalierbares Monitoring mit Prometheus

Klassischen Monitoring-Lösungen geht die Puste aus, wenn sie mit den Anforderungen moderner, skalierbarer Setups konfrontiert sind. Prometheus tritt an, in solchen Umgebungen Monitoring, Alerting und Trending zu verwirklichen. (mehr)
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Linux-Backup

Welche Backup-Lösung setzen Sie für Linux im professionellen Umfeld ein?

  • keine
  • eigene Scripts
  • rsnapshot
  • rdiff-backup
  • Bacula
  • Bareos
  • Borg
  • Duplicity
  • Amanda
  • Burp
  • Clonezilla
  • Acronis
  • Arkeia
  • SEP sesam
  • Veeam
  • Redo Backup
  • Relax-and-Recover
  • andere kommerzielle Software
  • andere Open-Source-Software

Google+

Ausgabe /2017

Microsite