How to troubleshoot failing control language program

I am a newbie AS400 student and am learning from a course.  I wrote and compiled a simple control language program.  However, when I call the program I get the error "Processing command failure, refer to job log for details."  I tried using wrkjoblog and wrkactjob but couldn't find the log I was looking for.  Where can I find this log?  Also, is the job log my primary tool for troubleshooting a failed program or are there other better options.  Course doesn't really seem to cover that.  Thanks in advance for your help.
Who is Participating?
tliottaConnect With a Mentor Commented:

The related joblog is almost always the primary starting point for problem resolution.

However, "problem resolution" isn't the same as "debugging". Your program might have no bugs, but problems can still exist because of environment issues.

Technical debugging would normally be started by setting the session to 'debug mode' and then calling the program. Debug mode is most easily entered by running the STRDBG command and naming the program you're interested in on the command. The command will create the debug environment and open a view of the program that allows you to set break-points and do other debug stuff.

How you use the STRDBG command can depend on how you're defining your program. A CL program can be either OPM or ILE. If you're compiling as OPM, the STRDBG command should have the 'OPM source level debug' option set to *YES.

Also, your program should be compiled so that debug information is retained in the compiled program object. Whatever compile command you're using can be prompted and the relevant parm values can be set. You can probably assume for now that the defaults are sufficient for general debugging.

Discussion for V5R4:

You might have an earlier release, but most info should still be relevant.

General steps:

1. STRDBG to enter debug mode.
2. Set break-points, etc.
3. Press <F12> to drop out of the STRDBG command.
4. CALL the program.
5. As the program runs, it will be interupted wherever your break-points are set. Review any variables you think you need to know. Do whatever debug function seems reasonable.
6. Press <F10> to single-step through each subsequent instruction or <F12> to run the program to the next break-point.
7. If an exception occurs, the debugger will also open, similar to reaching a break-point.
8. When the program finishes, run ENDDBG to get your session out of debug mode.

Now, those are the _basic_ steps for the standard debugger. 98% of the detail is left out because there's simply to much. Further, other debuggers are available. For example:

However, for the problem you mentioned -- "Processing command failure, refer to job log for details." -- the joblog is probably the place to look. If you saw the message, then you should be able to position the cursor on the message and press <F1> for help. When the help display appears, you should see that <F10> will bring up the joblog display. Whenever you see anything on a screen that looks unusual, always try <F1> after moving the cursor to it.

Without more info, it's guesswork where the joblog is. At first guess, the joblog is with your session. To see your session's joblog, most likely you can run the DSPJOBLOG command.

But it's hard to tell if the joblog will do you much good. A joblog needs to have info logged. If the job that runs the program isn't doing any logging, then there might not be enough info in the joblog.

First thing that should be done is ensure that the logging level is high enough to capture what you need. The highest logging level is LOG(4 00 *SECLVL). Your current session can be set that way by running CHGJOB LOG(4 00 *SECLVL).

Also, when testing a CL program, it can be a good idea to cause each CL statement to be logged. This can be enabled by specifying the LOG(*YES) parameter value at compile time.

It might also be necessary to enable the job to allow CL statement logging, so the CHGJOB command might be:


With a job set that way, you'll get about as much info in a joblog as you'll ever need. I rarely need to enter debug mode for a CL program.

One other useful element is the DMPCLPGM command. This command can be coded into a CL program to dump the program's variables whenever the statement is encountered. The output is to a spooled file in the job that runs the program. Finding a job's spooled files... well, usually it's through the DSPJOB command.

It's starting to feel like there are too many options...

There are in fact a lot of options. CL isn't like control languages on other platforms. It is a compiled language that results in executable programs, or modules that can be bound into program objects along with modules from other languages. In V5R4, there are no significant capabilities that CL lacks. V5R4 CL even has access to pointers which makes all system APIs directly available, including all of the C library functions.

Anyway, too much info causes confusion. Try the parts that make sense and let us know if you need more.

Are you using the character-based telnet emulator?
In the character-based 'green' screen, you would put option 14 beside the source member name to compile.
To see your own joblog, use DSPJOBLOG command. Press F10 to get the lower level details, and roll-up to see the errors.

Hope this helps!
ckangas7Author Commented:
Thanks much!!!!  Problem was I failed to set the LOG parameter to YES when I compiled the program.  Lots of great info.
ckangas7Author Commented:
Thanks much for a lot of great info.  Problem was I failed to turn on the LOG option when I compiled the program.  After that I was able to see my error in the joblog.  The logging level was already set to 4.  A related question would be how can you know the name of the job that is running your program?  Is that something you can set during compile, or does the AS400 simply create and name a job automatically each time you do a call?

There are two general kinds of jobs that your program will be running in -- interactive and batch. (There are many other kinds of jobs, but all jobs that will be running a CL program that you wrote will break down into those two categories.)

An interactive job is one that has a terminal session. If you use telnet and issue a CALL command on a command line or take a menu option that results in a call to your program, then your program will run in your "interactive" session (job). This is like a "foreground" process on some other systems.

A batch job is one that resulted from a SBMJOB command (mostly). If you use telnet and issue a SBMJOB command on a command line or take a menu option that results in a SBMJOB command, the submitted job is a batch job. This is like a "background" process on some other systems. A SBMJOB command will include a parameter that results in a program being called; if that program is your CL program or that program calls your CL program, then your program is running in batch.

It usually isn't necessary to determine the name of your interactive job. If you enter the DSPJOB command on a command line, for example, you don't need to specify the name of any job. The default job is the job that the command is running in. You only need to supply a job name if you want to display some other job.

When you use SBMJOB, one of the parameters is the name that you want to use for the batch job. There is a default name, but it's a good idea to supply the desired name. When SBMJOB runs, it shows a message that tells what name the submitted job was given.

In a lot of early testing, programs are simply called from a command line. Assume you named your program MYCLPGM. You could enter this at a command line:

 ==>  call myclpgm

...and press [enter]. Your CL program would begin running interactively, in your interactive job. Any messages logged to the joblog would go into the interactive job's joblog. There wouldn't be another joblog for your program.

Once the program finished, you could access the joblog by running a DSPJOBLOG command. Another way to access the joblog would be by running a DSPJOB command; this would bring up a menu of options that can be taken, one of those options displays the joblog. Interactive jobs are just about that easy.

When you want to display the joblog of a batch job, you need to know what name was given to the job. Usually, since you supplied the name, you'll know what name to give to the command.

Also, the system keeps track of batch jobs that you started. The WRKSBMJOB command lets you bring up a list of them all and you can select the one you're interested in. There are three ways you can ask for the list -- *USER, *WRKSTN and *JOB.

The WRKSBMJOB *USER variation will bring up a list of all jobs that you have submitted (as long as they still exist in some form in the system). They might be jobs from yesterday or six months ago. As long as your UserID was the one that ran those jobs, they'll be on the list.

The WRKSBMJOB *WRKSTN variation will bring up a list of jobs that were submitted from the same interactive session name. If you start up a job under the session name DISPLAY01, then all jobs submitted through sessions named DISPLAY01 will be listed, regardless of who used that session device or when it happened.

The WRKSBMJOB *JOB variation limits the list to those that were submitted in the current session. If you log off and back on, then you're in a different session. If someone else logs on to the same terminal device, then that's a different session. This is the variation that I find myself using the most. Usually I'm interested in batch jobs that I'm creating through my current session.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.