Βελτιώστε την ποιότητα του κώδικα και αποτρέψτε τα απροσδόκητα αποτελέσματα μαθαίνοντας πώς να χρησιμοποιείτε το GNU Debugger για να αποκαλύπτετε ανεπιθύμητα σφάλματα στον κώδικά σας.

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

Ο εντοπισμός σφαλμάτων GNU ή, GDB, είναι ένα διαχρονικό εργαλείο εντοπισμού σφαλμάτων στο οποίο βασίζονται οι προγραμματιστές εδώ και χρόνια. Δείτε πώς μπορείτε να χρησιμοποιήσετε το GDB σε Linux.

Προετοιμασία δειγμάτων προγραμμάτων

Για να εξερευνήσετε τις δυνατότητες του GDB, θα χρειαστείτε ένα εκτελέσιμο αρχείο για να πειραματιστείτε. Για επίδειξη, θα εκτελείτε το GDB σε ένα πρόγραμμα ελέγχου κλειδιού μία φορά με διαθέσιμο πηγαίο κώδικα και σύμβολα εντοπισμού σφαλμάτων, μία φορά χωρίς πηγαίος κώδικας και σε ένα απλό πρόγραμμα πολλαπλών νημάτων που εκτυπώνει μηνύματα στην οθόνη, γραμμένα σε C και μεταγλωττισμένα με GCC (GNU C Μεταγλωττιστής).

instagram viewer

Μπορείς χρησιμοποιήστε οποιονδήποτε άλλο μεταγλωττιστή C αλλά φροντίστε να μην αφαιρέσετε το δυαδικό.

Πιθανότατα θα τρέχετε το GDB στα δικά σας προγράμματα. Φροντίστε λοιπόν να τα μεταγλωττίσετε με το -σολ επισημάνετε με gcc για να ενεργοποιήσετε τα σύμβολα εντοπισμού σφαλμάτων.

Χωρίς να υπάρχουν τα σύμβολα εντοπισμού σφαλμάτων και με ένα πολύ απογυμνωμένο δυαδικό αρχείο, θα πρέπει να διορθώσετε την αποσυναρμολόγηση του προγράμματος. Αυτό θα απαιτήσει από εσάς να καταλάβετε καλά τη γλώσσα assembly και πώς λειτουργεί η κατανομή μνήμης στο Linux για να κατανοήσετε τα δεδομένα στη στοίβα και τους καταχωρητές.

Εκτέλεση προγράμματος στο GDB

Εκτελείτε ένα πρόγραμμα στο GDB με δύο τρόπους. Είτε πληκτρολογήστε gdb και μόλις φορτώσει, πληκτρολογήστε τρέξιμο. Ή ξεκινήστε το gdb και στη συνέχεια χρησιμοποιήστε το αρχείο εντολή, φορτώστε το δυαδικό αρχείο στο gdb και, στη συνέχεια, εκτελέστε το με το τρέξιμο εντολή.

Εάν το πρόγραμμά σας απαιτεί ορίσματα γραμμής εντολών για να λειτουργήσει σωστά, φροντίστε να προσθέσετε τα ορίσματα μετά το όνομα του προγράμματος. Ακολουθεί η σύνταξη για τη φόρτωση του προγράμματος στο GDB και την εκτέλεσή του με ορίσματα:

gdb 
run

Ή:

gdb
file
run

Ρύθμιση σημείων διακοπής με το GDB

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

Στο GDB, όταν διορθώνετε ένα πρόγραμμα με σύμβολα εντοπισμού σφαλμάτων, μπορείτε είτε να ορίσετε ένα σημείο διακοπής με το όνομα της συνάρτησης είτε να ορίσετε ένα σημείο διακοπής με βάση τον αριθμό γραμμής. Εδώ είναι η σύνταξη:

break main
break 47

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

info breakpoints

Για να διαγράψετε ένα συγκεκριμένο σημείο διακοπής ή πολλά σημεία διακοπής, πληκτρολογήστε:

delete 2
delete 3-5

Το GDB σάς επιτρέπει επίσης να ορίσετε σημεία διακοπής υπό όρους, που σημαίνει ότι το πρόγραμμα θα σταματήσει μόνο εάν ικανοποιηθεί μια συγκεκριμένη συνθήκη κατά την εκτέλεση. Θα μπορούσε να είναι η αλλαγή στην τιμή μιας μεταβλητής ή μιας ανεπιτυχούς κλήσης συνάρτησης ή οτιδήποτε θέλετε. Ακολουθεί η σύνταξη για τον ορισμό σημείων διακοπής υπό όρους:

break  if n == 2

Εάν θέλετε να συνεχίσετε την εκτέλεση του προγράμματος αφού πατήσετε ένα σημείο διακοπής, πληκτρολογήστε το να συνεχίσει εντολή:

continue

Βήμα μέσω κώδικα

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

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

  1. βήμα: Αυτή η εντολή λέει στο GDB να μπει στην επόμενη γραμμή του αρχείου προέλευσης. Αυτό σας επιτρέπει να διασχίσετε ουσιαστικά το μήκος του πηγαίου κώδικα γραμμή προς γραμμή.
  2. Επόμενο: Αυτή η εντολή εκτελεί την επόμενη γραμμή πηγαίου κώδικα μέσα στην τρέχουσα συνάρτηση και στη συνέχεια σταματά. Επόμενο αντιμετωπίζει μια συνάρτηση ως μεμονωμένη γραμμή, επομένως εάν χρησιμοποιήσετε την επόμενη πριν από μια κλήση συνάρτησης, θα την αντιμετωπίσει ως μία γραμμή και θα περάσει πάνω από αυτήν, σε αντίθεση με την βήμα εντολή.
  3. φινίρισμα: Η εντολή finish εκτελεί όλες τις υπόλοιπες γραμμές μέσα στην τρέχουσα συνάρτηση και στη συνέχεια σταματά.

Εξέταση μεταβλητών

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

print 

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

display 

Ρύθμιση σημείων παρακολούθησης

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

watch 

Εντοπισμός σφαλμάτων για συγκεκριμένο νήμα με GDB

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

Για να προβάλετε τα νήματα που δημιουργούνται αυτήν τη στιγμή στο πρόγραμμά σας, χρησιμοποιήστε το πληροφορίες εντολή:

info threads

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

thread 2

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

Απομακρυσμένος εντοπισμός σφαλμάτων με GDB

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

Για παράδειγμα, για να εγκαταστήσετε τον gdbserver στα συστήματά σας που βασίζονται στο Ubuntu ή στο Debian, χρησιμοποιήστε το APT:

sudo apt install gdbserver

Μόλις εγκατασταθεί, μετακινηθείτε στο φάκελο του δυαδικού αρχείου και εκτελέστε αυτήν την εντολή για να ξεκινήσετε το gdbserver:

gdbserver :

Ο gdbserver θα πρέπει να επιστρέψει την έξοδο που είναι επάνω και ακούει στη θύρα που ορίσατε. Τώρα στον υπολογιστή-πελάτη, ξεκινήστε το GDB και, στη συνέχεια, συνδεθείτε στον απομακρυσμένο διακομιστή χρησιμοποιώντας το στόχος εντολή:

target remote :

Σύνταξη σεναρίων GDB για την αυτοματοποίηση του εντοπισμού σφαλμάτων

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

Εδώ είναι ένα παράδειγμα:

set logging enabled on
set logging file sample.out
break main
command 1
backtrace
print N
continue
end
quit

Στο παραπάνω σενάριο, λέτε στο GDB να ενεργοποιήσει την καταγραφή και να αποθηκεύσει το αρχείο καταγραφής σε ένα αρχείο που ονομάζεται δείγμα.έξω, στη συνέχεια ορίστε ένα σημείο διακοπής στο κύριος λειτουργία.

Για το σημείο διακοπής αριθμό 1, σε αυτήν την περίπτωση, το σημείο διακοπής στη συνάρτηση main, εκτελέστε τις ακόλουθες εντολές: οπισθοδρόμηση, Τυπώνω, να συνεχίσει. Βασικά, το GDB θα εκτελέσει πρώτα ένα backtrace, στη συνέχεια θα εκτυπώσει την τιμή της μεταβλητής "N", θα συνεχίσει την εκτέλεση και τελικά θα τερματίσει.

Για να εκτελέσετε αυτό το σενάριο, χρησιμοποιήστε:

gdb -x