Een systeemaanroep (Engels: system call) is de programmatorische manier waarop een computerprogramma (process) een dienst (service) aanvraagt bij de kernel van het besturingssysteem waarop het wordt uitgevoerd. Dit kunnen hardware-gerelateerde diensten zijn (bijvoorbeeld toegang tot een harde schijf), maar ook vragen om nieuwe processen aan te maken en uit te voeren, of communicatie met kernelservices over bijvoorbeeld het plannen van processen. Systeemoproepen vormen een essentiële interface tussen een proces en het besturingssysteem.

Het Unix commando strace registreert alle systeemaanroepen die een proces doet en alle signalen die het proces opvangt. Je kan strace bijvoorbeeld uitvoeren met een ander commando als argument. Dit commando zal door strace uitgevoerd worden en de uitvoer van het commando wordt uitgeschreven naar stdout. Het commando strace zal zelf een overzicht van alle systeemaanroepen die het commando doet, alle signalen die het commando opvangt en de exit status waarmee het commando eindigt uitschrijven op stderr. Voor elke systeemaanroep wordt de naam weergegeven, gevolgd door de argumenten tussen ronde haakjes en de waarde die wordt teruggegeven. De naam van een systeemaanroep bevat zelf nooit ronde haakjes.

Dit is bijvoorbeeld een ingekorte versie van de uitvoer die strace produceert voor het commando echo "Hello, World!":

$ strace echo "Hello, World!"
execve("/bin/echo", ["echo", "Hello, World!"], 0x7fff55675798 /* 29 vars */) = 0
brk(NULL)                               = 0x555e75047000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffe2e778b10) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=90791, ...}) = 0
mmap(NULL, 90791, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f813ea0a000
close(3)                                = 0
…
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x88, 0x12), ...}) = 0
write(1, "Hello, World!\n", 14)         = 14
Hello, World!
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Opgave

Vul het volgende Unix commando aan zodat op stdout een overzicht wordt uitgeschreven van de systeemaanroepen die strace registreert voor het gegeven commando (<commando>). In dit overzicht moeten de namen van alle geregistreerde systeemaanroepen opgelijst worden, voorafgegaan door het aantal keer dat elke systeemaanroep geregistreerd werd. De systeemaanroepen moeten opgelijst worden in dalende volgorde van het aantal registraties. Indien er systeemaanroepen zijn die even vaak geregistreerd werden, dan moeten die in alfabetische volgorde opgelijst worden. Van dit overzicht moeten enkel de eerste tien systeemaanroepen getoond worden.

$ strace <commando> …

Als het commando (<commando>) dat als argument aan strace wordt doorgegeven zelf informatie naar stdout zou uitschrijven, dan mag die informatie niet in het overzicht voorkomen. Het uitschrijven van die informatie moet met andere woorden onderdrukt worden.

Voorbeeld

$ strace echo "Hello, World!" …
      8 mmap
      6 pread64
      5 close
      4 fstat
      4 mprotect
      3 brk
      3 openat
      2 arch_prctl
      1 access
      1 execve

Richtlijnen bij het indienen

Dien enkel het stuk van het commando in dat moet ingevuld worden op de plaats van de drie puntjes (…).