Un programma che non funziona lascia tracce in più posti: il job log, la pila delle chiamate, il debugger, il dump. Questo capitolo li prende uno alla volta.
Leggere l'errore
Quando un programma RPG va in errore, il job log contiene due cose distinte, e servono entrambe.
Il messaggio. RNQ sono le eccezioni che si fermano ad aspettare una risposta, RNX
quelle che terminano il programma. MCH sono errori del livello macchina: indice fuori
dai limiti, campo numerico che contiene qualcosa che numerico non è.
Lo stack delle chiamate. Dice quale programma, quale procedura e quale numero di istruzione. È l'informazione che porta dritti al punto.
DSPJOBLOG JOB(123456/MROSSI/CHIUSURA)
Su un job ancora attivo, lo stack si guarda con WRKJOB, opzione 11.
Consiglio
compilando con OPTION(*SRCSTMT) il numero che compare nel messaggio è il
numero di riga del sorgente, non un numero interno da riconvertire. Vale la pena
metterlo in tutto ciò che si compila.
Gli errori gestiti dal programma
Un programma può accorgersi da solo di un errore invece di morire. Due modi.
MONITOR, che è la forma moderna e vale per un blocco:
monitor;
chain (numero) ordini;
if not %found(ordini);
// record assente: caso previsto
endif;
on-error;
// qualunque errore dentro il blocco
esito = 'Errore in lettura ordini';
endmon;
*PSSR, la subroutine di errore del programma, che raccoglie tutto quello che non è
stato gestito altrove ed è l'ultima rete prima della fine.
Avvertenza
una *PSSR che si limita a return trasforma un guasto in un silenzio.
Il programma finisce, il job risulta terminato normalmente, e il dato non è stato
scritto. È il modo in cui nascono le chiusure che "sono andate bene" e hanno lasciato
l'archivio a metà. Qualunque cosa faccia la *PSSR, deve lasciare traccia: un messaggio
in coda, una riga in un file di log, un codice di ritorno che chi ha chiamato controlla.
Il debugger
Il debugger ILE lavora sul sorgente, purché il programma sia stato compilato con le informazioni necessarie:
CRTBNDRPG PGM(PRODLIB/FATTURE) DBGVIEW(*SOURCE)
*SOURCE mostra il sorgente originale, *LIST il listato dopo l'espansione delle copie e
della precompilazione SQL, che è quello che serve quando il problema è dentro un /COPY o
dentro un EXEC SQL.
STRDBG PGM(PRODLIB/FATTURE) UPDPROD(*YES)
Poi si mette un punto di interruzione (F6 sulla riga), si esegue il programma, e ci si ferma lì: F10 esegue un'istruzione, F12 riprende, F11 mostra il valore della variabile su cui è il cursore.
Avvertenza
UPDPROD(*YES) serve per lavorare su file di produzione, e va scritto
consapevolmente. In debug si eseguono le istruzioni davvero: se il programma scrive, il
record viene scritto. Provare su una libreria di collaudo, con OVRDBF che punta ai dati
di prova, è la differenza fra un debug e un incidente.
Il job che non è il tuo
Il problema è in un job batch, e nel debugger bisogna entrare da fuori.
STRSRVJOB JOB(123456/MROSSI/CHIUSURA)
STRDBG PGM(PRODLIB/CHIUSURA) UPDPROD(*YES)
Da quel momento i comandi di debug valgono su quel job: si mettono i punti di interruzione,
si rilascia il job, e ci si ferma nel punto giusto dentro l'elaborazione vera. Alla fine si
chiude con ENDDBG e ENDSRVJOB.
Consiglio
la procedura che IBM descrive per un job batch: lo si sottomette con
SBMJOB ... HOLD(*YES), se ne legge il nome qualificato con WRKSBMJOB o WRKJOBQ, ci si
aggancia con STRSRVJOB, si lancia STRDBG con tutti i programmi da seguire (mentre il
job aspetta in coda non si possono dare altri comandi di debug), e poi lo si rilascia.
Per un lavoro schedulato che fallisce solo di notte: si sospende la voce di
schedulazione e si sottomette lo stesso comando così.
Il dump
Quando il problema non si riproduce, resta la fotografia:
dump(a);
L'operazione DUMP scrive campi, file, indicatori, strutture dati, schiere e tabelle del
modulo nel file di spool QPPGMDMP. Con (A) lo fa sempre; senza, non lo fa se il
programma ha DEBUG(*NO). Due limiti dalla pagina IBM: con DBGVIEW(*NONE) mostra solo la
struttura di stato, quelle dei file e gli indicatori *IN, e con OPTIMIZE(*FULL) i
valori possono non essere quelli veri.
Le tre cose che risolvono più casi
Guardare il primo errore, non l'ultimo. In un job log lungo i messaggi finali descrivono un programma già in difficoltà. Il messaggio che spiega è il primo grave.
Controllare che l'oggetto corrisponda al sorgente. Prima di leggere il codice riga per
riga, DSPOBJD ... DETAIL(*SERVICE) dice quando è stato compilato l'oggetto e da quale
sorgente (capitolo «Dove sta il codice»).
Guardare l'ambiente prima del programma. Lista librerie del job, sovrascritture attive, gruppo di attivazione, iASP impostato. Un programma giusto in un ambiente sbagliato si comporta come un programma sbagliato.
Commenti
Nessun commento ancora. Sii il primo a commentare!
Devi avere un account per commentare. Accedi · Registrati