User Tools

Site Tools


qna:misc:runtime:crash-or-long-return-value

This is an old revision of the document!


Η εκτέλεση τερματίζετα με "παράξενο" κωδικό

Το πρόβλημα

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

Process finished with exit code -1073741819 (0xC0000005)

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

  • Πρόσβαση σε στοιχεία του πίνακα έξω από τα όρια του πίνακα (είτε με αρνητικό δείκτη, είτε δείκτη μεγαλύτερο ή ίσο από το μήκος του πίνακα).
  • Η τιμή ενός δείκτη (pointer) να είναι NULL ή να δείχνει σε σημείο μνήμης που δεν θα έπρεπε (π.χ. μνήμη που δεν ανήκει στο πρόγραμμά σας ή μνήμη που δεν επιτρέπεται η εγγραφή).
  • Μία περίπτωση όπου η μνήμη δεν επιτρέπει την εγγραφή, είναι σε κείμενο δηλωμένο μέσα στον κώδικα σε διπλά εισαγωγικά. (πχ char *T = “Hello”; και μετά T[0] = 'Y';)

Μέθοδοι επίλυσης

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

Με τη χρήση της printf

Εισάγετε μερικές εντολές printf σε διάφορα σημεία του κώδικα της συνάρτησης που υποψιάζεστε ότι έχει το πρόβλημα (ή εάν δεν έχετε κάποια υποψία στην κεντρική συνάρτηση) ώστε κατά την εκτέλεση να δείτε μέχρι ποιά printf εκτυπώνεται.

Έτσι έντοπίζετε την περιοχή που “κρασάρει” όπως λέμε, ο κώδικάς σας. Εάν η περιοχή περιλαμβάνει κάποιο βρόχο καλό θα είναι τα μηνύματα της printf να περιέχουν και τη μεταβλητή του βρόχου, π.χ. σε μία for(i=……) να εκτυπώνεται και η τιμή του i.

Δεν πρέπει ποτέ να ξεχνάτε ότι στο τέλος, όταν λυθεί το πρόβλημα, πρέπει να αφαιρούνται όλες αυτές οι πρόσθετες printf.

Με τη χρήση του Debugger

Αφού αφαιρέσετε ή απενεργοποιήσετε όλα τα breakpoints, εκτελέστε τον κώδικα μέσω του debugger. Τότε η εκτέλεση θα διακοπεί στη γραμμή που παράγει το σφάλμα.

Εάν δεν έχετε προηγούμενη εμπειρία από τη χρήση του debugger, τότε πατώντας το κουμπί δεξιά από το Run (το 2ο) στη γραμμή εργαλείων εκτέλεσης, ξεκινά η εκτέλεση του προγράμματος σε debugging mode, το οποίο σημαίνει ότι όταν προκύψει σφάλμα όπως αυτά που οφείλονται σε λανθασμένη χρήση pointers (δεικτών), εμφανίζει τη γραμμή που προέκυψε στο σφάλμα. Τις περισσότερες φορές αυτή η γραμμή είναι μέσα στον κώδικα που γράφει ο προγραμματιστής και όχι σε κώδικα κάποιας βιβλιοθήκης. Κατόπιν με το stop (τελευταίο κουμπί στην ίδια γραμμή εργαλείων) τεραμίζεται η λειτουργία του debugging.

Προσέξτε ότι η γραμμή αυτή δεν είναι απαραίτητα η λανθασμένη, αλλά μπορεί να είναι αυτή που παρουσιάζει την… παρενέργεια του σφάλματος που υπάρχει σε άλλη γραμμή.

Προσοχή! Υπάρχουν μερικές περιπτώσεις που αυτή η μέθοδος δεν βοηθά, αυτό π.χ. συμβαίνει ότι η εκτέλεση τερματίζεται μέσα σε κάποια συνάρτηση του συστήματος. Σε αυτές τις περιπτώσεις, εάν υπάρχει η δυνατότητα μπορεί να μας βοηθήσει το stack trace που εμφανίζεται αριστερά στα εργαλεία του debugger.

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

qna/misc/runtime/crash-or-long-return-value.1653756409.txt.gz · Last modified: 2022/05/28 16:46 by xallos