Programmare su IBM i: sorgenti, ILE, RPG e SQL Capitolo 7 di 9

Quando si rompe: errori e debug

Rivista il Verificata su IBM i 7.5

Accedi per salvare

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.

Fonti

Torna all'indice della guida

← Torna al blog

Commenti

Nessun commento ancora. Sii il primo a commentare!

Devi avere un account per commentare. Accedi · Registrati