Πραγματική Έγχυση Σφαλμάτων Πυρήνα: Μια Βιβλιοθήκη Χάους C99 LD_PRELOAD για Οποιαδήποτε Διαδικασία
Μηχανική category.testing June 26, 2026

Πραγματική Έγχυση Σφαλμάτων Πυρήνα: Μια Βιβλιοθήκη Χάους C99 LD_PRELOAD για Οποιαδήποτε Διαδικασία

Έξι τομείς σφαλμάτων, μηδέν αλλαγές κώδικα εφαρμογής, οποιοδήποτε δυαδικό αρχείο ELF. Μια βιβλιοθήκη χάους C99 που παρεμβάλλεται στις κλήσεις libc στο επίπεδο του δυναμικού συνδέσμου — παρέχοντας πραγματικά σφάλματα πυρήνα σε Java, Go, Python, Node.js και ό,τι άλλο υπάρχει στη μέση.

E
Engineering Team
Senior Solutions Architects
16 λεπτά ανάγνωσης

Το Πρόβλημα με την Προσομοίωση Κλήσεων Συστήματος

Οι βιβλιοθήκες έγχυσης σφαλμάτων χωρίζονται σε δύο μεγάλες κατηγορίες. Η πρώτη κατηγορία κάνει προσομοίωση στο επίπεδο της εφαρμογής: προσομοιώνει ένα αποθετήριο, προσομοιώνει έναν HTTP client, επιστρέφει μια εξαίρεση. Καθαρό. Γρήγορο. Και εντελώς αποκομμένο από αυτό που κάνει το πραγματικό λειτουργικό περιβάλλον όταν υποβαθμίζεται.

Η δεύτερη κατηγορία στρέφεται σε εργαλεία υποδομής: Toxiproxy για σφάλματα TCP proxy, tc netem για διαμόρφωση πακέτων σε επίπεδο πυρήνα, Pumba ή Chaos Monkey για τερματισμό containers. Ισχυρά, αλλά απαιτούν εξωτερική ρύθμιση, συγκρούονται με την απομόνωση δοκιμών, και συχνά εκτελούνται σε ξεχωριστή διαδικασία που η εφαρμογή δεν μπορεί να γνωρίζει.

Και οι δύο κατηγορίες παραβλέπουν κάτι: το όριο libc. Το επίπεδο όπου η εφαρμογή σας, ανεξάρτητα από γλώσσα ή χρόνο εκτέλεσης, παραδίδει στο λειτουργικό σύστημα. Εκεί που συμβαίνει πραγματικά το `read()`. Εκεί που το `getaddrinfo()` επιλύει ονόματα. Εκεί που το `mmap()` εκχωρεί μνήμη. Εκεί που το `clock_gettime()` επιστρέφει ώρα.

Αν παρεμβληθείτε εδώ, παρεμβάλλεστε σε όλα. Και αν τα σφάλματα που εγχύετε σε αυτό το επίπεδο είναι αδιάκριτα από τα σφάλματα που παράγει ο πυρήνας — επειδή χρησιμοποιούν τους ίδιους κωδικούς errno, τις ίδιες συμβάσεις τιμής επιστροφής, τα ίδια χαρακτηριστικά χρονισμού — τότε αυτό που έχετε φτιάξει δεν είναι προσομοίωση. Είναι εξομοίωση. Μια εξομοίωση πραγματική ως τον πυρήνα.

Γιατί το Όριο libc Είναι το Σωστό Επίπεδο

Το LD_PRELOAD είναι ένα χαρακτηριστικό του δυναμικού συνδέσμου Linux που εισάγει κοινόχρηστα αντικείμενα στον χάρτη συνδέσμων μιας διαδικασίας πριν από οποιαδήποτε άλλη βιβλιοθήκη — συμπεριλαμβανομένης της libc. Όταν μια εφαρμογή καλεί το `connect()`, η επίλυση συμβόλων του δυναμικού συνδέσμου διατρέχει τον χάρτη συνδέσμων κατά σειρά. Αν μια προφορτωμένη βιβλιοθήκη εξάγει ένα σύμβολο με όνομα `connect`, αυτό το σύμβολο υπερισχύει.

Αυτό μας δίνει παρεμβολή: τη δυνατότητα να τυλίγουμε οποιαδήποτε συνάρτηση libc χωρίς να τροποποιήσουμε τον κώδικα κλήσης ή να μεταγλωττίσουμε εκ νέου οτιδήποτε. Και αυτό είναι διαθέσιμο από πριν σχεδιαστούν τα περισσότερα από τα σημερινά παραγωγικά συστήματα.

Οι βασικές ιδιότητες που κάνουν αυτό το σωστό επίπεδο:

**Καθολικότητα ανεξαρτήτως γλώσσας.** Το `socket.connect()` της Python περνά μέσα από glibc. Το `net.connect()` του Node.js περνά μέσα από glibc. Το `Socket.connect()` της Java — μέσω JNI — περνά μέσα από glibc. Μια μόνο προφορτωμένη βιβλιοθήκη παρεμβάλλεται σε όλα.

**Πραγματικά σφάλματα πυρήνα.** Επιστρέφουμε πραγματικές τιμές errno. Ο κώδικας κλήσης δεν μπορεί να ξεχωρίσει ένα πραγματικό ECONNREFUSED από το εγχυόμενο ECONNREFUSED μας. Ο διακόπτης κυκλώματος βλέπει μια πραγματική αποτυχία, όχι μια προσομοιωμένη που γνωρίζει ότι είναι δοκιμή.

**Μηδέν αλλαγές εφαρμογής.** Χωρίς agents. Χωρίς εισαγωγές API. Χωρίς ενσωμάτωση πλαισίου δοκιμών στο επίπεδο εφαρμογής. Η εφαρμογή εκτελείται κανονικά· τα σφάλματα εμφανίζονται κάτω από αυτήν.

**Εμβέλεια διαδικασίας.** Τα σφάλματα περιορίζονται σε μία διαδικασία. Εκτελέστε τη διαδικασία δοκιμής σας με ένα σύνολο σφαλμάτων· εκτελέστε την εξάρτησή σας σε ξεχωριστό container χωρίς σφάλματα. Χωρίς διασταυρούμενη μόλυνση.

Έξι Τομείς Σφαλμάτων

Το σύνολο βιβλιοθηκών καλύπτει έξι ανεξάρτητους τομείς σφαλμάτων, ο καθένας ως ξεχωριστό κοινόχρηστο αντικείμενο. Μπορούν να φορτωθούν μεμονωμένα ή να συνδυαστούν — ο συνδυασμός είναι ασφαλής επειδή κάθε βιβλιοθήκη ανήκει σε ένα αποκλειστικό σύνολο συμβόλων (το Θεώρημα Κυριότητας Συμβόλων, τεκμηριωμένο λεπτομερώς στα έγγραφα αρχιτεκτονικής).

text
libchaos-io.so     — File I/O
  Hooks: open/openat, read/readv, write/writev, pread/preadv, pwrite/pwritev,
         close, fsync/fdatasync, ftruncate, fallocate, unlinkat, renameat,
         sendfile, copy_file_range
  Effects: ERRNO (EIO, ENOSPC, EDQUOT, ...), LATENCY,
           TORN writes (short return < requested), CORRUPT reads (bit flip)

libchaos-net.so    — Network Sockets
  Hooks: socket/socketpair, bind, listen, connect, accept,
         send/sendto/sendmsg/sendmmsg, recv/recvfrom/recvmsg/recvmmsg,
         poll, select, epoll_wait/epoll_pwait
  Effects: ERRNO (ECONNREFUSED, ECONNRESET, ETIMEDOUT, ...), LATENCY, CORRUPT

libchaos-dns.so    — DNS Resolution
  Hooks: getaddrinfo, getnameinfo
  Effects: Name rewrites, address synthesis, EAI_AGAIN, EAI_FAIL, EAI_NONAME,
           EAI_MEMORY, answer shuffling, family filtering, result limiting

libchaos-time.so   — Clock & Timing
  Hooks: clock_gettime (all POSIX clocks), nanosleep, usleep
  Effects: ERRNO, LATENCY, OFFSET (signed millisecond time skew)

libchaos-memory.so — Memory Allocation
  Hooks: mmap, munmap, mprotect, madvise
  Effects: ERRNO (ENOMEM, ENFILE), LATENCY

libchaos-process.so — Process Lifecycle
  Hooks: pthread_create, fork, posix_spawn/posix_spawnp, execve/execveat,
         waitpid
  Effects: ERRNO, LATENCY, FAIL_AFTER (allow N calls then fail permanently)

Παρεμβολή Συμβόλων: Πώς Λειτουργεί στην Πράξη

Ο μηχανισμός είναι απλός στην αρχή, προσεκτικός στην εκτέλεση.

**Βήμα 1 — Αρχικοποίηση βιβλιοθήκης.** Όταν φορτωθεί το προφορτωμένο `.so`, εκτελείται ο κατασκευαστής του. Καλεί το `dlsym(RTLD_NEXT, "connect")` για να βρει το πραγματικό `connect` της libc. Το RTLD_NEXT παραλείπει το τρέχον DSO στον χάρτη συνδέσμων και επιστρέφει το επόμενο αντίστοιχο σύμβολο — την πραγματική υλοποίηση libc. Αυτός ο δείκτης αποθηκεύεται σε μια στατική μεταβλητή. Χωρίς dlsym ανά κλήση στο κρίσιμο μονοπάτι.

**Βήμα 2 — Παρεμβολή κλήσης.** Όταν η εφαρμογή καλεί το `connect()`, ο δυναμικός σύνδεσμος βρίσκει πρώτα το δικό μας σύμβολο (σειρά χάρτη συνδέσμων). Εκτελείται ο wrapper μας: διαβάζει το αρχείο ρύθμισης (ή ένα αποθηκευμένο στιγμιότυπο), αξιολογεί αν πρέπει να ενεργοποιηθεί ένα σφάλμα με βάση τον επιλογέα τελικού σημείου και την πιθανότητα, και είτε εγχύει το σφάλμα είτε μεταβιβάζει στη πραγματική συνάρτηση libc μέσω του αποθηκευμένου δείκτη.

**Βήμα 3 — Αμετάβλητο κυριότητας συμβόλου.** Αν δύο προφορτωμένες βιβλιοθήκες προσπαθήσουν και οι δύο να τυλίξουν το `read()`, μία από αυτές θα λάβει το RTLD_NEXT που δείχνει στην άλλη, προκαλώντας διπλή έγχυση. Αποτρέπουμε αυτό με αυστηρή ανάθεση συμβόλων: κάθε σύμβολο libc ανήκει ακριβώς σε μία βιβλιοθήκη του συνόλου. Το `libchaos-net.so` δεν ανήκει το `read()` — τα σύμβολα I/O ανήκουν στο `libchaos-io.so`. Οι βιβλιοθήκες συντίθενται με ασφάλεια επειδή έχουν σχεδιαστεί έτσι.

bash
# Compose safely — net + dns + io loaded simultaneously, no double-injection
LD_PRELOAD=libchaos-net.so:libchaos-dns.so:libchaos-io.so ./your-service

# Each library reads its own config file independently
/tmp/.chaos-net.conf
/tmp/.chaos-dns.conf
/tmp/.chaos-io.conf

Η Διεπαφή Αρχείου Ρύθμισης

Δεν υπάρχει API. Δεν υπάρχει δημόσια κεφαλίδα. Δεν υπάρχει βιβλιοθήκη για σύνδεση. Ολόκληρη η διεπαφή είναι ένα απλό αρχείο κειμένου ρύθμισης.

Αυτή ήταν μια σκόπιμη επιλογή. Ένα αρχείο ρύθμισης μπορεί να γραφτεί από ένα shell script, μια εργασία CI, ένα σύστημα δοκιμών σε οποιαδήποτε γλώσσα, ή από έναν άνθρωπο σε ένα τερματικό. Δεν απαιτεί ενσωμάτωση συστήματος κατασκευής. Μπορεί να αντικατασταθεί εν λειτουργία ενώ η διαδικασία εκτελείται. Μπορεί να ελέγχεται από εκδόσεις μαζί με δεδομένα δοκιμών. Και δημιουργεί μηδενική σύζευξη μεταξύ της βιβλιοθήκης χάους και της εφαρμογής υπό δοκιμή.

Η σύνταξη ρύθμισης είναι `selector:operation:effect:value:probability`. Μερικά αντιπροσωπευτικά παραδείγματα:

text
# libchaos-net.conf — network fault examples
#
# ECONNREFUSED on 10% of connects to the payments service
tcp4://payments.internal:8080:connect:ECONNREFUSED:0.10
#
# ECONNRESET on 5% of recv() on any TCP socket
tcp4://*:*:recv:ECONNRESET:0.05
#
# 200ms latency on 100% of connects to the analytics backend
tcp4://analytics.internal:9000:connect:LATENCY:200
#
# Corrupt 1% of sent packets to any endpoint (single bit flip)
tcp4://*:*:send:CORRUPT:0.01

# libchaos-dns.conf — DNS fault examples
#
# Transient failure for all *.internal lookups
dns://*.internal:EAI_AGAIN:0.20
#
# Permanent failure for a specific service
dns://legacy-payments.svc.cluster.local:EAI_FAIL:1.0

# libchaos-io.conf — filesystem fault examples
#
# Torn writes (short return) on WAL file
/data/wal:write:TORN:0.05
#
# EIO on 1% of reads from the config directory
/etc/app:read:EIO:0.01

Επαναφόρτωση Ρύθμισης Χωρίς Κλείδωμα κατά την Εκτέλεση

Μία από τις λιγότερο εμφανείς προκλήσεις μηχανικής είναι η εν θερμώ επαναφόρτωση ρύθμισης σε μια πολυνηματική διαδικασία. Η αφελής προσέγγιση — ανάγνωση του αρχείου σε κάθε κλήση — είναι πολύ δαπανηρή. Η αφελής προσέγγιση βασισμένη σε κλείδωμα — διατήρηση mutex κατά την ενημέρωση του στιγμιοτύπου ρύθμισης — μπλοκάρει κάθε παρεμβαλλόμενη κλήση συστήματος κατά την επαναφόρτωση.

Χρησιμοποιούμε μια προσέγγιση χωρίς κλείδωμα βασισμένη σε ατομική σύγκριση-και-ανταλλαγή:

**Δύο ενδιάμεσα buffer.** Το ένα είναι ενεργό· το άλλο είναι διαθέσιμο για εγγραφή. Μια ατομική υποδοχή 64-bit κρατά το mtime της τρέχουσας ενεργής ρύθμισης.

**Ανίχνευση νικητή επαναφόρτωσης.** Κάθε παρεμβολή ελέγχει το mtime του αρχείου ρύθμισης έναντι της αποθηκευμένης τιμής. Σε αναντιστοιχία, ένα νήμα κερδίζει τη φυλή CAS για να ξεκινήσει την επαναφόρτωση. Οι χαμένοι βλέπουν την κατάσταση RELOADING και περιστρέφονται σύντομα.

**Ατομική εναλλαγή.** Ο νικητής γράφει τη νέα ρύθμιση στο ανενεργό buffer, στη συνέχεια ανταλλάσσει ατομικά τον ενεργό δείκτη. Από αυτό το σημείο, όλα τα νήματα βλέπουν τη νέα ρύθμιση. Το παλαιό buffer είναι διαθέσιμο για τον επόμενο κύκλο επαναφόρτωσης.

Το παράθυρο επαναφόρτωσης είναι συνήθως κάτω από 15 μικροδευτερόλεπτα. Οι αναγνώστες δεν μπλοκάρουν ποτέ τους συγγραφείς σε σταθερή κατάσταση. Αυτό καθιστά πρακτική την αλλαγή ρυθμών σφαλμάτων μεταξύ μεθόδων δοκιμής χωρίς επανεκκίνηση της διαδικασίας.

Ενσωμάτωση CI: Τρεις Γραμμές YAML

Η ενσωμάτωση σε αγωγό CI είναι σκόπιμα ελάχιστη. Προμεταγλωττισμένα δυαδικά αρχεία για τέσσερις συνδυασμούς πλατφόρμας (glibc/musl × amd64/arm64) είναι διαθέσιμα. Δεν χρειάζεται βήμα κατασκευής — κατεβάστε το σωστό δυαδικό για το λειτουργικό σύστημα και αρχιτεκτονική του runner CI σας, γράψτε ένα αρχείο ρύθμισης, ορίστε LD_PRELOAD.

yaml
# GitHub Actions example: inject network chaos for integration tests
- name: Download libchaos
  run: |
    curl -fsSL https://github.com/macstab/chaos-testing-libraries/releases/latest/\
download/libchaos-net-glibc-amd64.so -o /tmp/libchaos-net.so

- name: Write chaos config
  run: |
    cat > /tmp/.chaos-net.conf << 'EOF'
    tcp4://db.internal:5432:connect:ECONNREFUSED:0.10
    tcp4://cache.internal:6379:connect:ETIMEDOUT:0.05
    dns://*.internal:EAI_AGAIN:0.15
    EOF

- name: Run integration tests with chaos
  env:
    LD_PRELOAD: /tmp/libchaos-net.so
  run: ./gradlew integrationTest

Εσωτερικά Νήματος-Τοπικά: Χωρίς Καθολική Κατάσταση

Η ορθότητα πολλαπλών νημάτων επιβάλλεται μέσω αποθήκευσης τοπικής στο νήμα αντί για κλειδώματα όπου είναι δυνατόν.

**PRNG ανά νήμα.** Κάθε νήμα έχει τη δική του κατάσταση γεννήτριας τυχαίων αριθμών. Οι ακολουθίες σφαλμάτων είναι ανεξάρτητες ανά νήμα — χωρίς καθολικό σημείο συμφόρησης τυχαιότητας, χωρίς διαμάχη στην κοινή κατάσταση. Αυτό σημαίνει επίσης ότι οι ακολουθίες σφαλμάτων είναι ντετερμινιστικές ανά νήμα για το ίδιο seed, κάτι που έχει σημασία για την αναπαραγωγή αποτυχιών δοκιμών.

**Φύλακας αναδρομής.** Όταν ο κώδικας χάους καλεί εσωτερικές libc (stat για έλεγχο mtime, read για ανάγνωση αρχείου ρύθμισης), αυτές οι κλήσεις θα παρεμβάλλονταν και οι ίδιες, προκαλώντας άπειρη αναδρομή. Μια μεταβλητή `__thread int guard` αποτρέπει αυτό: αν το βάθος αναδρομής είναι μη μηδενικό, καλούμε απευθείας την πραγματική συνάρτηση.

**Κρυφή μνήμη FD-προς-διαδρομή.** Ο αναχαιτιστής I/O αρχείων χρειάζεται να αντιστοιχίσει έναν περιγραφέα αρχείου σε μια διαδρομή (για αντιστοίχιση κανόνων προθέματος διαδρομής). Η ανάγνωση `/proc/self/fd/<fd>` σε κάθε κλήση I/O είναι πολύ δαπανηρή. Διατηρούμε μια τοπική στο νήμα κρυφή μνήμη άμεσης αντιστοίχισης 32 θέσεων (fd % 32) που εισάγεται στο `open()` και ακυρώνεται στο `close()`. Το ποσοστό αποτυχίας κρυφής μνήμης για πραγματικά φορτία εργασίας είναι κάτω από 3%.

Τι Μπορεί και Τι Δεν Μπορεί να Παρεμβληθεί

Τεκμηριώνουμε ρητά τα όρια αντί να αφήνουμε τους χρήστες να τα ανακαλύψουν.

**Δεν μπορεί να παρεμβληθεί:**

- **Άμεσες κλήσεις συστήματος.** Το runtime Go εκδίδει κλήσεις συστήματος απευθείας μέσω του πακέτου `syscall`, παρακάμπτοντας εντελώς τη libc. Τα προγράμματα Go που μεταγλωττίζονται χωρίς CGO είναι ανοίκεια στο χάος LD_PRELOAD στο I/O δικτύου τους. (Η Java μέσω JNI είναι εντάξει· το JNI περνά μέσα από glibc.) - **Στατικά δυαδικά αρχεία.** Το LD_PRELOAD είναι μηχανισμός δυναμικού συνδέσμου. Τα στατικά δυαδικά δεν έχουν δυναμικό σύνδεσμο· η προφόρτωση δεν έχει αποτέλεσμα. - **Δυαδικά αρχεία Setuid/setgid.** Ο πυρήνας αφαιρεί το LD_PRELOAD για δυαδικά setuid (σημασιολογία AT_SECURE). Αυτό είναι χαρακτηριστικό ασφαλείας στο οποίο βασιζόμαστε σωστά. - **Ρολόγια γρήγορης διαδρομής vDSO.** Ορισμένες κλήσεις clock_gettime περνούν μέσω vDSO, όχι glibc. Η βιβλιοθήκη χρόνου μας παρεμβάλλεται στο επίπεδο wrapper glibc, που βρίσκεται κατάντη από το vDSO. Στην πράξη, αυτό σημαίνει ότι το σφάλμα ενεργοποιείται στην κλήση glibc πριν από την αναζήτηση vDSO — το καθαρό αποτέλεσμα είναι το ίδιο, αλλά το εσωτερικό ρολόι του πυρήνα δεν επηρεάζεται.

**Μπορεί να παρεμβληθεί:** - Οποιαδήποτε δυναμικά συνδεδεμένη διαδικασία στο Linux (glibc ή musl) - Java μέσω JNI — συμπεριλαμβανομένων όλων των κλήσεων socket, αρχείου, DNS και χρόνου στο JDK - Python, Node.js, Ruby, PHP — όλα χρησιμοποιούν glibc για I/O συστήματος - Δυαδικά Rust που χρησιμοποιούν std (που χρησιμοποιεί glibc) ή βιβλιοθήκες C γεφυρωμένες με CGO

  • Java (διαδρομή JNI): πλήρης κάλυψη — δίκτυο, DNS, αρχείο, ρολόι, μνήμη
  • Python / Node.js / Ruby: πλήρης κάλυψη μέσω glibc
  • Go (CGO=1 ή βιβλιοθήκες C): μερική κάλυψη — κλήσεις CGO παρεμβάλλονται, καθαρές κλήσεις συστήματος Go παρακάμπτουν
  • Go (순수, CGO=0): χωρίς κάλυψη — άμεσο ABI κλήσης συστήματος, το LD_PRELOAD δεν έχει αποτέλεσμα
  • Στατικά δυαδικά αρχεία: χωρίς κάλυψη εξ ορισμού

Απόδοση: Οι Αριθμοί Επιβάρυνσης

Μετράμε την επιβάρυνση διέλευσης με μικρο-αναφορές σειριοποιημένες με rdtsc για να λάβουμε αριθμούς χειρότερης περίπτωσης. Το κρίσιμο μονοπάτι για μια κλήση διέλευσης (χωρίς ρυθμισμένο σφάλμα):

- **Επιτυχία κρυφής μνήμης ρύθμισης (χωρίς ανάγκη επαναφόρτωσης):** ~20–40 ns επιβάρυνση πέρα από το πραγματικό κόστος κλήσης συστήματος. Αυτός είναι ένας έλεγχος mtime stat (αποθηκευμένος σε ατομική υποδοχή), μια σάρωση κανόνων (γραμμική επί N κανόνες, συνήθως N < 16), και μια κλήση μέσω του αποθηκευμένου δείκτη συνάρτησης. - **Αποτυχία κρυφής μνήμης (αρχείο ρύθμισης επαναφορτώνεται):** Μία κλήση stat() συν μια read() του αρχείου ρύθμισης — συνήθως 150–300 ns συνολικά, και μόνο στην πρώτη κλήση μετά από αλλαγή ρύθμισης. - **Εγχυόμενο σφάλμα:** Η ίδια η επιβάρυνση σφάλματος (ύπνος για LATENCY, ορισμός errno για ERRNO) κυριαρχεί· το κόστος wrapper είναι αμελητέο.

Για μια καλά ρυθμισμένη σουίτα δοκιμών με μικρό αριθμό κανόνων, η επιβάρυνση διέλευσης είναι κάτω από το επίπεδο θορύβου μιας κλήσης δικτύου. Πληρώνετε δεκάδες νανοδευτερόλεπτα πάνω σε λειτουργίες που κοστίζουν μικροδευτερόλεπτα έως χιλιοστά του δευτερολέπτου.

Key Takeaways

Η βιβλιοθήκη χάους C99 LD_PRELOAD είναι αυτό που μοιάζει η πραγματική έγχυση σφαλμάτων πυρήνα όταν σχεδιάζεται από πρώτες αρχές αντί να συναρμολογείται από υπάρχοντα εργαλεία.

Έξι ανεξάρτητοι τομείς σφαλμάτων. Αποκλειστική κυριότητα συμβόλων ώστε να συντίθενται με ασφάλεια. Μια απλή διεπαφή ρύθμισης κειμένου που λειτουργεί από οποιαδήποτε γλώσσα ή αλυσίδα εργαλείων. Εν θερμώ επαναφόρτωση χωρίς κλείδωμα ώστε οι ρυθμοί σφαλμάτων να αλλάζουν μεταξύ μεθόδων δοκιμής. PRNG τοπικό στο νήμα ώστε οι ακολουθίες σφαλμάτων να είναι ανεξάρτητες και ντετερμινιστικές. Προμεταγλωττισμένα δυαδικά αρχεία για glibc και musl σε amd64 και arm64.

Και 100% κάλυψη γραμμών κώδικα επιβαλλόμενη σε CI, επειδή έχουμε στείλει αρκετό λογισμικό σε κασέτες χωρίς κουμπιά ενημέρωσης για να γνωρίζουμε ότι κάθε μη καλυμμένη γραμμή είναι ένα επερχόμενο συμβάν παραγωγής.

Ο πηγαίος κώδικας είναι διαθέσιμος στο chaos-testing-libraries. Το πλαίσιο δοκιμών Java που εγχύει αυτές τις βιβλιοθήκες στα Docker containers σας αυτόματα βρίσκεται στο chaos-testing.

#chaos-engineering #c99 #ldpreload #elf #libc #fault-injection #ci-cd #linux #resilience
E

Engineering Team

Senior Solutions Architects

Χτίζουμε κατανεμημένα συστήματα από πριν ακόμα υπήρχε ο όρος «microservices». Οι ουλές μας έχουν ιστορίες να αφηγηθούν.