Next                 Up                   Back                     Contents

Επόμενο:Β.8 ΣΤΑΤΙΣΤΙΚΑ ΑΠΟΔΟΣΗΣ ΠΡΟΓΡΑΜΜΑΤΩΝ Πάνω: Παράρτημα Β Πίσω: Β.6 ΒΗΜΑΤΙΚΗ ΕΚΤΕΛΕΣΗ


 

B.7 ΕΜΦΑΝΙΣΗ ΚΑΙ ΙΧΝΗΛΑΤΗΣΗ ΤΙΜΩΝ ΜΕΤΑΒΛΗΤΩΝ

 

Όταν η εκτέλεση ενός προγράμματος Multi-Pascal ανασταλεί με κάποιο τρόπο ο χρήστης μπορεί να ελέγξει τις τιμές μεταβλητών στο τρέχον περιβάλλον της κάθε διεργασίας. Στη Multi-Pascal η κάθε διεργασία έχει το δικό της σημείο εκτέλεσης και το δικό της περιβάλλον ανεξάρτητα από το αν πολλές διεργασίες εκτελούν παράλληλα αντίγραφα της ίδιας διαδικασίας. Η γενική μορφή της εντολής εμφάνισης τιμής μεταβλητής είναι

 

*WRITE <αριθμός διεργασίας> <όνομα μεταβλητής>

 

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

 

Β.7.1. Εμφάνιση τιμών απλών μεταβλητών

 

Η λειτουργία της WRITE εξηγείται με τη βοήθεια του προγράμματος στο Σχήμα Β.2. Ας υποθέσουμε οτι η διεργασία 0 εκτελεί την δομή FORALL στη γραμμή 80 του κυρίως προγράμματος. Η εντολή

 

*WRITE 0 j

 

θα εμφανίσει την τιμή της μεταβλητής j του κυρίως προγράμματος. Αν επίσης υποτεθεί οτι η διεργασία 1 εκτελεί την γραμμή 30 της διαδικασίας Compare τότε η εντολή

 

*WRITE 1 temp

 

θα εμφανίσει την τιμή της μεταβλητής temp, αφού υπάρχει στο περιβάλλον της διεργασίας 1.

 

1   PROGRAM Oddeven;
2   TYPE itemtype = RECORD
3                     first: INTEGER;
4                     second: INTEGER;
5                   END;
6   VAR i, j: INTEGER;
7       a: ARRAY [1..10] OF REAL;
8	  item: itemtype;
9       itemlist: ARRAY [1..3] OF itemtype;
...
20	  PROCEDURE Compare(k: INTEGER);
21	  VAR index: INTEGER;
22	      temp: REAL;
23	  BEGIN
...
40	  END;
41      PROCEDURE Tree(value: REAL);
42	  VAR b: ARRAY [1..10] OF REAL;
43	  BEGIN
...
70 	  END;
71  BEGIN
...
80   FORALL i := 1 TO 10 DO
81     Compare(i);
...
100 END
*WRITE 0 j

 

Όμως η εντολή "WRITE 0 temp" δεν είναι έγκυρη αφού η μεταβλητή temp δεν ανήκει στο τρέχον περιβάλλον της διεργασίας 0. Σε απάντηση η Multi-Pascal θα αναφέρει οτι το όνομα της μεταβλητής δεν βρέθηκε.

 

*WRITE 0 temp

Name not found

 

Αντίθετα η εντολή "WRITE 1 j" είναι έγκυρη και στην ουσία ισοδύναμη με την "WRITE 0 j" αφού η μεταβλητή j είναι κοινή γιά όλες τις διαδικασίες και άρα ανήκει στα περιβάλλοντα όλων των διεργασιών.

 

Β.7.2. Εμφάνιση τιμών δομών μεταβλητών

 

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

 

*WRITE 0 α[4]

*WRITE 0 item.second

*WRITE 2 b[3]

 

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

 

*WRITE 0 α

 

 Index Range: 3:6
     3 --> 56
     4 --> 70
     5 --> -3
     6 --> 0

 

Στην εντολή "WRITE 0 a" η Multi-Pascal ζητά να ορίσουμε την πρώτη και την τελευταία τιμή που θα λάβει ο δείκτης πίνακα με την προτροπή "Index Range:". Ο χρήστης μπορεί να εισάγει δύο αριθμούς στη μορφή "n:m" οι οποίοι να βρίσκονται στα νόμιμα όρια των διαστάσεων του πίνακα. Για να εμφανίσουμε όλα τα στοιχεία του πίνακα απαντούμε στην προτροπή με απλό Enter.

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

 

*WRITE item

  RECORD
     FIRST: 3
    SECOND: 45

 

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

 

*WRITE 0 itemlist[2].fisrt 

*WRITE 0 itemlist[2]

*WRITE 0 itemlist

 

που θα απαντηθούν η πρώτη με έναν απλό αριθμό, η δεύτερη με μία εγγραφή και η τρίτη με έναν αριθμό εγγραφών που θα επιλεγεί από τον χρήστη μέσω της προτροπής "Index Range".

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

 

TYPE itemtype = RECORD
                  first: INTEGER;
                  second: INTEGER;
                END;
     nodeptr = ^node;
     node = RECORD
              data: INTEGER;
              next: nodeptr;
            END;
VAR itemptr: ^itemtype;
    root: nodeptr;

 

Όταν μιά εντολή WRITE αναφέρεται σε έναν δείκτη χωρίς καμμία άλλη ένδειξη τότε εμφανίζονται τα περιεχόμενα των μεταβλητών στα οποία δείχνει ο δείκτης. Γιά παράδειγμα η εντολή

 

*WRITE 0 itemptr

 

θα απαντηθεί όπως παρακάτω

 

POINTER
    TO^:   RECORD
             FIRST: 3
            SECOND: 45

 

Ο δείκτης μπορεί να συνοδεύεται από το σύμβολο "^" δηλαδή

 

*WRITE 0 itemptr^.second


45

 

Όταν η εντολή WRITE επιχειρεί να εμφανίσει τιμές μεταβλητών που περιλαμβάνουν δείκτες σε δείκτες (γιά παράδειγμα συνδεμένες λίστες) τότε η Multi-Pascal διατρέχει όλη τη δομή. Γιά παράδειγμα η εντολή

 

*WRITE 0 root

 

θα απαντηθεί όπως παρακάτω

 

POINTER
    TO^:   RECORD
             DATA: 124
             NEXT: POINTER
			   TO^:   RECORD
                              DATA: 30
                              NEXT: NIL POINTER        

 

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

 

*WRITE 0 root^.next^.data

30

 

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

 

VAR c: CHANNEL OF INTEGER;

 

Η εντολή

 

*WRITE c

 

θα απαντηθεί ως

 

CHANNEL

> 13

> 11

> 56

> -100

> 0

 

Τα δεδομένα της ουράς παρουσιάζονται με την αρχή της ουράς στην κορυφή και το τέλος της ουράς στη βάση, δηλαδή το 13 είναι το πρώτο δεδομένο υποψήφιο γιά παραλαβή ενώ το 0 είναι το τελευταίο δεδομένο που στάλθηκε στο κανάλι. Σε περίπτωση που προσομοιώνεται μιά αρχιτεκτονική κατανεμημένης μνήμης και ειδικά αν προβλέπονται καθυστερήσεις επικοινωνίας τότε μπορεί να εμφανιστεί το εξής φαινόμενο. Έστω οτι αναφερόμαστε σε μιά διεργασία-καταναλωτή και εξετάζουμε τα περιεχόμενα ενός καναλιού εισόδου. Τότε μπορεί να υπάρχουν κάποιες τιμές οι οποίες έχουν μεν αποσταλεί από την διεργασία-παραγωγό αλλά δεν έχουν ακόμη παραληφθεί από την διεργασία-καταναλωτή λόγω των καθυστερήσεων επικοινωνίας. Αυτά τα δεδομένα εμφανίζονται με το πρόθεμα "**".

 

*WRITE c

 

CHANNEL

> 13

> 11

> 56

**> -100

**> 0

 

 

Β.7.3. Ιχνηλάτηση τιμών μεταβλητών

 

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

 

*TRACE <αριθμός διεργασίας> <όνομα μεταβλητής>

 

Μιά σημαντική διαφορά της TRACE από την WRITE είναι οτι ένα όνομα μεταβλητής είναι έγκυρο μόνο αν πρόκειται γιά απλό δεδομένο και όχι ολόκληρη δομή. Με βάση το πρόγραμμα του Σχήματος Β.2 οι παρακάτω εντολές είναι έγκυρες

 

*TRACE 0 j

 

*TRACE 0 a[4]

 

*TRACE 0 item.first

 

*TRACE 0 itemlist[2].second

 

αλλά οι παρακάτω εντολές είναι άκυρες

 

*TRACE 0 a

 

*TRACE 0 item

 

*TRACE 0 itemlist

 

*TRACE 0 itemlist[1]


 

Γενικά η εκτέλεση μιάς εντολής TRACE έχει ως αποτέλεσμα την σύνδεση της θέσης μνήμης της μεταβλητής ίχνους με μιά σημαία (λογική μεταβλητή) η οποία γίνεται αληθής κάθε φορά που η εκτέλεση του πτογράμματος προκαλεί πρόσβαση σε αυτή τη θέση μνήμης. Κατά την εκτέλεση του προγράμματος μιά μεταβλητή μπορεί να περαστεί ως παράμετρος αναφοράς (VAR parameter) σε μιά διαδικασία. Αυτό σημαίνει οτι η θέση μνήμης της μεταβλητής ίχνους μπορεί να προσπελαστεί μέσω διαφόρων ονομάτων μεταβλητών που ανήκουν σε διαφορετικά περιβάλλοντα διεργασιών. Κάθε τέτοια αναφορά προκαλεί αναστολή της εκτέλεσης του προγράμματος.

Μεταβλητές τύπου δείκτη μπορούν να χρησιμοποιηθούν ως μεταβλητές ίχνους. Όμως, σε αντίθεση με την εντολή WRITE, η εντολή TRACE επενεργεί μόνον στην ίδια τη μεταβλητή δείκτη και όχι στα δεδομένα που αυτή δείχνει.

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

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

 

*TRACE 0 j

 

*TRACE 0 a[4]

 

*BREAK 23

 

*DISPLAY


 

θα έχει ως αποτέλεσμα την παρακάτω λίστα

 

Beakpoints at Following Lines:

23

 

List of Trace Variables:

Variable Name              Memory Location

    A[4]                          13

    J                              5

 

 

Η ακύρωση μιάς μεταβλητής ίχνους επιτυγχάνεται με την εντολή CLEAR TRACE η οποία όμως αναφέρεται σε θέση μνήμης και όχι σε όνομα μεταβλητής. Έτσι η ακύρωση της μεταβλητής ίχνους j γίνεται με την εντολή

 

*CLEAR TRACE 5

      Next                 Up                   Back                     Contents

Επόμενο:Β.8 ΣΤΑΤΙΣΤΙΚΑ ΑΠΟΔΟΣΗΣ ΠΡΟΓΡΑΜΜΑΤΩΝ Πάνω: Παράρτημα Β Πίσω: Β.6 ΒΗΜΑΤΙΚΗ ΕΚΤΕΛΕΣΗ