Система обнаружила исключение защиты

Я пытаюсь использовать функцию СОРТИРОВКИ COBOL.

IDENTIFICATION DIVISION.                       
PROGRAM-ID. ******.                          
ENVIRONMENT DIVISION.                          
INPUT-OUTPUT SECTION.                          
FILE-CONTROL.                                  
     SELECT IN-FILE ASSIGN TO IFILE.           
     SELECT OUT-FILE ASSIGN TO OFILE.          
     SELECT SORT-FILE ASSIGN TO SORTWK.        
DATA DIVISION.                                 
FILE SECTION.                                  
SD SORT-FILE.                                  
01 SORT-REC.                                   
   05 S-NAME     PIC X(20).                    
   05 S-ADDRESS  PIC X(20).                    
   05 S-ID       PIC 9(9).                     
   05 S-CREDITS  PIC 99.                       
   05 FILLER     PIC X(29).                    
FD IN-FILE.                                    
01 IN-REC.                                     
   05 IN-NAME    PIC X(20).                    
   05 IN-ADDRESS PIC X(20).                    
   05 IN-ID      PIC 9(9).                     
   05 IN-CREDITS PIC 99.                       
   05 FILLER     PIC X(29).                    
FD OUT-FILE.                                   
01 OUT-REC       PIC X(80).                    
WORKING-STORAGE SECTION.                       
01 WS-WORK-AREA.                               
    05  EOF-SW    PIC X           VALUE SPACES.
01 WS-DETAIL-LINES.                            
   05 RPT-LINE.                                
      10 OUT-NAME    PIC X(20).                
      10 OUT-ADDRESS PIC X(20).                
      10 OUT-ID      PIC 9(9).
      10 OUT-CREDITS PIC 99.                      
      10 FILLER      PIC X(29)       VALUE SPACES.
PROCEDURE DIVISION.                               
MAIN-RTN.                                         
    SORT SORT-FILE                                
            ON ASCENDING KEY S-ID                 
            INPUT PROCEDURE READ-RELEASE          
            OUTPUT PROCEDURE RETURN-WRITE.        
    STOP RUN.                                     
OPEN-FILES-RTN.                                   
    OPEN INPUT IN-FILE.                           
    OPEN OUTPUT OUT-FILE.                         
OPEN-FILES-RTN-EXIT. EXIT.                        

READ-RELEASE.                                     
    PERFORM OPEN-FILES-RTN.                       
    PERFORM READ-INPUT                            
     UNTIL EOF-SW = 'F'.                          
READ-RELEASE-RTN-EXIT. EXIT.                      

READ-INPUT.                                       
    READ IN-FILE                                  
     AT END MOVE 'F' TO EOF-SW.                   
    RELEASE SORT-REC FROM IN-REC.                 

RETURN-WRITE.                                     
    MOVE SPACES TO EOF-SW.                        
    PERFORM WRITE-FL                              
     UNTIL EOF-SW  = 'F'.                         
    PERFORM CLOSE-FILES-RTN.                      
RETURN-WRITE-RTN-EXIT. EXIT.                      

WRITE-FL.                                         
    RETURN SORT-FILE RECORD INTO OUT-REC          
     AT END MOVE 'F' TO EOF-SW.                   
    WRITE OUT-REC.
WRITE-FL-RTN-EXIT. EXIT.   

CLOSE-FILES-RTN.           
    CLOSE IN-FILE OUT-FILE.
CLOSE-FILES-RTN-EXIT. EXIT. 

Я могу скомпилировать эту программу, но когда дело доходит до выполнения, возникает следующая ошибка:

CEE3204S Система обнаружила исключительную ситуацию защиты (код завершения системы = 0C4). Из модуля компиляции SU98PGM6 в точке входа SU98PGM6 при смещении модуля компиляции + 0005517A по адресу 1F45517A.

Я искал информацию об этой ошибке, но не смог понять, что вызывает эту проблему в моей программе.

Я внес некоторые изменения после того, как принял к сведению комментарии, но у меня все еще возникает та же проблема с этим измененным кодом.

READ-RELEASE.                           
    PERFORM OPEN-FILES-RTN.             
    PERFORM READ-INPUT                  
     UNTIL EOF-SW = 'F'.                
READ-RELEASE-RTN-EXIT. EXIT.            

READ-INPUT.                             
    READ IN-FILE                        
     AT END MOVE 'F' TO EOF-SW          
     NOT AT END PERFORM PROCESS-INPUT.  

PROCESS-INPUT.                          
    MOVE IN-NAME TO S-NAME.             
    MOVE IN-ADDRESS TO S-ADDRESS.       
    MOVE IN-ID TO S-ID.                 
    MOVE IN-CREDITS TO S-CREDITS.       
    RELEASE SORT-REC.                   
PROCESS-INPUT-RTN-EXIT. EXIT.           

RETURN-WRITE.                           
    MOVE SPACES TO EOF-SW.              
    PERFORM WRITE-FL                    
     UNTIL EOF-SW = 'F'.                
    PERFORM CLOSE-FILES-RTN.            
RETURN-WRITE-RTN-EXIT. EXIT.            

WRITE-FL.                               
    RETURN SORT-FILE RECORD INTO OUT-REC
     AT END MOVE 'F' TO EOF-SW          
     NOT AT END PERFORM PROCESS-OUTPUT. 
WRITE-FL-RTN-EXIT. EXIT.                

PROCESS-OUTPUT.                         
    MOVE S-NAME TO OUT-NAME.            
    MOVE S-ADDRESS TO OUT-ADDRESS.      
    MOVE S-ID TO OUT-ID.                
    MOVE S-CREDITS TO OUT-CREDITS.
    WRITE OUT-REC.            
PROCESS-OUTPUT-RTN-EXIT. EXIT.   

Вот мой JCL

//******** JOB 1,'*****',NOTIFY=*******                    
//JOBLIB   DD  DSN=*******.*******.*******,DISP=SHR         
//STEP0    EXEC PGM=SU98PGM6                               
//IFILE    DD DSN=*******.*******.*******.*******(*******),DISP=SHR
//SORTWK   DD DSN=*******.*******.*******.*******,DISP=SHR          
//OFILE    DD DSN=*******.*******.*******.*******,              
//            DISP=(NEW,CATLG,DELETE),                     
//            DCB=(BLKSIZE=0,LRECL=80,RECFM=FB),           
//            SPACE=(CYL,(1,1),RLSE),                      
//            UNIT=SYSDA                                   
/*         

person Barte    schedule 23.11.2015    source источник
comment
Ошибка S0C4 может означать несколько разных вещей, обычно что-то вроде того, что вы пытались прочитать или записать в памяти, является недопустимым, или вы вводите недопустимые данные. Дополнительную информацию об ошибке см. по этой ссылке.   -  person bhamby    schedule 24.11.2015
comment
Я все еще не мог решить проблему. Мне удалось создать вывод без использования SORT, поэтому я думаю, что проблема не в прочитанном или выходном файле. Кроме того, SORT-FILE - это просто пустой файл, я не знаю, что с ним не так. Мне было интересно, может ли логическая ошибка в программе вызвать эту проблему?   -  person Barte    schedule 24.11.2015
comment
Вы дважды определяете конец ввода (ваш файл для сортировки и ваш отсортированный файл), а затем все равно пытаетесь использовать данные. Предварительное чтение упростит ситуацию.   -  person Bill Woodger    schedule 24.11.2015
comment
@BillWoodger прав. Следует закодировать либо предварительное чтение, либо IF-тесты для обхода инструкций RELEASE и WRITE.   -  person user2338816    schedule 24.11.2015
comment
Для WRITE-FL также следует использовать возвратный трубопровод. Вы пытаетесь записать возвращенные данные (даже если это может быть конец файла).   -  person Bruce Martin    schedule 24.11.2015
comment
В какой строке возникла ошибка ???, попробуйте найти адрес в листинге программы. В качестве альтернативы используйте некоторые операторы трассировки в   -  person Bruce Martin    schedule 24.11.2015
comment
Я не знаю, как найти строку, в которой возникает ошибка.   -  person Barte    schedule 24.11.2015
comment
Я изменил код, как указано выше, но все равно получаю ту же ошибку.   -  person Barte    schedule 24.11.2015
comment
Добавьте дисплеи в свой код. т.е. в начале каждой процедуры   -  person Bruce Martin    schedule 24.11.2015
comment
Вы должны добавить SYSOUT DD (// SYSOUT DD SYSOUT = *). Затем он будет содержать вывод ваших сообщений DISPLAY и SORT. В качестве первой строки вашей программы включите CBL NOOFFSET,LIST, скажем, в столбец 12. Затем перекомпилируйте вашу программу. Посмотрите на вывод вашего задания компиляции (я предполагаю, что вы отправляете компиляцию в пакетном режиме). В списке компиляции будет файл четыре. Заголовок каждой страницы будет содержать название и версию / выпуск компилятора. Наверное Enterprise COBOL 3 или 4 или пять,   -  person Bill Woodger    schedule 24.11.2015
comment
Обновленный ответ. Это объясняет корень проблемы. У вас есть SyncSORT?   -  person Bill Woodger    schedule 24.11.2015
comment
Нет, я тоже использую DFSORT. Ваши обновленные ответы очень полезны, спасибо.   -  person Barte    schedule 24.11.2015
comment
Обновился снова. Как только вы увидите результат DFSORT и сможете разработать версию своего компилятора, опубликуйте их в качестве комментария, и я посмотрю и передам его в DFSORT для комментариев, если я не смогу что-то придумать. .   -  person Bill Woodger    schedule 24.11.2015
comment
Я просто хотел упомянуть, что в этой задаче есть возможность изучить одну из жемчужин z / OS: это инструменты диагностики. Одна из самых замечательных особенностей z / OS заключается в том, что вы почти всегда можете точно расшифровать, что происходит, не догадываясь. Просто прочтите дамп. Добавьте оператор DD // SYSUDUMP (или // SYSMDUMP, если вы чувствуете себя смелым), перезапустите свою программу, и вы получите дамп, в котором будет все, что вы можете пожелать, чтобы определить источник вашей проблемы.   -  person Valerie R    schedule 27.11.2015


Ответы (1)


Вывод // SYSOUT DD может сбивать с толку при использовании COBOL, SORT (DFSORT или SyncSORT) и Language Environment, которые могут выдавать вам сообщения во время выполнения, поскольку все они используют SYSOUT по умолчанию, и сообщения будут отображаться смешанными.

К счастью, вы можете изменить поведение по умолчанию, как показано здесь для DFSORT и Language Envrionment (в LE есть много способов указать параметр, наиболее гибким является //CEEOPTS DD в вашем JCL): https://stackoverflow.com/a/29521423/1927206

Сам COBOL имеет параметр компилятора OUTDD. значение по умолчанию SYSOUT, но вы можете указать любой OUTDD (xxxx)


Хорошо, просмотрев ваш JCL и ваши комментарии о том, как оператор DISPLAY в вашей программе влияет на данные, мне удалось частично воспроизвести.

Я использую DFSORT и не понимаю вашего точного поведения, поэтому предполагаю, что вы используете SYNCSORT.

Поведение, которое я могу получить после удаления //SYSOUT DD из моего JCL, выглядит следующим образом:

IGZ0026W На специальный регистр SORT-RETURN никогда не ссылались, но текущее содержимое указывает, что операция сортировки или слияния в программе STOB87 в строке номер 46 была неудачной.

Когда я добавляю // SYSOUT обратно в JCL, программа работает успешно.

Когда я вынимаю // SYSOUT и добавляю DISPLAY перед SORT, программа работает. Это связано с тем, что если в JCL нет // SYSOUT, первый выполненный DISPLAY вызовет его динамическое создание (вывод будет отображаться в спуле, как если бы это было отдельное задание с тем же именем и номером задания).

В моем случае DFSORT жалуется на отсутствие // SYSOUT. При использовании DISPLAY // SYSOUT не пропадает во время запуска DFSORT.

Я должен предположить, что SYNCSORT сталкивается с аналогичной проблемой, но сообщение COBOL во время выполнения не создается, и сам SYNCSORT не работает при следующем RELEASE.

Хотя это кажется простой и распространенной проблемой, поскольку мы всегда копируем часть JCL, чтобы создать новую часть JCL, // SYSOUT всегда присутствует.

Проконсультируйтесь с Руководством по программированию Enterprise COBOL, глава 12, я думаю, и узнайте, как использовать SORT-RETURN для подтверждения успешного завершения SORT.

Я почти уверен, что если вы включите // SYSOUT в свой JCL, вы больше не получите аварийного завершения, независимо от того, есть ли у вас DISPLAY.

Причина высокого «смещения» заключается в том, что аварийный процессор не может идентифицировать точку входа вашего продукта SORT, поэтому продолжает поиск в обратном направлении, чтобы найти то, что он может идентифицировать, и находит точку входа вашей программы, а затем вычисляет неправильное смещение. . Это также может произойти при ВЫЗОВЕ некоторых программ на Ассемблере.


Во-первых, к вашему S0C4, который является исключением защиты, что означает, что вы пытаетесь получить доступ к хранилищу, которое не «принадлежит» вам, для того доступа, который вам нужен.

Вы получаете S0C4 в программе SU98PGM6. Вы хитро стерли свое PROGRAM-ID имя при размещении здесь сообщения, что, вероятно, не помогло.

SU98PGM6 - это не ваша программа. Аварийное завершение (Abnormal End) находится по смещению X'0005517A 'в сбойной программе. Это означает, что с «начала» программы (точка входа) инструкция со смещением / смещением X'0005517A 'является той, которая попыталась сделать плохую вещь. Это смещение, равное 348538 в десятичной системе, указывает на довольно большую программу. Ваша программа очень маленькая.

Это может произойти разными способами. Например, вы могли скопировать JCL откуда-то еще и не смогли изменить EXEC PGM=. У вас может быть программа с тем же именем, что и ваша ранее в конкатенации STEPLIB. Возможно, вы скомпилировали не ту программу. И т.п.

Когда вы получаете аварийное завершение работы, всегда подтверждайте, что список компиляции, который у вас есть, относится к прерванной программе. Простой и полезный способ сделать это:

   01  W-WHEN-COMPILED                     PIC X(8)BX(8).

   ...

  * where it can only be executed once:
       MOVE WHEN-COMPILED           TO W-WHEN-COMPILED
       DISPLAY 
               "yourname COMPILED ON " 
               W-WHEN-COMPILED

"ваше имя" вы замените текстом, следующим за ИД ПРОГРАММЫ.

Результат будет таким:

yourname COMPILED ON 11/24/15 10.35.26

Это будет соответствовать дате / времени в заголовке на каждой странице списка компиляции.

Если вы запускаете программу и не получаете этого вывода, или вы получаете результат, но это не тот результат, который ожидается, то вы знаете, что ваша программа не работает.

Теперь о вашей программе.

  1. Вам не нужно использовать процедуры ввода / вывода, чтобы иметь возможность СОРТИРОВАТЬ
  2. Вы должны всегда использовать предложение FILE STATUS оператора SELECT и всегда проверять поля статуса файла (по одному на файл), которые вы определяете, после каждой операции ввода-вывода. Проверка поля состояния файла для входного файла позволит вам определить конец файла без использования извилистой конструкции AT END/NOT AT END.
  3. Если вы используете процедуры сортировки, COBOL выполняет ввод-вывод. Если вы этого не сделаете и используете опцию компилятора FASTSRT, ваш продукт SORT выполнит ввод-вывод, что будет намного эффективнее, чем COBOL.
  4. Если вы не выбираете или не переформатируете записи, вам не нужны процедуры сортировки.
  5. Поскольку вы используете INTO, который выполняет неявное ПЕРЕМЕЩЕНИЕ записи, вам не нужно также ПЕРЕМЕЩАТЬ данные по отдельности.
  6. COBOL, поскольку компиляторы, поддерживающие Стандарт 1985 года, который, я уверен, у вас будет, есть "ограничители области видимости". До этого единственным ограничителем области видимости была точка / точка. В наши дни при использовании «императивных операторов» и для всех условных операторов используются явные, конкретные указатели конца области видимости. В вашем случае замените использование READ / END-READ, RETURN / END-RETURN
  7. Используйте точки / точки только в PROCEDURE DIVISION, где они требуются, а не в строке кода. Это помогает перемещать / копировать код из одного места в другое.
  8. Используйте для тестов 88-уровневые имена условий, а не литералы. Вы можете сделать имя значимым, чтобы никому не приходилось задумываться о том, что означает «F» в конкретном контексте.

Чтобы просто СОРТИРОВАТЬ файл в программе на языке COBOL, посмотрите SORT ... USING ... GIVING... и используйте параметр компилятора FASTSRT (если возможно).

Вы еще не осведомлены о значениях абзацев (или SECTION) и оператора EXIT.

При использовании PERFORM или SORT PROCEDURE выполнение передается коду в абзаце и возвращает управление при достижении следующего абзаца.

Ваши "выходные" абзацы в том виде, в каком вы их закодировали, никогда не используются, но кто-то, глядя на код, предположит (если они глупые, и многие люди сделают предположение), что вы использовали THRU, и они будут придерживаться GO TO абзац «выход». Тогда они будут удивлены, что программа ведет себя плохо (если им повезет) и в конечном итоге выяснят, что они использовали GO TO для передачи управления из диапазона PERFORM / PROCEDURE.

Если ваши местные стандарты предписывают использование выходных параграфов, вы должны использовать THRU в своих инструкциях PERFORM и PROCEDURE.

Выходные абзацы совершенно бесполезны и ничего не делают, кроме как предоставляют целевую метку для GO TO, а это означает, что кто-то в будущем, вероятно, будет использовать GO TO для «удобства».

Вот ваша исходная программа с удаленными выходными абзацами:

IDENTIFICATION DIVISION.                       
PROGRAM-ID. ******.                          
ENVIRONMENT DIVISION.                          
INPUT-OUTPUT SECTION.                          
FILE-CONTROL.                                  
     SELECT IN-FILE ASSIGN TO IFILE.           
     SELECT OUT-FILE ASSIGN TO OFILE.          
     SELECT SORT-FILE ASSIGN TO SORTWK.        
DATA DIVISION.                                 
FILE SECTION.                                  
SD SORT-FILE.                                  
01 SORT-REC.                                   
   05 S-NAME     PIC X(20).                    
   05 S-ADDRESS  PIC X(20).                    
   05 S-ID       PIC 9(9).                     
   05 S-CREDITS  PIC 99.                       
   05 FILLER     PIC X(29).                    
FD IN-FILE.                                    
01 IN-REC.                                     
   05 IN-NAME    PIC X(20).                    
   05 IN-ADDRESS PIC X(20).                    
   05 IN-ID      PIC 9(9).                     
   05 IN-CREDITS PIC 99.                       
   05 FILLER     PIC X(29).                    
FD OUT-FILE.                                   
01 OUT-REC       PIC X(80).                    
WORKING-STORAGE SECTION.                       
01 WS-WORK-AREA.                               
    05  EOF-SW    PIC X           VALUE SPACES.
01 WS-DETAIL-LINES.                            
   05 RPT-LINE.                                
      10 OUT-NAME    PIC X(20).                
      10 OUT-ADDRESS PIC X(20).                
      10 OUT-ID      PIC 9(9).
      10 OUT-CREDITS PIC 99.                      
      10 FILLER      PIC X(29)       VALUE SPACES.
PROCEDURE DIVISION.                               
    SORT SORT-FILE                                
            ON ASCENDING KEY S-ID                 
            INPUT PROCEDURE READ-RELEASE          
            OUTPUT PROCEDURE RETURN-WRITE        
    GOBACK
    .                                     
OPEN-FILES-RTN.                                   
    OPEN INPUT IN-FILE                           
    OPEN OUTPUT OUT-FILE
    .                         

READ-RELEASE.                                     
    PERFORM OPEN-FILES-RTN
    PERFORM READ-INPUT                            
     UNTIL EOF-SW = 'F'                          
    .

READ-INPUT.                                       
    READ IN-FILE                                  
     AT END MOVE 'F' TO EOF-SW
    END-READ                   
    RELEASE SORT-REC FROM IN-REC
    .

RETURN-WRITE.                                     
    MOVE SPACES TO EOF-SW
    PERFORM WRITE-FL                              
     UNTIL EOF-SW  = 'F'                         
    PERFORM CLOSE-FILES-RTN                      
    .

WRITE-FL.                                         
    RETURN SORT-FILE RECORD INTO OUT-REC          
     AT END MOVE 'F' TO EOF-SW
    END-RETURN
    WRITE OUT-REC
    .

CLOSE-FILES-RTN.           
    CLOSE IN-FILE OUT-FILE
    .

Я также изменил STOP RUN на GOBACK, который является гораздо более гибким, и удалил ваше имя первого абзаца, так как это не нужно и для людей, плохо знакомых с COBOL, слишком много подразумевает (сам COBOL не имеет понятия "main", поскольку это может быть быть уместным на других языках, которые вы, возможно, знаете).

person Bill Woodger    schedule 24.11.2015
comment
SU98PGM6 - это программа, над которой я работаю, я дважды проверил JCL, и, похоже, они в порядке. - person Barte; 24.11.2015
comment
Можете ли вы вставить в свою программу КОГДА-СКОРБИЛИРОВАННЫЙ ДИСПЛЕЙ? Скомпилируйте программу с помощью LIST и NOOFFSET, которые предоставят вам полный список сгенерированных инструкций. - person Bill Woodger; 24.11.2015
comment
Какой COBOL вы используете? Я предполагаю, что Enterprise COBOL, но какой выпуск (посмотрите список компиляции)? - person Bill Woodger; 24.11.2015
comment
Я скомпилировал, скомпилировал и запустил вашу исходную программу, включая выдумку NOT AT END, и она работает (как и ожидалось). Наибольшее смещение - X'000874 '. - person Bill Woodger; 24.11.2015
comment
Я только что проверил список Enterprise COBOL V5 для программы из 700 строк, и самое высокое смещение - X'0031E8 ', даже отдаленно не близко к тому смещению, которое вы даете. Ваша программа ВЫЗЫВАЕТСЯ другим, или только из EXEC PGM = SU98PGM6? - person Bill Woodger; 24.11.2015
comment
Я знаю, это звучит странно, но когда я добавляю WHEN-COMPILED-DISPLAY, программа запускается успешно. Когда я удаляю эту часть, она перестает работать. - person Barte; 24.11.2015
comment
Я просто звоню из EXEC PGM = SU98PGM6. - person Barte; 24.11.2015
comment
Как это не выполняется? Нет вывода, аварийное завершение, какое-то сообщение? - person Bill Woodger; 24.11.2015
comment
Когда я удаляю эту часть, она дает ту же ошибку S0C4, что и была. - person Barte; 24.11.2015
comment
С тем же смещением, что и раньше? - person Bill Woodger; 24.11.2015
comment
Да с тем же смещением, что и раньше. Кроме того, я только что понял, что если я помещаю DISPLAY прямо перед оператором SORT SORT-FILE, программа запускается успешно, но если я удалю DISPLAY, она выдаст ту же ошибку. - person Barte; 24.11.2015
comment
Хорошо спасибо. Это означает, что он прерван в программе SORT. Давайте выясним почему. Можете ли вы добавить свой JCL, параметры компиляции и набор данных спула SYSOUT из этого шага. И ответьте на этот вопрос о том, какую версию Enterprise COBOL вы используете. пожалуйста. - person Bill Woodger; 24.11.2015
comment
Мне действительно было сложно определить, что добавить к моему JCL. Я включил свой JCL выше, и мне было интересно, можете ли вы показать мне, как добавить эти вещи? Кроме того, я не знаю, какую версию COBOL я использую, и я не мог понять, что такое листинг компилятора. - person Barte; 24.11.2015