| 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) SUBMITTEDEle 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=S0C7Silê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
|
`-- FIMCada programa termina conforme esperado.
Por exemplo:
RETURN CODE = 0000Mas algo pode acontecer durante a execução:
JOB
|
+-- STEP01 RC=0000
|
+-- STEP02 ABEND S0C7
|
XO sistema interrompe aquele processamento.
A primeira coisa que o iniciante precisa aprender é não misturar três conceitos:
RETURN CODE
ABEND
SQLCODEEles 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á:
S0C7significa 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
S0C7O caractere depois do S é:
0zero.
Não:
OPortanto:
S0C7e não:
SOC7Essa pequena diferença já entregou muitos novatos aos Sith Lords do suporte.
Também encontramos códigos como:
S806
SB37
S322O 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 S0C7O 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 novamenteIsso é investigação.
Não adivinhação.
4. O primeiro jogo de Joshua — S0C7
Talvez seja o ABEND mais famoso entre programadores COBOL.
S0C7Geralmente 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-VALORO processador tenta realizar uma operação decimal.
Só que os bytes armazenados não representam o número esperado.
Resultado possível:
S0C7O 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-TAXApode 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-3Isso é 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 contextosSe uma área COMP-3 recebe bytes inválidos e depois participa de uma operação decimal, temos forte candidato a:
S0C7Imagine 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:
S0C7nã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.
S0C4Esse 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é 10mas estamos tentando acessar:
50Dependendo 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 1ou 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 suficientePor 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:
SB37Em termos simplificados:
o dataset ficou sem espaço disponível para continuar a alocação necessária.
É o equivalente mainframe daquele momento:
Disk fullMas 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=SYSDASimplificando:
10 tracks = alocação primária
5 tracks = incrementos secundáriosQuando o dataset precisa crescer, o sistema tenta obter espaço adicional.
Se não conseguir continuar expandindo adequadamente, podemos encontrar situações como:
SB37Há outros ABENDs relacionados a espaço, como:
SD37
SE37E 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ê:
SB37e faz:
SPACE=(CYL,(9999,9999))Problema resolvido?
Talvez.
Ou talvez tenha escondido algo muito pior.
Imagine que seu programa deveria escrever:
100.000 registrosmas devido a um loop:
PERFORM UNTIL EOF
WRITE REG-SAIDA
END-PERFORMo EOF nunca muda.
O programa escreve eternamente.
O dataset cresce.
Até acabar espaço.
O sintoma é:
SB37Mas a causa lógica é:
LOOP INFINITOJoshua 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, é:
S322Em 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-PERFORMSe:
WS-FIMjamais se tornar:
Sparabé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=5O 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 foundPara nosso treinamento, vamos escrever corretamente o código de sistema como:
S806Esse é um dos mais didáticos para entender a relação entre:
JCL
programa
load module
load library
STEPLIB
JOBLIB
link-editImagine:
//STEP01 EXEC PGM=BELL001O sistema precisa localizar um módulo executável chamado:
BELL001Mas ele não aparece nas bibliotecas onde a busca está sendo realizada.
Resultado possível:
S80618. “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 OBJECTExecutar COBOL não significa o z/OS abrir seu source e interpretar:
MOVE A TO BO 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=SHREstamos indicando uma biblioteca onde o sistema poderá procurar o programa.
Agora imagine:
BELL001 está em:
BELLACOSA.LOAD.PRODmas o JCL usa:
BELLACOSA.LOAD.TESTJoshua procura.
Não encontra.
S806Perguntas ú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ódigo | Pense primeiro em |
|---|---|
S0C4 | acesso/endereço/proteção de storage |
S0C7 | dados numéricos inválidos / data exception |
SB37 | problema de espaço/extensão de dataset |
S322 | limite de execução/tempo excedido |
S806 | programa/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
SYSABENDNem 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:
COBTST1E começa a investigação.
Fluxo mental:
ST
|
+--> localizar JOB
|
+--> verificar RC / ABEND
|
+--> localizar STEP
|
+--> mensagens
|
+--> SYSOUT
|
+--> dumpA 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=PROGCResultado:
STEP10 RC=0000
STEP20 ABEND=S0C7
STEP30 FLUSHTemos uma informação gigantesca:
PROGA provavelmente terminou
PROGB falhou
PROGC nem executouEntã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=0000Outro:
RC=0004Outro:
RC=0008Outro pode sofrer:
ABEND S0C7Return 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
GOBACKO 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:
U4038O 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 codePara 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
MODULEO 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 runtimeCompilação com informações adequadas de debug pode permitir uma correlação muito melhor entre:
OFFSETe:
linha COBOLEssa é 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 +00001A72de 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 definitionsPor isso equipes maduras conservam artefatos apropriados das builds.
Não somente:
SOURCE.COBOLMas 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
dumpsCloud, Kubernetes e observabilidade moderna redescobriram ideias semelhantes com:
exit codes
logs
events
traces
metrics
crash dumps
health checksO 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:
S0C7O programador altera:
REGION=0MNã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:
S806Parabéns.
Transformamos um incidente em dois.
Troubleshooting profissional segue hipóteses:
EVIDÊNCIA
↓
HIPÓTESE
↓
TESTE
↓
RESULTADO
↓
CONCLUSÃONão:
ABEND
↓
PÂNICO
↓
ALTERA TUDO
↓
REZA31. 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 SUBMITTEDTrês segundos depois:
IEF450I WARGAME STEP01 - ABEND=S806Operador:
— 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 incorretaA ideia não é memorizar cinco códigos.
É aprender a cadeia:
CÓDIGO
↓
COMPILAÇÃO
↓
LINK
↓
JCL
↓
EXECUÇÃO
↓
JES
↓
ABEND
↓
DIAGNÓSTICOQuando 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:
S0C7Pergunte:
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-SAIDAPergunte 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 Cmas 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 MBe hoje tentou chegar a:
80 GBnã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-IFNã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=ABC123Cheque:
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:
PROGRAMA1e 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
copybooksS0C4
Ensina:
storage
endereçamento
arrays
CALL
memóriaSB37
Ensina:
datasets
DASD
SPACE
extents
JCLS322
Ensina:
CPU
loops
execução batch
limites
performanceS806
Ensina:
build
binder
load libraries
STEPLIB
execuçãoOu 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 S0C7para 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 hexadecimalA 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 infraestruturaPortanto:
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:
ABENDTérmino anormal.
RCReturn Code.
CCCondition Code, dependendo do contexto.
STEPUnidade executável de um JOB.
SYSOUTSaída gerada durante execução.
DUMPEstado capturado para diagnóstico.
LOADLIBBiblioteca contendo programas executáveis.
STEPLIBDD utilizado para definir bibliotecas privadas de busca para aquele step.
JOBLIBBiblioteca de busca aplicável aos steps do job dentro das regras pertinentes.
SPACEParâmetro relacionado à alocação de espaço do dataset.
OCCURSEstrutura de repetição/tabela COBOL.
COMP-3Representação decimal packed.
42. Uma rotina realista de incidente
Agora estamos às 03:00.
Produção.
JOB:
FATUR001falhou.
Passo a passo:
1. Abrir SDSFEncontrar:
FATUR0012. Identificar stepResultado:
STEP0403. Identificar programaFATU8474. Identificar falhaS0C75. Ler mensagensBuscar runtime/dump.
6. Identificar statement/offsetSuponha:
PARAGRAPH CALCULA-TOTAL7. Identificar operandosVALOR-BRUTO
TAXA
TOTAL8. Inspecionar dadosDescobre-se que VALOR-BRUTO contém representação inválida.
9. Descobrir origemVeio do arquivo produzido por STEP030.
10. Descobrir alteraçãoCopybook 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 equivocadaCaso contrário, amanhã:
S0C7volta.
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 ERROe começa a responder:
ONDE
QUANDO
COM QUAL DADO
EM QUAL VERSÃO
DEPOIS DE QUAL ALTERAÇÃOIsso é observabilidade.
45. Curiosidade — o mainframe já fazia “observabilidade” quando a palavra nem era moda
Hoje ouvimos:
logs
metrics
traces
telemetry
observabilityO ecossistema mainframe possui há décadas uma enorme cultura de:
SMF
JES logs
system messages
dumps
accounting
performance data
audit recordsNã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
milagreA segunda produz:
observação
hipótese
teste
causa
correção
prevenção47. Cheatsheet do Padawan
Quando aparecer:
S0C7
Pense:
DADO NUMÉRICO INVÁLIDOProcure:
COMP-3
MOVE
arquivo
copybook
REDEFINES
layout
campo não inicializadoS0C4
Pense:
ACESSO/ENDEREÇO DE STORAGEProcure:
OCCURS
subscript
index
CALL
ponteiros/referências
área sobrescritaSB37
Pense:
ESPAÇO DO DATASETProcure:
SPACE
volume
extents
crescimento
loop de escritaS322
Pense:
TEMPO/EXECUÇÃO EXCESSIVAProcure:
loop
READ
volume
SQL
CPU
condição de saídaS806
Pense:
PROGRAMA NÃO ENCONTRADOProcure:
PGM=
STEPLIB
JOBLIB
LOADLIB
binder
deploy
nome do módulo48. 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 ------------> S806Esse 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 AUTHORITYJoshua:
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
S806Agora 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 ABENDEDe 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 WARe escreve:
S0C7 DIAGNOSTIC LABO Padawan toma um gole de café.
— Podemos jogar.
Joshua responde:
EXCELLENT.
PLEASE PROVIDE:
JOBNAME
STEPNAME
PROGRAM NAME
ABEND CODE
COMPILE LISTING
DUMPO 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 0000A humanidade sobreviveu.
E melhor ainda:
o Padawan aprendeu a abrir o SDSF antes de culpar o mainframe.
Sem comentários:
Enviar um comentário