Αποσφαλμάτωση

Στην επιστήμη υπολογιστών και στην ηλεκτρονική, αποσφαλμάτωση ή εκσφαλμάτωση ονομάζεται η μεθοδική διαδικασία εύρεσης και εξάλειψης σφαλμάτων κώδικα ενός προγράμματος υπολογιστή ή ελαττωμάτων ενός ηλεκτρονικού κυκλώματος, ώστε να συμπεριφέρεται όπως προβλέπεται. Η αποσφαλμάτωση τείνει να είναι δυσκολότερη όταν τα διάφορα υποσυστήματα είναι στενά συνδεδεμένα (tightly coupled), καθώς αλλαγές - διορθώσεις στο ένα μπορεί να είναι αιτία εμφάνισης σφαλμάτων σε ένα άλλο.

 Παρόλο που κάθε σφάλμα απαιτεί ξεχωριστή προσέγγιση γενικά ακολουθούνται τα εξής βήματα: Επανάληψη του προβλήματος Απομόνωση του σημείου που εμφανίζεται το σφάλμα Αναγνώριση της αιτίας που το προκαλεί Διόρθωση του σφάλματος Επιβεβαίωση της διόρθωσης Το πρώτο βήμα για την αποσφαλμάτωση είναι, συνήθως, η επανάληψη του προβλήματος. Αυτό μπορεί να ακούγεται ειρωνικό αλλά είναι αρκετά σημαντικό και πολλές φορές ακατόρθωτο αν το σφάλμα προέρχεται από τη χρήση του προγράμματος σε περιβάλλον πολλών ταυτόχρονων χρηστών ή σε προγράμματα που χρησιμοποιούν παράλληλη επεξεργασία. Μετά τη φάση της επανάληψης του προβλήματος, συνήθως χρησιμοποιείται η τεχνική του "διαίρει και βασίλευε", η διαίρεση, δηλαδή, του κώδικα σε επιμέρους λειτουργικά κομμάτια, όσο το δυνατόν μικρότερα, και ο έλεγχος αν κάποιο από αυτά προκαλεί πρόβλημα. Αν ο έλεγχος αυτός "αποδώσει", αν δηλαδή βρεθεί ποιο τμήμα προκαλεί το πρόβλημα, τότε το έργο της αποσφαλμάτωσης μειώνεται σημαντικά. Στο σημείο αυτό χρησιμοποιούνται διάφορες τεχνικές για την αναγνώριση της αιτίας. Το σφάλμα μπορεί να προέρχεται από λάθη στην πληκτρολόγηση του κώδικα ή από λογικά σφάλματα που είναι και τα πλέον δύσκολα να βρεθούν. Αν έχει εντοπιστεί το πρόβλημα και η αιτία του τότε προχωράμε στην εύρεση λύσης. Τις περισσότερες φορές αυτό σημαίνει τη διόρθωση του κώδικα. Αυτό δεν συμβαίνει πάντα. Δεν είναι λίγες οι φορές που μεγάλοι κατασκευαστές αναγνώρισαν την ύπαρξη προβλήματος αλλά αποφάσισαν να μην το διορθώσουν. Οι λόγοι μπορεί να οφείλονται είτε στην έλλειψη κατάλληλου προσωπικού είτε στην εγκατάλειψη του έργου από τον ιδιοκτήτη, είτε στο ασύμφορο οικονομικό βάρος που θα υπάρξει. Σε αυτό το σημείο υπάρχει και η τεράστια διαφορά μεταξύ προγραμμάτων κλειστού και ανοικτού κώδικα. Αν και ο ιδιοκτήτης του κώδικα έχει εντοπίσει και έχει δημοσιεύσει τον τρόπο επίλυσης του σφάλματος αν δεν θέλει να το διορθώσει οι κάτοχοι των αντιγράφων του προγράμματος μένουν "ξεκρέμαστοι". Στα προγράμματα ανοικτού κώδικα ο καθένας μπορεί να διορθώσει το σφάλμα έστω και μόνο για δική του χρήση. Η διαδικασία ολοκληρώνεται με τον έλεγχο της νέας, διορθωμένης, έκδοσης. Επιπλέον, ίσως χρειαστεί να ερευνηθεί αναλυτικότερα το πρόγραμμα, προκειμένου να διαπιστωθεί αν η διόρθωση δεν επέφερε άλλες ανεπιθύμητες παρενέργειες. Η αποσφαλμάτωση κυμαίνεται σε πολυπλοκότητα, από την επιδιόρθωση απλών λαθών στην εκτέλεση χρονοβόρων και κουραστικών εργασιών συλλογής δεδομένων, ανάλυσης και προγραμματισμού ενημερώσεων (updates). Η ικανότητα εντοπισμού σφαλμάτων του προγραμματιστή μπορεί να αποτελέσει σημαντικό παράγοντα στην προσπάθεια αποσφαλμάτωσης, αλλά η δυσκολία ποικίλλει αναλόγως την πολυπλοκότητα του συστήματος. Επίσης, εξαρτάται σε κάποιο βαθμό, από τη γλώσσα(ες) προγραμματισμού που χρησιμοποιείται και τα διαθέσιμα εργαλεία, όπως προγράμματα εντοπισμού σφαλμάτων (debuggers). Οι debuggers είναι εργαλεία λογισμικού που επιτρέπουν στον προγραμματιστή να παρακολουθεί την εκτέλεση του προγράμματος, να τη σταματά, να την επανεκκινεί, να ορίζει σημεία διακοπής (breakpoints) και να αλλάζει τιμές στη μνήμη. Ο όρος debugger μπορεί επίσης να αναφέρεται στο πρόσωπο που κάνει το debugging. Σε γενικές γραμμές, οι γλώσσες προγραμματισμού υψηλού επιπέδου, όπως η Java, καθιστούν ευκολότερη την αποσφαλμάτωση, επειδή έχουν χαρακτηριστικά, όπως χειρισμό εξαιρέσεων (exception handling), που κάνουν πραγματικές πηγές αλλοπρόσαλλης συμπεριφοράς ευκολότερα εντοπίσημες. Σε γλώσσες προγραμματισμού όπως η C ή η συμβολική γλώσσα (assembly), σφάλματα στον κώδικα μπορεί να προκαλέσουν σιωπηλά - μη εμφανή προβλήματα όπως memory corruption, και είναι συχνά δύσκολο να δούμε που συνέβη το αρχικό πρόβλημα. Σε αυτές τις περιπτώσεις, μπορεί να χρειαστούν εργαλεία εντοπισμού σφαλμάτων μνήμης (memory debugger tools). Σε ορισμένες περιπτώσεις, γενικού σκοπού εργαλεία λογισμικού, τα οποία είναι ειδικά σχεδιασμένα για μια γλώσσα, μπορεί να είναι πολύ χρήσιμα. Αυτά μπορεί να είναι εργαλεία στατικής ανάλυσης κώδικα, τα οποία ψάχνουν για ένα πολύ συγκεκριμένο σύνολο γνωστών προβλημάτων, κάποιων κοινών και κάποιων σπάνιων, στον πηγαίο κώδικα. Όλα αυτά τα προβλήματα που ανιχνεύονται από αυτά τα εργαλεία, σπάνια θα εντοπίζονταν από ένα μεταγλωττιστή (compiler) ή διερμηνέα (interpreter), για αυτό αυτά τα εργαλεία δεν είναι συντακτικοί αναλυτές (syntax checkers) αλλά περισσότερο σημασιολογικοί αναλυτές (semantic checkers). Υπάρχουν εμπορικά και δωρεάν τέτοια εργαλεία για κάθε γλώσσα προγραμματισμού, ενώ κάποια ισχυρίζονται ότι μπορούν να ανιχνεύσουν περισσότερα από 300 διαφορετικά προβλήματα. Τέτοια εργαλεία μπορεί να είναι εξαιρετικά χρήσιμα στον έλεγχο πολύ μεγάλων δέντρων πηγαίου κώδικα (source trees), όπου δεν είναι πρακτικό να εξεταστεί κάθε μονοπάτι εκτέλεσης του προγράμματος. Ένα τυπικό παράδειγμα προβλήματος που ανιχνεύεται είναι η αναφορά σε μεταβλητή, η οποία συμβαίνει πριν ανατεθεί μια τιμή στη μεταβλητή. Ένα άλλο παράδειγμα θα ήταν η εκτέλεση ισχυρού ελέγχου τύπων (strong type checking), όταν η γλώσσα δεν το απαιτεί. Έτσι, αυτά τα εργαλεία είναι καλύτερα στον εντοπισμό πιθανών λαθών, έναντι πραγματικών. Ως αποτέλεσμα, έχουν τη φήμη του ψευδώς θετικού (false positive). Το παλιό πρόγραμμα Unix lint είναι ένα πρώιμο παράδειγμα. Για τον εντοπισμό σφαλμάτων ηλεκτρονικού υλικού (π.χ., υλικού υπολογιστών), καθώς και λογισμικού χαμηλού επιπέδου (π.χ., BIOSes, οδηγών συσκευών) και firmware, όργανα όπως παλμογράφοι, αναλυτές λογικής ή in-circuit εξομοιωτές (in-circuit emulators - ICEs) χρησιμοποιούνται συχνά, μόνα τους ή σε συνδυασμούς. Ένας in-circuit emulator μπορεί να εκτελέσει πολλές από τις τυπικές εργασίες αποσφαλμάτωσης λογισμικού σε λογισμικό χαμηλού επιπέδου και firmware. Τεχνική με την οποία δεν χρησιμοποιούνται οι πραγματικές τιμές που θα έπρεπε να εισαχθούν αλλά προκαθορισμένες ελεγχόμενες τιμές που συνήθως είναι και ακραίες. Για παράδειγμα σε ένα πρόγραμμα για τάβλι αντί να καλείται η συνάρτηση που "ρίχνει τα ζάρια" και επιστρέφει τη "ζαριά" μπορεί να καλείται ο χρήστης να δώσει αυτός τα νούμερα ή να τα νούμερα να παίρνονται από κάποιο σταθερό, γνωστό πίνακα. Με αυτόν τον τρόπο απομακρύνεται (ή επιβεβαιώνεται) το ενδεχόμενο να υπάρχει σφάλμα στο τμήμα του προγράμματος που δημιουργεί τυχαίες τιμές. Τεχνική με την οποία γίνεται χρήση ειδικών σημείων ελέγχου μέσα στο πρόγραμμα όπου είτε καταγράφονται είτε εκτυπώνονται στην οθόνη ή σε εκτυπωτή οι τιμές διαφόρων μεταβλητών, που κάτω από κανονικές συνθήκες εκτέλεσης του προγράμματος δεν εμφανίζονται στον τελικό χρήστη. Απλοϊκό παράδειγμα μπορεί να είναι η εμφάνιση της πλήρους αλλαγής που καλείται ο χρήστης να αποφασίσει αν θα την κάνει. Αν π.χ. ένα πρόγραμμα σε κανονικές συνθήκες απλά εμφανίζει στον χρήστη αν θέλει να συνεχίσει με την καταχώρηση, για λόγους αποσφαλμάτωσης, μπορεί να του παρουσιάζει και όλα τα προς καταχώρηση στοιχεία, με την ηλεκτρονική μορφή που θα καταχωρηθούν, επιπλέον από τη μορφή που τα "πέρασε" ο χρήστης. Αποσφαλματωτής GNU