☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

quarta-feira, 24 de abril de 2024

WarGames Entra no CPD — O Dia em que o WOPR Deu S0C7, Joshua Pediu um Dump e o Programador COBOL Descobriu que ABEND Não Significa “Acabou o Mundo”

 

Bellacosa Mainframe e os abends em mainframe

☕ Um Café no Bellacosa Mainframe

WarGames Entra no CPD — O Dia em que o WOPR Deu S0C7, Joshua Pediu um Dump e o Programador COBOL Descobriu que ABEND Não Significa “Acabou o Mundo”

Ou: como S0C4, S0C7, SB37, S322, S806, dumps, JES2, JCL, datasets, storage, load libraries e um pouco de sangue-frio transformam “JOB ABENDED” de mensagem apocalíptica em pista de investigação — e por que a melhor maneira de vencer um ABEND talvez seja aprender a não jogar adivinhação


“Shall we play a game?”

A tela 3270 ficou silenciosa.

O programador COBOL Padawan tinha acabado de submeter seu primeiro JOB sozinho.

No canto superior da tela:

IKJ56250I JOB COBTST1(JOB01234) SUBMITTED

Ele sorriu.

— Funcionou.

Joshua, instalado misteriosamente em algum lugar entre uma LPAR de desenvolvimento, um terminal antigo e o NORAD, respondeu:

PROCESSING...

Alguns segundos depois:

IEF450I COBTST1 STEP01 - ABEND=S0C7

Silêncio.

O Padawan olhou para a tela.

Olhou para o café.

Olhou novamente para a tela.

— Destruí o mainframe?

Joshua respondeu:

WOULD YOU LIKE TO PLAY
GLOBAL THERMONUCLEAR WAR?

— Não, obrigado. Só queria executar um COBOL.

Bem-vindo ao universo dos ABENDs.

E antes que alguém aperte o botão vermelho, precisamos entender uma coisa fundamental:

ABEND não significa que o mainframe morreu.

Normalmente significa apenas:

um programa, step ou tarefa terminou de maneira anormal.

E isso muda completamente a investigação.



1. Primeiro contato — afinal, o que é ABEND?

ABEND é abreviação histórica de:

ABnormal END

Ou seja:

término anormal.

Em um processamento normal, imaginamos algo parecido com:

JOB
 |
 +-- STEP01
 |
 +-- STEP02
 |
 +-- STEP03
 |
 `-- FIM

Cada programa termina conforme esperado.

Por exemplo:

RETURN CODE = 0000

Mas algo pode acontecer durante a execução:

JOB
 |
 +-- STEP01   RC=0000
 |
 +-- STEP02   ABEND S0C7
 |
 X

O sistema interrompe aquele processamento.

A primeira coisa que o iniciante precisa aprender é não misturar três conceitos:

RETURN CODE
ABEND
SQLCODE

Eles podem aparecer no mesmo trabalho, mas não significam a mesma coisa.

Um RC=0004, por exemplo, normalmente indica que determinado programa terminou e devolveu um código.

Já:

S0C7

significa que houve uma exceção durante a execução.

E:

SQLCODE -811

é uma condição reportada pelo Db2.

São universos relacionados, mas distintos.



2. O detalhe que engana todo Padawan: é zero, não letra O

Observe:

S0C4
S0C7

O caractere depois do S é:

0

zero.

Não:

O

Portanto:

S0C7

e não:

SOC7

Essa pequena diferença já entregou muitos novatos aos Sith Lords do suporte.

Também encontramos códigos como:

S806
SB37
S322

O formato varia porque esses códigos representam diferentes System Completion Codes.



3. Quem realmente matou o JOB?

Em WarGames, o drama nasce porque todo mundo olha para uma tela e começa a imaginar imediatamente o pior cenário possível.

No mainframe acontece algo parecido.

O operador vê:

ABEND S0C7

O programador conclui:

— Problema no sistema operacional.

O sysprog responde:

— É seu COBOL.

O DBA fala:

— Não tem nada a ver com Db2.

O storage pergunta:

— Por que vocês estão me chamando?

Joshua observa silenciosamente.

O procedimento correto é muito menos cinematográfico:

1. identificar o JOB
2. identificar o STEP
3. identificar o ABEND
4. localizar as mensagens
5. consultar dump/log
6. identificar programa/instrução
7. verificar causa
8. corrigir
9. recompilar, se necessário
10. executar novamente

Isso é investigação.

Não adivinhação.


4. O primeiro jogo de Joshua — S0C7

Talvez seja o ABEND mais famoso entre programadores COBOL.

S0C7

Geralmente está associado a uma Data Exception.

Traduzindo para o mundo COBOL:

algum dado que deveria ser numérico não contém uma representação numérica válida para a operação executada.

Imagine:

01  WS-VALOR      PIC 9(05).

E por algum problema de arquivo, layout ou movimentação, a área contém algo incompatível.

Então executamos:

ADD 1 TO WS-VALOR

O processador tenta realizar uma operação decimal.

Só que os bytes armazenados não representam o número esperado.

Resultado possível:

S0C7

O clássico culpado

Considere:

01 WS-NUMERO PIC 9(5).

MOVE '12A45' TO WS-NUMERO.
ADD 1 TO WS-NUMERO.

Dependendo da representação e do contexto, temos material perfeito para uma exceção de dados quando aquela área for usada aritmeticamente.

O verdadeiro problema, entretanto, nem sempre está na linha que deu o ABEND.

Esse é um princípio crucial.

A instrução:

COMPUTE WS-TOTAL = WS-VALOR + WS-TAXA

pode apenas ser o lugar onde a corrupção foi descoberta.

A corrupção talvez tenha acontecido 500 linhas antes.


5. Packed decimal — onde o S0C7 encontra seu habitat favorito

No COBOL empresarial encontramos muito:

PIC S9(7)V99 COMP-3

Isso é packed decimal.

Os dígitos são armazenados compactados em nibbles.

Por exemplo, conceitualmente, os valores são codificados em hexadecimal em vez de armazenados simplesmente como caracteres ASCII/EBCDIC visíveis.

O último nibble normalmente contém o sinal.

Valores típicos de sinal incluem:

C = positivo
D = negativo
F = unsigned/positivo em determinados contextos

Se uma área COMP-3 recebe bytes inválidos e depois participa de uma operação decimal, temos forte candidato a:

S0C7

Imagine um layout errado:

Arquivo real:

01 REGISTRO-REAL.
   05 CODIGO       PIC X(05).
   05 VALOR        PIC S9(7)V99 COMP-3.

Seu programa acredita que seja:

01 REGISTRO-ERRADO.
   05 CODIGO       PIC X(06).
   05 VALOR        PIC S9(7)V99 COMP-3.

Um byte mudou de posição.

Agora você não está lendo VALOR.

Está lendo uma mistura de bytes.

Joshua pergunta:

“Would you like to play S0C7?”


6. Checklist Bellacosa para um S0C7

Quando aparecer:

S0C7

não saia alterando código aleatoriamente.

Investigue:

O campo é DISPLAY?
COMP?
COMP-3?

O layout do arquivo está correto?

O copybook é a versão correta?

Houve REDEFINES?

Existe MOVE entre campos incompatíveis?

O registro possui o comprimento esperado?

O programa inicializou todas as áreas?

Existe arquivo antigo sendo processado com layout novo?

O erro apareceu depois de alteração de copybook?

E uma pergunta particularmente poderosa:

Qual era o conteúdo hexadecimal do campo no momento do ABEND?

O dump pode responder isso.

Aqui começamos a perceber por que um dump não é lixo.

Ele é a fotografia da cena do crime.


7. Segundo jogo — S0C4

Agora Joshua resolve jogar com memória.

S0C4

Esse ABEND está geralmente ligado a problemas de acesso à memória, proteção ou endereçamento.

Em linguagem humana:

o programa tentou acessar uma área de storage que não deveria ou não poderia acessar daquela maneira.

A imagem apresentada resume isso como:

Protection / memory access error.

É uma boa simplificação para o iniciante.

Mas o universo real é mais profundo.

Um S0C4 pode surgir por diversas situações, incluindo erros de endereço, referências inválidas, subscripts incorretos e problemas relacionados ao uso de storage.


8. O array que atravessou a fronteira do NORAD

Considere:

01 WS-TABELA.
   05 WS-ITEM PIC X(10) OCCURS 10 TIMES.

01 WS-I PIC 99.

Agora:

MOVE 50 TO WS-I

DISPLAY WS-ITEM(WS-I)

Temos apenas:

1 até 10

mas estamos tentando acessar:

50

Dependendo do programa, compilação e circunstâncias, podemos acabar acessando storage além da estrutura esperada.

Esse tipo de erro é especialmente perigoso porque memória não respeita a nossa intenção.

O processador não pensa:

“Ah, Vagner queria provavelmente o elemento número 5.”

Ele usa o endereço calculado.

Se estiver errado, estará errado em velocidade de mainframe.


9. Subscript versus index

COBOL possui mecanismos de tabelas que o iniciante precisa compreender.

Por exemplo:

05 WS-CLIENTE OCCURS 100 TIMES
   INDEXED BY IDX-CLIENTE.

Podemos navegar com índice:

SET IDX-CLIENTE TO 1

ou utilizar subscripts em determinadas definições:

MOVE WS-CLIENTE(WS-I)

Erros nessa lógica podem produzir acesso a áreas inesperadas.

Uma proteção importante durante desenvolvimento é utilizar opções adequadas de compilação e runtime para ajudar a detectar referências fora dos limites.

Em ambientes Enterprise COBOL modernos, opções como verificação de limites podem transformar bugs misteriosos em diagnósticos muito melhores.

Ou seja:

debugabilidade também é uma decisão de compilação.


10. S0C4 não significa automaticamente “memória cheia”

Essa confusão merece destaque.

S0C4 não deve ser traduzido simplesmente como:

acabou memória.

Normalmente o raciocínio é mais próximo de:

ocorreu uma exceção relacionada ao acesso/proteção/endereço de storage.

É diferente de:

não há memória suficiente

Por isso precisamos ler as mensagens associadas e o dump.

O código do ABEND é uma pista.

Não é necessariamente o diagnóstico completo.


11. Terceiro jogo — SB37

Agora o míssil nuclear é substituído por algo aparentemente muito menos dramático:

um dataset.

O JOB escreve:

AAAA
BBBB
CCCC
...

E continua.

E continua.

Até o z/OS dizer:

SB37

Em termos simplificados:

o dataset ficou sem espaço disponível para continuar a alocação necessária.

É o equivalente mainframe daquele momento:

Disk full

Mas com detalhes importantes relacionados a datasets, volumes, extents e alocação.


12. SPACE no JCL — a pequena linha que pode derrubar o STEP

Observe:

//OUTFILE DD DSN=BELLACOSA.TESTE.OUT,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(TRK,(10,5)),
//            UNIT=SYSDA

Simplificando:

10 tracks = alocação primária
 5 tracks = incrementos secundários

Quando o dataset precisa crescer, o sistema tenta obter espaço adicional.

Se não conseguir continuar expandindo adequadamente, podemos encontrar situações como:

SB37

Há outros ABENDs relacionados a espaço, como:

SD37
SE37

E eles não devem ser tratados como absolutamente equivalentes.

Cada um fornece pistas sobre o que aconteceu durante a tentativa de alocação/extensão.


13. O erro nem sempre é “aumente o SPACE”

Aqui mora uma armadilha maravilhosa.

O programador vê:

SB37

e faz:

SPACE=(CYL,(9999,9999))

Problema resolvido?

Talvez.

Ou talvez tenha escondido algo muito pior.

Imagine que seu programa deveria escrever:

100.000 registros

mas devido a um loop:

PERFORM UNTIL EOF
    WRITE REG-SAIDA
END-PERFORM

o EOF nunca muda.

O programa escreve eternamente.

O dataset cresce.

Até acabar espaço.

O sintoma é:

SB37

Mas a causa lógica é:

LOOP INFINITO

Joshua está aprendendo.

E agora está fabricando registros em velocidade industrial.


14. Quarto jogo — S322

Se existe um código perfeito para um crossover entre JCL e WarGames, é:

S322

Em termos gerais, ele indica que o STEP excedeu determinado limite de tempo de execução permitido.

A imagem resume:

Job exceeded time limit.

Para o iniciante funciona.

Tecnicamente é bom lembrar que o problema normalmente é associado ao step/processamento e seu limite de CPU/tempo aplicável, não necessariamente ao JOB inteiro da forma genérica sugerida pela frase.

Uma causa clássica?

Loop.

PERFORM UNTIL WS-FIM = 'S'
    CONTINUE
END-PERFORM

Se:

WS-FIM

jamais se tornar:

S

parabéns.

Você inventou o moto-perpétuo COBOL.

O sistema, menos otimista, eventualmente intervém.


15. TIME no JCL

Podemos encontrar parâmetros como:

//STEP01 EXEC PGM=MEUPGM,TIME=5

O significado exato deve ser interpretado conforme a sintaxe e contexto do JCL, mas o ponto é que limites de execução podem existir.

Então, diante de S322, pergunte:

O programa entrou em loop?

O volume processado aumentou?

Existe READ que não avança?

Existe PERFORM sem saída?

Um SQL está extremamente custoso?

Houve mudança no comportamento de I/O?

O limite configurado é simplesmente inadequado para o workload?

Não conclua imediatamente:

“Preciso aumentar TIME.”

É o equivalente a descobrir que o carro está com acelerador preso e resolver o problema instalando um tanque de combustível maior.


16. O clássico loop de arquivo

Observe esta beleza:

PERFORM UNTIL WS-EOF = 'S'

    IF WS-TIPO = 'A'
       PERFORM PROCESSA-A
    END-IF

END-PERFORM.

Cadê o:

READ ARQUIVO

?

Joshua responde:

INTERESTING GAME.
THE ONLY WINNING MOVE IS TO READ THE NEXT RECORD.

17. Quinto jogo — S806

A imagem mostra:

806
Load module not found

Para nosso treinamento, vamos escrever corretamente o código de sistema como:

S806

Esse é um dos mais didáticos para entender a relação entre:

JCL
programa
load module
load library
STEPLIB
JOBLIB
link-edit

Imagine:

//STEP01 EXEC PGM=BELL001

O sistema precisa localizar um módulo executável chamado:

BELL001

Mas ele não aparece nas bibliotecas onde a busca está sendo realizada.

Resultado possível:

S806

18. “Mas o source existe!”

Essa frase já ecoou em milhares de CPDs:

— O programa existe! Estou vendo o membro no PDS!

Sim.

Mas você pode estar olhando para:

BELLACOSA.COBOL.SOURCE(BELL001)

Isso é source.

O sistema precisa executar o load module/program object correspondente.

Conceitualmente:

SOURCE
   |
   v
COMPILER
   |
   v
OBJECT
   |
   v
LINK-EDIT / BINDER
   |
   v
LOAD MODULE / PROGRAM OBJECT

Executar COBOL não significa o z/OS abrir seu source e interpretar:

MOVE A TO B

O programa precisa ter passado pelo processo necessário para produzir algo executável.


19. STEPLIB — o mapa que Joshua perdeu

Imagine:

//STEP01 EXEC PGM=BELL001
//STEPLIB DD DSN=BELLACOSA.LOADLIB,DISP=SHR

Estamos indicando uma biblioteca onde o sistema poderá procurar o programa.

Agora imagine:

BELL001 está em:

BELLACOSA.LOAD.PROD

mas o JCL usa:

BELLACOSA.LOAD.TEST

Joshua procura.

Não encontra.

S806

Perguntas úteis:

O nome em PGM= está correto?

O módulo foi link-editado?

O binder terminou com sucesso?

O módulo está realmente nessa LOADLIB?

STEPLIB aponta para a biblioteca correta?

JOBLIB interfere na busca?

Existe diferença entre ambiente DEV, QA e PROD?

Uma nova versão foi compilada mas não implantada?

20. O grande mapa dos cinco ABENDs

Guarde esta associação inicial:

CódigoPense primeiro em
S0C4acesso/endereço/proteção de storage
S0C7dados numéricos inválidos / data exception
SB37problema de espaço/extensão de dataset
S322limite de execução/tempo excedido
S806programa/load module não localizado

Mas acrescente mentalmente:

“Pense primeiro em...”

e não:

“A causa obrigatoriamente é...”

Essa diferença separa troubleshooting de superstição.


21. O verdadeiro professor chama-se JES

Depois do ABEND, uma das primeiras paradas costuma ser a saída do JOB.

No universo z/OS, frequentemente estamos navegando por elementos como:

JES2
SDSF
JESMSGLG
JESJCL
JESYSMSG
SYSOUT
SYSPRINT
CEEDUMP
SYSUDUMP
SYSABEND

Nem todos aparecerão em todos os casos.

Mas isso cria uma regra:

Nunca investigue um ABEND olhando apenas para o código final.

Leia as mensagens próximas ao momento da falha.

Por exemplo:

IEF...
IGD...
IEC...
CEE...
IGZ...

Os prefixos das mensagens já podem indicar qual componente está conversando com você.

O z/OS é quase uma cidade onde cada repartição começa suas cartas com uma assinatura diferente.


22. SDSF — nossa sala de guerra

O Padawan abre o SDSF.

Entra no painel de jobs.

Localiza:

COBTST1

E começa a investigação.

Fluxo mental:

ST
 |
 +--> localizar JOB
       |
       +--> verificar RC / ABEND
             |
             +--> localizar STEP
                   |
                   +--> mensagens
                         |
                         +--> SYSOUT
                               |
                               +--> dump

A pergunta não é:

“Onde está escrito S0C7?”

A pergunta é:

“O que estava acontecendo imediatamente antes do S0C7?”


23. Procure o STEP, não apenas o JOB

Imagine:

//JOB01 JOB ...
//STEP10 EXEC PGM=PROGA
//STEP20 EXEC PGM=PROGB
//STEP30 EXEC PGM=PROGC

Resultado:

STEP10 RC=0000
STEP20 ABEND=S0C7
STEP30 FLUSH

Temos uma informação gigantesca:

PROGA provavelmente terminou
PROGB falhou
PROGC nem executou

Então não comece depurando PROGC.

Parece óbvio.

Sob pressão de produção às 02:37, deixa de ser.


24. Cond code e ABEND não são irmãos gêmeos

Outro conceito importante.

Um programa pode terminar:

RC=0000

Outro:

RC=0004

Outro:

RC=0008

Outro pode sofrer:

ABEND S0C7

Return codes são definidos/conduzidos pelo software conforme sua lógica e convenções.

ABENDs representam término anormal.

Por exemplo, COBOL pode fazer:

MOVE 8 TO RETURN-CODE
GOBACK

O programa terminou deliberadamente com RC 8.

Isso não é igual a sofrer uma exceção e acabar em S0C7.


25. E o misterioso Uxxxx?

Nem todo ABEND começa com S.

Você também poderá encontrar algo como:

U4038

O U remete a user abend.

Ou seja, o término foi solicitado por software/aplicação/runtime em determinada condição.

Um clássico em ambientes Language Environment pode envolver códigos dessa família associados a erros detectados durante execução.

Isso nos dá dois grandes mundos conceituais:

Sxxx = System completion code
Uxxxx = User completion code

Para o Padawan, essa distinção já vale ouro.


26. Dump — a autópsia do programa

Um dump pode parecer inicialmente uma espécie de pergaminho Sith:

PSW
GPR0
GPR1
GPR2
...
OFFSET
TRACEBACK
STORAGE
HEX
MODULE

O iniciante pensa:

— Preciso aprender hexadecimal, assembler e arquitetura z/Architecture inteira antes de corrigir meu COBOL?

Não.

Mas, conforme você evolui, aprender a ler informações de dump muda radicalmente sua capacidade de suporte.

Procure inicialmente:

Nome do programa
Código do ABEND
Offset
Statement
Entry point
Call chain
Variáveis relevantes
Mensagem do runtime

Compilação com informações adequadas de debug pode permitir uma correlação muito melhor entre:

OFFSET

e:

linha COBOL

Essa é uma das grandes vantagens de manter listings de compilação.


27. Nunca jogue fora o compile listing

O compile listing parece inútil enquanto tudo funciona.

Quando o programa cai em produção:

OFFSET +00001A72

de repente aquele listing vira o Santo Graal.

Dependendo das opções e tooling utilizados, ele pode ajudar a relacionar:

offset
paragraph
statement
generated code
data definitions

Por isso equipes maduras conservam artefatos apropriados das builds.

Não somente:

SOURCE.COBOL

Mas também aquilo que permite provar:

qual versão foi compilada, como foi compilada e qual executável foi gerado.

Isso é DevOps antes de DevOps receber esse nome.


28. Curiosidade Bellacosa — ABEND é quase uma filosofia operacional

Mainframes nasceram em um mundo em que jobs podiam processar volumes enormes sem alguém olhando continuamente para a tela.

Logo o sistema precisava dizer precisamente:

terminou?

Se sim:

como terminou?

E se algo deu errado:

por quê?

Por isso temos uma cultura inteira ao redor de:

completion codes
return codes
messages
logs
dumps

Cloud, Kubernetes e observabilidade moderna redescobriram ideias semelhantes com:

exit codes
logs
events
traces
metrics
crash dumps
health checks

O CPD de 1975 provavelmente reconheceria muita coisa em uma War Room de 2026.

Só perguntaria por que colocaram emojis no dashboard.


29. Método Bellacosa de sete perguntas

Quando um programa cair, faça estas perguntas nesta ordem:

1. Qual JOB falhou?

JOBNAME?
JOBID?

2. Qual STEP falhou?

STEP10?
STEP20?
PROCSTEP?

3. Qual programa estava rodando?

PGM=?

4. Qual foi o ABEND?

S0C7?
S0C4?
S806?
...

5. Que mensagens apareceram antes e depois?

Não leia apenas uma linha.

Contexto importa.

6. Qual foi a última alteração?

Pergunta brutalmente poderosa:

Novo source?
Novo copybook?
Novo arquivo?
Novo JCL?
Nova loadlib?
Novo volume de dados?
Nova versão do compilador?

7. Consigo reproduzir?

O problema reproduzível deixa de ser fantasma.

Vira experimento.


30. O jogo mais perigoso chama-se “tentar coisas”

Joshua apresenta:

S0C7

O programador altera:

REGION=0M

Não resolveu.

Aumenta SPACE.

Não resolveu.

Troca DISP.

Não resolveu.

Recompila.

Não resolveu.

Executa novamente.

Não resolveu.

Troca a STEPLIB.

Agora surge:

S806

Parabéns.

Transformamos um incidente em dois.

Troubleshooting profissional segue hipóteses:

EVIDÊNCIA
   ↓
HIPÓTESE
   ↓
TESTE
   ↓
RESULTADO
   ↓
CONCLUSÃO

Não:

ABEND
 ↓
PÂNICO
 ↓
ALTERA TUDO
 ↓
REZA

31. Easter egg — Joshua encontra o JCL

Joshua pergunta:

SHALL WE PLAY A GAME?

O operador responde:

//WARGAME JOB (NORAD),'JOSHUA',
//        CLASS=A,
//        MSGCLASS=X
//STEP01 EXEC PGM=WOPR
//STEPLIB DD DSN=NORAD.DEFENSE.LOAD,DISP=SHR
//INPUT   DD *
GLOBAL THERMONUCLEAR WAR
/*

JES2:

JOB SUBMITTED

Três segundos depois:

IEF450I WARGAME STEP01 - ABEND=S806

Operador:

— Graças a Deus esqueceram de instalar o load module.

Às vezes um S806 salva a humanidade.


32. O exercício do Padawan — provoque um erro controladamente

Em laboratório, entender falhas controladas é excelente treinamento.

Nunca faça isso em produção.

Crie programas simples destinados especificamente a estudar:

S0C7
limites de OCCURS
arquivo crescendo
loops
STEPLIB incorreta

A ideia não é memorizar cinco códigos.

É aprender a cadeia:

CÓDIGO
   ↓
COMPILAÇÃO
   ↓
LINK
   ↓
JCL
   ↓
EXECUÇÃO
   ↓
JES
   ↓
ABEND
   ↓
DIAGNÓSTICO

Quando você entende a cadeia, dezenas de códigos deixam de parecer mágicos.


33. Laboratório mental 1 — S0C7

Você tem:

01 WS-TOTAL PIC S9(7)V99 COMP-3.

O programa sofre:

S0C7

Pergunte:

Quem escreveu nessa área?

Foi MOVE?

Foi arquivo?

Foi Db2?

Foi outra estrutura?

Existe REDEFINES?

O copybook coincide com o registro físico?

Não olhe apenas para:

ADD WS-TOTAL TO ...

A instrução pode ser apenas a vítima que encontrou o cadáver.


34. Laboratório mental 2 — S0C4

Programa cai após:

MOVE WS-TABELA(WS-I) TO WS-SAIDA

Pergunte imediatamente:

Qual valor de WS-I?

Qual OCCURS?

Existe DEPENDING ON?

Existe subscript fora da faixa?

Alguma área foi sobrescrita?

Existe CALL utilizando parâmetros incorretos?

Interfaces entre programas são particularmente interessantes.

Se:

CALL 'PGM2' USING A B C

mas PGM2 interpreta parâmetros incompatíveis, podemos produzir estragos memoráveis.


35. Laboratório mental 3 — SB37

Dataset lotou.

Antes de simplesmente aumentar espaço, verifique:

Quantos registros eram esperados?

Quantos foram escritos?

LRECL?

RECFM?

SPACE?

Primário/secundário?

Volume disponível?

Extents?

Houve crescimento anormal?

Se ontem o arquivo tinha:

500 MB

e hoje tentou chegar a:

80 GB

não comece culpando o storage.

Pergunte por quê.


36. Laboratório mental 4 — S322

Pergunte:

Onde o programa estava?

Quantos registros processou?

Existe progresso no contador?

READ avança?

Cursor Db2 avança?

Laço tem condição de saída?

Foi aumento legítimo de workload?

Um contador de diagnóstico pode ajudar enormemente em desenvolvimento:

ADD 1 TO WS-CONTADOR

IF FUNCTION MOD(WS-CONTADOR 10000) = 0
   DISPLAY 'PROCESSADOS: ' WS-CONTADOR
END-IF

Não necessariamente colocaríamos exatamente isso em toda produção eternamente.

Mas como técnica de investigação, observar progresso é ouro.


37. Laboratório mental 5 — S806

Seu JCL:

//STEP01 EXEC PGM=ABC123

Cheque:

ABC123 existe?

Foi bindado/link-editado?

Está na biblioteca correta?

STEPLIB está certa?

O módulo tem esse nome?

Deploy ocorreu?

Existe alias?

Ambiente está apontando para QA ou DEV?

Um detalhe delicioso:

o source pode chamar-se:

PROGRAMA1

e o executável implantado possuir outro nome conforme processo de build.

Nunca presuma.

Verifique.


38. ABEND também ensina arquitetura

Esses cinco códigos parecem erros isolados.

Mas observe o que aprendemos:

S0C7

Ensina:

representação de dados
PIC
COMP-3
layouts
copybooks

S0C4

Ensina:

storage
endereçamento
arrays
CALL
memória

SB37

Ensina:

datasets
DASD
SPACE
extents
JCL

S322

Ensina:

CPU
loops
execução batch
limites
performance

S806

Ensina:

build
binder
load libraries
STEPLIB
execução

Ou seja:

estudar ABEND é estudar o próprio mainframe.


39. O erro moderno: pedir imediatamente à IA

Em 2026 temos outra personagem sentada na sala do WOPR.

O programador copia:

ABEND S0C7

para uma IA e pergunta:

“Corrija meu programa.”

A IA pode explicar brilhantemente as causas comuns.

Mas faltam informações.

Ela não viu:

dump
layout
input
listing
JCL
alteração recente
conteúdo hexadecimal

A pergunta melhor seria:

Meu STEP STEP20 executando programa FATU001
terminou com S0C7.

O dump aponta para o statement 1487.
A variável usada é WS-VALOR PIC S9(7)V99 COMP-3.
O valor veio do campo ARQ-VALOR de um copybook alterado ontem.

Quais hipóteses devo testar?

Agora existe contexto.

IA não elimina troubleshooting.

Ela pode acelerar troubleshooting bem feito.


40. Nunca coloque dados sensíveis do dump em qualquer IA pública

Aqui aparece nosso RACF imaginário.

Dumps podem conter:

nomes
contas
identificadores
dados financeiros
credenciais
tokens
dados pessoais
informações de infraestrutura

Portanto:

sanitizar dados faz parte do diagnóstico moderno.

Não copie um dump de produção inteiro para um serviço externo apenas porque quer descobrir um S0C7.

Joshua pode ser simpático.

Compliance talvez não seja.


41. O pequeno dicionário do sobrevivente

O Padawan deve reconhecer:

ABEND

Término anormal.

RC

Return Code.

CC

Condition Code, dependendo do contexto.

STEP

Unidade executável de um JOB.

SYSOUT

Saída gerada durante execução.

DUMP

Estado capturado para diagnóstico.

LOADLIB

Biblioteca contendo programas executáveis.

STEPLIB

DD utilizado para definir bibliotecas privadas de busca para aquele step.

JOBLIB

Biblioteca de busca aplicável aos steps do job dentro das regras pertinentes.

SPACE

Parâmetro relacionado à alocação de espaço do dataset.

OCCURS

Estrutura de repetição/tabela COBOL.

COMP-3

Representação decimal packed.


42. Uma rotina realista de incidente

Agora estamos às 03:00.

Produção.

JOB:

FATUR001

falhou.

Passo a passo:

1. Abrir SDSF

Encontrar:

FATUR001
2. Identificar step

Resultado:

STEP040
3. Identificar programa
FATU847
4. Identificar falha
S0C7
5. Ler mensagens

Buscar runtime/dump.

6. Identificar statement/offset

Suponha:

PARAGRAPH CALCULA-TOTAL
7. Identificar operandos
VALOR-BRUTO
TAXA
TOTAL
8. Inspecionar dados

Descobre-se que VALOR-BRUTO contém representação inválida.

9. Descobrir origem

Veio do arquivo produzido por STEP030.

10. Descobrir alteração

Copybook mudou ontem.

Agora temos causa provável.

Não:

“COBOL é antigo.”

Não:

“mainframe travou.”

Não:

“Db2 está estranho.”

Temos evidência.


43. O detalhe mais importante: encontre a causa raiz

Imagine que corrigimos um registro manualmente.

JOB roda.

Vitória?

Ainda não.

Precisamos perguntar:

Por que aquele registro ficou inválido?

Talvez:

programa produtor incorreto
copybook incompatível
deploy parcial
arquivo antigo
campo não inicializado
erro de interface
conversão equivocada

Caso contrário, amanhã:

S0C7

volta.

E Joshua pergunta novamente:

SHALL WE PLAY A GAME?

44. Prevenindo em vez de apenas corrigindo

O Jedi Mainframe não é aquele que conhece 500 ABEND codes de cabeça.

É aquele que cria sistemas que fornecem evidências boas.

Algumas práticas:

  • mantenha listings e artefatos de build;

  • versionamento de source e copybooks;

  • valide layouts;

  • controle deploy de load modules;

  • adote testes;

  • use opções de compilação apropriadas;

  • registre entradas críticas;

  • monitore crescimento de datasets;

  • monitore CPU e elapsed time;

  • trate arquivos e SQLCODE corretamente;

  • mantenha documentação de JCL;

  • preserve rastreabilidade entre source e executável.

A maior evolução acontece quando o sistema deixa de responder apenas:

DEU ERRO

e começa a responder:

ONDE
QUANDO
COM QUAL DADO
EM QUAL VERSÃO
DEPOIS DE QUAL ALTERAÇÃO

Isso é observabilidade.


45. Curiosidade — o mainframe já fazia “observabilidade” quando a palavra nem era moda

Hoje ouvimos:

logs
metrics
traces
telemetry
observability

O ecossistema mainframe possui há décadas uma enorme cultura de:

SMF
JES logs
system messages
dumps
accounting
performance data
audit records

Não são exatamente a mesma coisa das stacks modernas, claro.

Mas a filosofia é familiar:

um sistema crítico precisa deixar rastros suficientes para explicar o que aconteceu.

Os hipsters do Kubernetes descobriram o SYSOUT.

Só trocaram a fonte verde por Grafana.


46. A regra WarGames do ABEND

No final de WarGames, Joshua aprende algo fundamental examinando todas as possibilidades.

No mainframe, o programador também precisa parar de jogar:

“Qual alteração aleatória fará o JOB ficar verde?”

O jogo correto é:

“Qual evidência explica por que ele ficou vermelho?”

São filosofias completamente diferentes.

A primeira produz:

tentativa
erro
tentativa
erro
tentativa
milagre

A segunda produz:

observação
hipótese
teste
causa
correção
prevenção

47. Cheatsheet do Padawan

Quando aparecer:

S0C7

Pense:

DADO NUMÉRICO INVÁLIDO

Procure:

COMP-3
MOVE
arquivo
copybook
REDEFINES
layout
campo não inicializado

S0C4

Pense:

ACESSO/ENDEREÇO DE STORAGE

Procure:

OCCURS
subscript
index
CALL
ponteiros/referências
área sobrescrita

SB37

Pense:

ESPAÇO DO DATASET

Procure:

SPACE
volume
extents
crescimento
loop de escrita

S322

Pense:

TEMPO/EXECUÇÃO EXCESSIVA

Procure:

loop
READ
volume
SQL
CPU
condição de saída

S806

Pense:

PROGRAMA NÃO ENCONTRADO

Procure:

PGM=
STEPLIB
JOBLIB
LOADLIB
binder
deploy
nome do módulo

48. O mapa completo

Nossa aventura começou com cinco códigos.

Mas agora eles formam uma pequena arquitetura:

                    +------------------+
                    |       JOB        |
                    +--------+---------+
                             |
                             v
                    +------------------+
                    |       JCL        |
                    +--------+---------+
                             |
            +----------------+----------------+
            |                                 |
            v                                 v
       +---------+                       +-----------+
       | PROGRAM |                       | DATASETS  |
       +----+----+                       +-----+-----+
            |                                  |
            |                                  +--> SB37
            |
            +--> dados inválidos ------------> S0C7
            |
            +--> storage inválido -----------> S0C4
            |
            +--> loop/tempo -----------------> S322

      Antes de executar:
             |
             +--> módulo ausente ------------> S806

Esse desenho vale mais do que decorar uma tabela.

Ele mostra onde procurar.


49. Easter egg final — WOPR pede acesso à produção

Joshua:

ACCESS PRODUCTION?

RACF:

ICH408I USER(JOSHUA) GROUP(NORAD)
  INSUFFICIENT ACCESS AUTHORITY

Joshua:

A STRANGE GAME.
THE ONLY WINNING MOVE IS NOT TO DEPLOY ON FRIDAY.

O sysprog lentamente fecha o terminal.

O Padawan COBOL anota no caderno:

REGRA 1:
NUNCA CONFUNDIR S0C7 COM SOC7.

REGRA 2:
LER O JES.

REGRA 3:
OLHAR O STEP.

REGRA 4:
NÃO ALTERAR TUDO AO MESMO TEMPO.

REGRA 5:
DESCOBRIR CAUSA RAIZ.

REGRA 6:
NÃO DAR UPDATE EM PRODUÇÃO PARA JOSHUA.

Essa última não está no manual IBM.

Mas deveria.


Epílogo — a única jogada vencedora é aprender a ler a evidência

No início desta viagem, aqueles códigos pareciam mensagens criptografadas:

S0C4
S0C7
SB37
S322
S806

Agora podemos enxergá-los como pistas.

S0C4 pode nos levar ao mundo de storage e endereçamento.

S0C7 nos obriga a entender representação numérica, COMP-3, layouts e dados.

SB37 abre a porta para datasets, DASD e alocação.

S322 ensina sobre execução, loops, CPU e limites.

S806 revela toda a cadeia de compilação, binder, LOADLIB, STEPLIB e deploy.

E talvez esta seja a maior lição para quem começa em COBOL:

um ABEND não é apenas um erro.

É uma aula de arquitetura embrulhada em uma mensagem desagradável.

O programador iniciante olha:

JOB ABENDED

e pensa:

“Algo quebrou.”

O programador experiente olha a mesma mensagem e pergunta:

Qual JOB?
Qual STEP?
Qual programa?
Qual código?
Qual mensagem?
Qual offset?
Qual dado?
Qual versão?
O que mudou?

Essa mudança de mentalidade é gigantesca.

Porque mainframe não exige que você conheça todas as respostas.

Ele exige que você saiba onde procurar as perguntas certas.

Joshua finalmente apaga da tela:

GLOBAL THERMONUCLEAR WAR

e escreve:

S0C7 DIAGNOSTIC LAB

O Padawan toma um gole de café.

— Podemos jogar.

Joshua responde:

EXCELLENT.

PLEASE PROVIDE:
JOBNAME
STEPNAME
PROGRAM NAME
ABEND CODE
COMPILE LISTING
DUMP

O Padawan sorri.

Agora sim.

Não temos mais um jogador apertando botões aleatórios.

Temos um programador mainframe investigando uma falha.

E no Bellacosa Mainframe, essa é a diferença entre alguém que simplesmente executa COBOL...

...e alguém que começa realmente a entender z/OS.

Fim de JOB.

IEF142I WARGAME STEP99 - STEP WAS EXECUTED - COND CODE 0000

A humanidade sobreviveu.

E melhor ainda:

o Padawan aprendeu a abrir o SDSF antes de culpar o mainframe.

☕ Gostou deste café?
Siga o Bellacosa Mainframe e acompanhe os próximos artigos.
SEGUIR O BLOG

Sem comentários:

Enviar um comentário

De Fã para Fã. Conteúdo não oficial produzido como homenagem, comentário, análise ou paródia. Personagens, marcas e obras eventualmente mencionados pertencem aos seus respectivos titulares.
Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...