View Full Version : MCH3601 when try to setll
01-01-1995, 02:00 AM
Hi. I get a big problem that cannot go on my program. My program first CALL QUSLFLD format FLDL0100 then use QUSRTVUS read header to get the number of field then DO loop for the number of entry CALL QUSRTVUS to get the field name and put in array according to field sequence. Then setll to one PF and get MCH3601. In my debug the program work correctly up to the setll statement and die. Now I try to find out, so I copy my program and reduce some of its working up to the point that before DO loop,then do setll program not bomp. What should I do? I also attach my source file here in zip file. After unzip their are 2 files (T1.txt is the not bomb one.) Please help. TIA.
05-26-2000, 03:28 AM
MCH3601 is a decimal data error. Without going into debug, it is a simple matter to determine the cause of this. When the system message appears take a "D" option. This will produce a program dump. Take a look at the dump (in your spool file). The very first line points to the line of code that has failed. Take a look at a compiled listing of your program. Refer to the line of code as indicated by the dump. Take note of all of the fields on that line of code. Cross reference each field with the dump listing. This can be found near the bottom of the dump listing. Check each value of each field from the failed line of code in your program. The field with non-numeric values is your problem. If the field is a work filed defined in the "D" specs, this may be resolved simply by adding the INZ(0) keyword. Dave
05-26-2000, 05:49 AM
Panida, <font color=blue>What should I do? </font> Change the way you call QUSRTVUS. The problem is that you are telling it to return LENDTA bytes, and LENDTA is initialized to LSTSIZ. On the surface, that looks good because you are telling it to return the size of one list entry. Makes sense until you consider that you are passing the ds LIST as the memory location for where to store the return value from the usrspc. The real problem is that LIST is only 212 bytes long, but LSTSIZ is at least 288 bytes long (at least at my release level QUSFLD returns 288 bytes per field). Your LIST ds correctly maps the first 212 bytes of the return value, and you evidently don't need the other values QUSFLD will return for each field. However, since you set LENDTA to the size of LSTSIZ and not the size of LIST, then QUSRTVUS returns LSTSIZ bytes starting at the beginning of LIST. After the first 212 bytes (the size of LIST), it continues to overwrite whatever is in memory beyond the last subfield of LIST. You have at least 76 bytes of memory being corrupted here. The work variables PFILE, PDUADN, and/or PDUASQN are apparently within that 76+ byte memory space. Plus some other stuff. What you need to do is to set LENDTA on line 110 to the size of LIST (ie 212) since that is how much memory you have alloted for the return value. You still need to use LSTSIZ on line 122 to increment the offset within the user space by the actual size of one list entry. Using LSTSIZ on line 122 is a good idea, because the size of one entry can change with releases, etc. But it is a bad idea on line 110. Even if your LIST ds was the full length of the currently documented return size per field, the program could break in the future if and when LSTSIZ increased. When using QUSRTVUS to retrieve a subset of a user space, ensure the field passed in parameter 4 is at least as large as the length passed in parameter 3. The bottom line is that you need to change factor2 on line 110 of T2.TXT from LSTSIZ to the constant 212. Then I suspect the program should work. Personally, I like to use RPG IV where I can use %size( LIST ) instead of a constant. But then, with RPG IV my preference is to just use pointer arithmetic with a based DS to walk a list in a user space. Completely avoids problems such as these. Doug
Powered by vBulletin® Version 4.1.5 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.