View Full Version : Callstackproblem(?) bei QMHRCVPM
ebschubert
17-04-09, 17:20
Guten Abend an alle :)
Ich habe folgendes Problem:
In einem ILE RPG-PGM benutze ich Funktionen, die ich aus entspr. angebundenen SRVPGM's aufrufe.
In einem generellen SRVPGM A habe ich grundlegende Funktionen wie QMHRCVPM definiert um Fehler bei Call QCMD und CL-Aufrufen etc. abzufangen und anzuzeigen.
Das funktioniert auch so weit ...
In einem weiteren SRVPGM B sind speziellere Funktionen definiert, die vom PGM genutzt werden.
An dieses SRVPGM B ist auch das generelle SRVPGM A gebunden.
Jetzt ist folgendes Problem:
Eine Funktion aus dem weiteren SRVPGM B ruft einen CL-Routine auf, die bei Fehler eine *ESC-Msg sendet.
Nun möchte ich diese Nachricht mittels QMHRCVPM aus meinem generellen SRVPGM A auslesen und verarbeiten - da kommt aber nix!!!
Habe im Debugger der verschiedensten Varianten versucht:
Mit Eval Änderung der MsgQue die abgegriffen werden soll als auch Änderung des CallStacks - kein Ergebnis
Weiss jemand Rat?
Mit den besten Wünsche für das Wochenende :)
Das problem ist natürlich die richtige Ebene zu ermitteln. Wichtig ist jedoch, dass diese auch aktiv sein muss !
Es geht also nicht:
PGMA
:
CALL PGMB <= erzeugt Fehler
CALL PGMC <= Fehler aus PGMB lesen
PGMC muss aus PGMB aufgerufen werden.
Ansonsten geht nur noch das Auslesen des Joblog's (JOBMSGQ).
da dürfte wohl ein ILE Condition Handler der richtige Ansatz sein, der wird pro Activation Group einmal registriert und bei nicht behandelten Fehlern (-> Escape Message) automatisch ausgeführt.
D*B
Das problem ist natürlich die richtige Ebene zu ermitteln. Wichtig ist jedoch, dass diese auch aktiv sein muss !
Es geht also nicht:
PGMA
:
CALL PGMB <= erzeugt Fehler
CALL PGMC <= Fehler aus PGMB lesen
PGMC muss aus PGMB aufgerufen werden.
Ansonsten geht nur noch das Auslesen des Joblog's (JOBMSGQ).
ebschubert
20-04-09, 10:28
Danke für den Tipp mit dem
ILE Condition Handler
Aber das löst das Problem nicht.
Mein SRVPGM B ruft ja im Fehlerfall die entspr. Routine aus SRVPGM A - aber leider komme ich nicht an die Msg ran -> diese steht aber im Joblog.
Meinen Frage also.... es wurde empfohlen JOBLOG auszulesen?????
Grüße
Wenn du deine Programmfolge debugst und vor dem Lesen der Nachricht deinen Callstack überprüfst und nachschaust, an wen die Nachricht gesendet wurde (F1->F9 auf der nachricht im Joblog), müsstest du die Ebene doch feststellen können.
Das Auslesen des Joblogs ist nicht das Problem sondern ggf. das Feststellen der richtigen Nachricht.
Viellicht sollte dein SRVPGM direkt die Dienste für QCMDEXC und CALL übernehmen, dann hast du ggf. weniger Schwierigkeiten.
Allerdings sind Stackabhängige Befehle wie OVRxxx dann auf OVRSCOPE(*JOB) anzupassen.
ebschubert
20-04-09, 11:04
Viellicht sollte dein SRVPGM direkt die Dienste für QCMDEXC und CALL übernehmen, dann hast du ggf. weniger Schwierigkeiten.
Allerdings sind Stackabhängige Befehle wie OVRxxx dann auf OVRSCOPE(*JOB) anzupassen.
Genau so ist es auch!
Die Msg geht an mein SRVPGM !
ABER ... wenn ich DORT mein SRVPGM A mit QMHRCVPM aufrufe, kommt nix.
Gleiche Konstellation mit MainPgm und SRVPGM A funktioniert jedoch....
ebschubert
20-04-09, 11:14
ergänzung:
Aufruf getErr aus SRVPGM A
....
Callp RcvPgmMsg( rtnMsgInfo
: %Size( rtnMsgInfo )
: 'RCVM0100'
: InMsgQue
: Stack
: '*EXCP'
: *Blanks
: 0
: '*SAME'
: ApiError )
...........
InMsgQue ist das rufende PGM
Stack steht auf 0
Nun ja, trotzdem nochmal:
Mach einen Break auf dem RcvPgmMsg mit dem Debugger und schau dir dann den Callstack an.
Die Routine GetErr ist ja in einer eigenen Stackebene (und 0 ist die Ebene selber) !
Prozeduren werden per CALL aufgerufen und sind nicht wie EXSR zu vergleichen.
Die Callstack-Ebene verschiebt sich daher.
ebschubert
20-04-09, 11:46
Auszug WRKACTJOB
...
WRKJRNOB WRKJRNOB WRKJRNOB Nein
ISTSRMTJOB RACIWRKSRV RACIWRKSRV Nein
GETERR RACIGENSRV RACIGENSRV Nein
WRKJRNKOB - MainPGM
RACIWRKSRV - SRVPGM wo duch Call CL der Fehler auftritt
RACIGENSRV - SRVPGM zum Auslesen Fehlermeldung
Ähnliche Konstellation doch Fehler in CL bei Aufruf aus MainPGM
WRKJRNOB WRKJRNOB WRKJRNOB Nein
GETERR RACIGENSRV RACIGENSRV Nein
<DT>Call stack counter <DD>INPUT; BINARY(4) A number identifying the location in the call stack of the call stack entry from whose message queue the messages are to be received. The number is relative to the call stack entry identified by the Call stack entry parameter. It indicates how many calls up the call stack the target entry is from the one identified by the Call stack entry parameter. Valid values follow:
<TABLE cellPadding=5><!-- cols="15 85" --><TBODY><TR><TD vAlign=top align=left>0</TD><TD vAlign=top align=left>Receive the message from the message queue of the call stack entry specified in the Call stack entry parameter.</TD></TR><TR><TD vAlign=top align=left>1</TD><TD vAlign=top align=left>Receive the message from the message queue of the call stack entry that is one earlier than the entry identified by the Call stack entry parameter.</TD></TR><TR><TD vAlign=top align=left>n (any positive number)</TD><TD vAlign=top align=left>Receive the message from the message queue of the nth call stack entry up the stack from the call stack entry specified in the Call stack entry parameter. You can use any positive number that does not exceed the actual number of call stack entries in the call stack, excluding the external message queue.
</TD></TR></TBODY></TABLE></DD>
0 = Du versucht die Nachricht deiner eigenen Aufrufebene zu lesen
1 = Die Ebene darüber
2 = die nächste Ebene
n = die n. Ebene
Du musst also nur die richtige Ebene identifizieren.