 |
| Bellacosa Mainframe e o debug em cobol |
☕ Um Café no Bellacosa Mainframe
Professor Pardal Entra no Abend: a Arte de Debugar COBOL sem Transformar Produção em Patópolis
🐔🔧 S0C7, S0C4, dumps, CEEDUMP, SYSOUT, DISPLAY, offsets, compile listings, Db2, CICS e a velha ciência de descobrir por que um programa que “funcionava ontem” resolveu explodir hoje
Existe uma frase particularmente perigosa no universo mainframe:
“Mas esse programa nunca deu problema.”
Meu jovem Padawan...
Um programa COBOL que está há 27 anos em produção não está necessariamente correto.
Ele pode simplesmente estar há 27 anos esperando o registro certo para explodir.
Então chega terça-feira.
02:47 da manhã.
O telefone toca.
JOB CLIENTE ABENDED
SYSTEM COMPLETION CODE=0C7
Silêncio.
Alguém pergunta:
— Quem alterou o programa?
Resposta:
— Ninguém.
Outra pessoa:
— Mudaram o arquivo?
— Não.
— Db2?
— Não.
— JCL?
— Também não.
Nesse momento, uma pequena porta se abre no CPD.
Entra um galo antropomórfico de chapéu, óculos e ferramentas.
Professor Pardal.
Ele olha para o dump.
Olha para o programador.
Olha novamente para o dump.
E provavelmente pergunta:
“Você leu a mensagem de erro?”
Porque antes de inventarmos observabilidade, AIOps, telemetry, tracing e outras palavras capazes de consumir três slides cada...
já existia uma técnica extraordinariamente eficiente:
LER A PORRA DO ERRO.
Bem-vindo ao maravilhoso mundo do debug COBOL.
🐔 Professor Pardal assume o plantão
Nos quadrinhos Disney, Professor Pardal é aquele inventor capaz de construir praticamente qualquer coisa.
Máquinas impossíveis.
Robôs.
Veículos.
Dispositivos absurdos.
Soluções para problemas que ninguém sabia que possuía.
E frequentemente suas invenções criam problemas ainda maiores.
Ou seja:
perfeitamente qualificado para desenvolvimento corporativo.
Ele também possui um pequeno ajudante robótico chamado Lampadinha.
Portanto nossa arquitetura está pronta:
PROFESSOR PARDAL
|
+---- Programador COBOL
|
+---- Lampadinha
|
+---- IA generativa
Agora precisamos descobrir por que:
COMPUTE WS-TOTAL =
WS-QUANTIDADE * WS-VALOR.
mandou nosso JOB diretamente para Valhalla.
🧠 Debug não significa olhar código
Primeira lição do Professor Pardal:
debug é investigação.
Existe uma diferença enorme.
O programador desesperado abre o código e começa:
rolando...
rolando...
rolando...
rolando...
Até encontrar alguma coisa que parece suspeita.
Então altera.
Compila.
Executa.
Falha.
Altera outra coisa.
Compila.
Executa.
Falha diferente.
Parabéns.
Você não está fazendo debugging.
Está praticando:
Programação Orientada a Superstição™
Professor Pardal jogaria uma chave inglesa em sua cabeça.
O processo correto começa com evidência.
🔎 1. Qual foi exatamente o ABEND?
Antes de olhar código:
QUAL JOB?
QUAL STEP?
QUAL PROGRAMA?
QUAL ABEND?
QUAL OFFSET?
QUAL ARQUIVO?
QUAL REGISTRO?
QUAL SQLCODE?
QUAL TRANSAÇÃO?
Imagine:
JOBNAME : FATURA01
STEP : STEP030
PROGRAM : FATU120
ABEND : S0C7
Já sabemos muita coisa.
S0C7 normalmente aponta para uma data exception.
Em linguagem Bellacosa:
alguma operação decimal encontrou algo que não deveria estar ali.
Você esperava:
12345
Recebeu:
12A45
COBOL olhou aquilo.
Pensou por aproximadamente três nanossegundos.
E decidiu:
VAI TOMAR NO CU.
S0C7.
💥 S0C7 — o clássico
Talvez seja o ABEND mais famoso do universo COBOL.
Imagine:
01 WS-VALOR PIC 9(05).
MOVE '12A45' TO WS-VALOR.
ADD 1 TO WS-VALOR.
A movimentação pode deixar dados incompatíveis com aquilo que posteriormente será tratado como numérico.
Quando uma instrução decimal tenta utilizar o campo...
💥
SYSTEM COMPLETION CODE=0C7
Professor Pardal imediatamente pergunta:
De onde veio WS-VALOR?
Essa pergunta vale ouro.
Porque frequentemente o erro não está na instrução que explodiu.
A instrução apenas encontrou o cadáver.
🕵️ A cena do crime
Considere:
READ ARQ-CLIENTES
AT END
SET EOF TO TRUE
NOT AT END
MOVE CLI-VALOR TO WS-VALOR
END-READ.
...
COMPUTE WS-TOTAL = WS-VALOR * WS-TAXA.
O COMPUTE explode.
Quem é acusado?
COMPUTE
Mas talvez o verdadeiro assassino tenha acontecido vinte instruções antes:
MOVE CLI-VALOR TO WS-VALOR
E talvez CLI-VALOR tenha vindo de:
ARQUIVO
que veio de:
SORT
que veio de:
OUTRO PROGRAMA
que veio de:
DB2
que recebeu dados de:
API
que recebeu alguma porcaria enviada por alguém.
Bem-vindo ao debugging corporativo.
🗺️ O mapa do Professor Pardal
Uma investigação eficiente pode ser visualizada assim:
ABEND
↓
STEP
↓
PROGRAMA
↓
OFFSET
↓
INSTRUÇÃO
↓
VARIÁVEIS
↓
ORIGEM DOS DADOS
↓
REGISTRO
↓
CAUSA
Não:
ABEND
↓
PÂNICO
↓
ALTERA QUALQUER COISA
↓
COMPILA
↓
REZA
Essa segunda metodologia é bastante popular.
📜 2. Leia o dump
Ah, o dump.
Aquele maravilhoso documento de 18 quilômetros que aparece no spool.
O programador iniciante abre:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
HEX HEX HEX HEX HEX HEX HEX HEX
REGISTER REGISTER REGISTER
STORAGE STORAGE STORAGE
Fecha.
E declara:
“Não dá para entender.”
Professor Pardal sorri.
Porque o dump não foi criado para ser bonito.
Foi criado para contar o que existia na memória quando o programa morreu.
É a autópsia.
🧬 CEEDUMP
Em ambientes Language Environment, podemos encontrar informações extremamente úteis no CEEDUMP.
Dependendo da configuração e do problema, você pode conseguir identificar:
programa;
condição;
offset;
traceback;
rotina;
registradores;
storage;
contexto da falha.
Você não precisa compreender imediatamente cada byte.
Primeiro procure aquilo que reduz o universo da investigação.
Se seu programa possui 25.000 linhas e você descobre aproximadamente onde ocorreu a falha...
já eliminou uma enorme quantidade de Patópolis.
📐 3. O offset é seu amigo
Imagine uma mensagem apontando algo semelhante a:
PROGRAM FATU120
OFFSET X'00001A7C'
Agora temos uma coordenada.
Precisamos relacioná-la ao código compilado.
É aqui que o compile listing se torna extremamente importante.
Dependendo do compilador, opções utilizadas e informações disponíveis, podemos correlacionar offsets com statements/instruções.
Professor Pardal abre sua bancada:
ABEND
+
OFFSET
+
COMPILE LISTING
=
LOCALIZAÇÃO PROVÁVEL
Agora nossa investigação saiu de:
“Existe algum problema no programa.”
para:
“Existe alguma coisa errada nesta região.”
Isso muda tudo.
📚 Compile listing não é papel para alimentar impressora
Durante anos conheci programadores que tratavam listing como aquele negócio gigantesco produzido depois da compilação.
Errado.
Ele pode ser uma verdadeira radiografia do programa.
Dependendo das opções de compilação, encontramos informações sobre:
SOURCE
CROSS-REFERENCE
DATA MAP
PROCEDURE MAP
OFFSETS
MESSAGES
OPTIMIZATION
O velho:
XREF
pode ser particularmente interessante.
Quer saber onde determinada variável aparece?
Em vez de executar:
CTRL+F
CTRL+F
CTRL+F
CTRL+F
você pode analisar suas referências.
🐔 Professor Pardal pergunta: “Quem mexeu nesta variável?”
Imagine:
01 WS-SALDO PIC S9(09)V99 COMP-3.
Você encontra problema em WS-SALDO.
Pergunta:
Quem escreve nele?
Talvez:
01230 MOVE DB2-SALDO TO WS-SALDO
01870 ADD WS-JUROS TO WS-SALDO
02410 MOVE ZERO TO WS-SALDO
03150 COMPUTE WS-SALDO = ...
Agora temos suspeitos.
Debugging começa a parecer investigação criminal.
Porque essencialmente é.
🔦 Lampadinha recomenda DISPLAY
E chegamos à ferramenta mais sofisticada já inventada pela humanidade.
DISPLAY.
Sim.
Pode rir.
Temos ferramentas modernas de debugging.
IDEs.
Debuggers interativos.
Tracing.
Observabilidade.
Ferramentas comerciais excelentes.
Mas existe um momento na carreira de todo COBOLzeiro em que aparece:
DISPLAY 'ENTREI AQUI'.
Depois:
DISPLAY 'WS-VALOR=' WS-VALOR.
Depois:
DISPLAY 'ANTES DO COMPUTE'.
E finalmente:
DISPLAY 'MEU DEUS CHEGOU AQUI'.
É feio?
Sim.
Funciona?
ABSOLUTAMENTE.
⚠️ Mas DISPLAY também pode virar arma de destruição
Professor Pardal faz uma advertência.
Imagine:
PERFORM UNTIL EOF
READ ARQUIVO
DISPLAY REGISTRO-INTEIRO
END-PERFORM.
Arquivo:
83.000.000 registros
JES2:
VOCÊ TEM CERTEZA DISSO, FILHO?
Portanto DISPLAY deve ser usado com inteligência.
Talvez:
IF WS-CONTADOR < 100
DISPLAY ...
END-IF
Ou somente quando determinada condição ocorrer:
IF WS-CLIENTE = 123456
DISPLAY ...
END-IF
Debugging não deveria provocar um novo incidente.
Embora isso torne a história muito melhor depois.
🧯 S0C4 — entrou onde não deveria
Outro clássico:
S0C4
De maneira simplificada, estamos frequentemente olhando para algum problema de acesso à memória/storage, endereço inválido ou operação relacionada.
É uma família de situações que exige analisar contexto.
Ponteiros.
Índices.
Subscripts.
CALLs.
Parâmetros.
Storage.
Professor Pardal imediatamente procura coisas como:
SET ADDRESS OF ...
ou tabelas:
01 TABELA.
05 ITEM OCCURS 100 TIMES.
e alguém fazendo:
ITEM(347)
A tabela possui 100 posições.
O programador quer acessar 347.
COBOL responde:
interessante.
O sistema responde:
S0C4.
📦 SSRANGE — o cinto de segurança
Durante desenvolvimento e testes, opções como SSRANGE podem ajudar enormemente na identificação de problemas relacionados a referências fora dos limites permitidos.
É o equivalente COBOL de colocar Professor Pardal ao lado da tabela dizendo:
“Meu amigo, existem 100 posições aqui. Por que você está tentando acessar a 347?”
Naturalmente existe custo associado às verificações adicionais, portanto decisões de compilação para desenvolvimento, teste e produção precisam considerar o ambiente e as políticas da organização.
Mas durante diagnóstico?
Pode ser extremamente útil.
🧮 COMP-3: onde mora o demônio hexadecimal
Agora entramos numa região particularmente divertida.
Packed decimal.
PIC S9(7)V99 COMP-3.
O programador iniciante olha um dump hexadecimal e pensa:
Satanás.
O COBOLzeiro experiente olha:
12 34 56 78 9C
e pensa:
Ah, 1234567,89 positivo.
E continua tomando café.
Campos COMP-3 são eficientes e tradicionais no processamento decimal empresarial.
Mas quando dados inválidos entram nesse território...
o S0C7 começa a afiar a faca.
🧪 TESTE O DADO, NÃO SUA FÉ
Uma das grandes lições do debugging é:
nunca confie cegamente na entrada.
“Mas o arquivo vem de outro sistema.”
Maravilha.
Outro sistema também possui programadores.
“Mas vem do banco.”
Ótimo.
“Mas existe validação.”
Excelente.
Mesmo assim:
VALIDATE.
Porque sistemas antigos frequentemente acumulam décadas de exceções, migrações, conversões e pequenas decisões históricas.
O campo chamado:
DATA-NASCIMENTO
pode conter:
00000000
99999999
20260231
e algum valor que ninguém consegue explicar desde 1987.
🗄️ Quando o culpado é Db2
Agora nosso programa executa SQL.
EXEC SQL
SELECT SALDO
INTO :WS-SALDO
FROM CLIENTE
WHERE ID = :WS-ID
END-EXEC.
Professor Pardal pergunta imediatamente:
SQLCODE?
SQLSTATE?
Não faça isto:
EXEC SQL
...
END-EXEC
CONTINUE.
Faça tratamento adequado.
Porque:
SQLCODE = 0
é uma história.
SQLCODE = +100
é outra.
Valores negativos contam histórias ainda mais interessantes.
Um bom debug de aplicação Db2 exige entender não apenas COBOL, mas a conversa entre:
PROGRAMA
↕
SQL
↕
DB2
🏦 CICS: agora o pato ficou bravo
Batch já é divertido.
Então entramos no CICS.
Agora temos:
TRANSACTION
COMMAREA
CHANNELS
CONTAINERS
RESP
RESP2
EIBRESP
EIBRCODE
MAPAS
TSQ
TDQ
FILES
DB2
MQ
E o usuário diz:
“A tela fechou.”
Excelente descrição técnica.
Professor Pardal pergunta:
Qual transação?
Usuário:
“Aquela azul.”
Bem-vindo ao suporte.
🚨 RESP e RESP2
Uma prática importantíssima no CICS é não tratar comandos como se fossem infalíveis.
Exemplo conceitual:
EXEC CICS READ
FILE('CLIENTE')
INTO(WS-REGISTRO)
RIDFLD(WS-CHAVE)
RESP(WS-RESP)
RESP2(WS-RESP2)
END-EXEC.
Agora conseguimos investigar.
Em vez de:
NÃO FUNCIONOU
temos informação sobre a resposta da operação.
Debugging é justamente isso:
transformar “não funciona” em evidência mensurável.
🧠 Professor Pardal apresenta o método científico
A melhor maneira de debugar COBOL não é decorar ABENDs.
É pensar como cientista.
Temos:
OBSERVAÇÃO
↓
HIPÓTESE
↓
TESTE
↓
EVIDÊNCIA
↓
CONCLUSÃO
Exemplo:
Observação
S0C7 durante cálculo.
Hipótese
WS-VALOR contém dados não numéricos.
Teste
Inspecionar campo imediatamente antes da operação.
Evidência
WS-VALOR = '00012A45'
Nova pergunta
Quem colocou A ali?
Seguimos para trás.
Isso é debugging.
❌ O anti-debug
O método corporativo alternativo é:
S0C7
↓
"DEVE SER O DB2"
↓
DBA INVESTIGA
↓
NÃO É DB2
↓
"DEVE SER INFRA"
↓
INFRA INVESTIGA
↓
NÃO É INFRA
↓
"SERÁ A REDE?"
↓
NETWORK INVESTIGA
↓
NÃO É REDE
↓
3 HORAS DE WAR ROOM
↓
CAMPO NUMÉRICO CONTINHA 'X'
Professor Pardal abandona Patópolis.
🤖 Lampadinha ganhou IA generativa
Agora chegamos a 2026.
Imagine Professor Pardal com uma Lampadinha equipada com IA.
Você fornece:
ABEND
dump
compile listing
trecho COBOL
copybook
JCL
mensagens
E pergunta:
“Quais são as hipóteses mais prováveis?”
Isso pode acelerar brutalmente a investigação.
IA pode ajudar a:
Mas existe uma regra fundamental:
IA NÃO TRANSFORMA HIPÓTESE EM EVIDÊNCIA.
Se Lampadinha disser:
“Provavelmente WS-VALOR possui dado inválido.”
Excelente.
Agora prove.
🧠 IA pode alucinar. Dump não.
Esta frase deveria estar colada em toda War Room moderna.
IA:
"Talvez seja..."
DUMP:
"ERA ISTO."
Use IA como copiloto investigativo.
Não como oráculo.
Especialmente em ambientes críticos.
E jamais copie dumps de produção contendo dados sensíveis para serviços externos sem autorização, mascaramento e respeito às políticas de segurança.
Professor Pardal é maluco.
Mas RACF continua observando.
🔐 DEBUG também é segurança
Essa parte frequentemente é esquecida.
Dump pode conter:
CPF
CONTA
NOME
TOKEN
CARTÃO
ENDEREÇO
DADOS FINANCEIROS
CHAVES
CREDENCIAIS
DISPLAY também pode colocar dados sensíveis no spool.
Logs permanecem.
SYSOUT permanece.
Ferramentas armazenam informações.
Portanto:
DEBUG ≠ LIBEROU GERAL
Em produção, diagnóstico precisa respeitar controles de segurança e privacidade.
🧰 A caixa de ferramentas do Professor Pardal
Nosso laboratório COBOL pode conter várias ferramentas e técnicas:
ABEND MESSAGES
SYSOUT
JES/SDSF
DUMP
CEEDUMP
COMPILE LISTING
XREF
OFFSET
DISPLAY
SSRANGE
TEST OPTIONS
DEBUGGERS
FAULT ANALYSIS TOOLS
FILE INSPECTION
DB2 DIAGNOSTICS
CICS DIAGNOSTICS
SMF
LOGS
Nenhuma ferramenta substitui raciocínio.
Porque o problema fundamental continua sendo:
O que o programa deveria fazer e o que ele realmente fez?
Essa diferença é o território do debugger.
🧭 O algoritmo Bellacosa-Pardal de Debug COBOL™
Quando alguma coisa explodir:
1. NÃO ENTRE EM PÂNICO
↓
2. IDENTIFIQUE JOB/STEP/PROGRAMA
↓
3. LEIA O ABEND/MENSAGEM
↓
4. PROCURE OFFSET/TRACEBACK
↓
5. CONSULTE O LISTING
↓
6. IDENTIFIQUE A INSTRUÇÃO
↓
7. INSPECIONE AS VARIÁVEIS
↓
8. DESCUBRA QUEM AS ALTEROU
↓
9. RASTREIE A ORIGEM DOS DADOS
↓
10. CRIE UMA HIPÓTESE
↓
11. TESTE
↓
12. REPRODUZA
↓
13. CORRIJA A CAUSA
↓
14. FAÇA TESTE DE REGRESSÃO
↓
15. DOCUMENTE
Observe o item 13:
CORRIJA A CAUSA.
Não simplesmente o sintoma.
🩹 O remendo que cria o monstro
Programa:
IF WS-VALOR IS NUMERIC
COMPUTE ...
END-IF.
Problema desapareceu.
CABÔ!
Talvez.
Mas espere.
Por que WS-VALOR não era numérico?
Se deveria obrigatoriamente ser...
você acabou de esconder um problema de qualidade de dados.
O programa não explode mais.
Agora apenas ignora silenciosamente dinheiro.
Excelente.
Transformamos um S0C7 visível em um erro contábil invisível.
Professor Pardal começa a suar frio.
🧪 Corrigir não é provar
Depois da alteração:
“Funcionou.”
Não significa:
“Está correto.”
Precisamos testar:
CASO ORIGINAL
CASOS NORMAIS
LIMITES
ZEROS
NEGATIVOS
VALORES MÁXIMOS
DADOS INVÁLIDOS
ARQUIVO VAZIO
DUPLICIDADES
ERROS DB2
ERROS CICS
E principalmente:
garantir que você não consertou uma coisa quebrando três.
Esse fenômeno é conhecido tecnicamente como:
sexta-feira às 17h43.
📚 Documente o incidente
Encontramos:
CAUSA:
campo VALOR recebeu caractere inválido.
ORIGEM:
programa anterior gerou registro inconsistente.
IMPACTO:
JOB FATURA01 interrompido.
CORREÇÃO:
validação corrigida na origem.
PREVENÇÃO:
teste adicionado.
Isso vale muito mais do que:
PROBLEMA RESOLVIDO.
Daqui a três anos outro programador pode encontrar situação semelhante.
E descobrir que o Professor Pardal de 2026 deixou um mapa.
🐔 O melhor debugger não é quem conhece todos os ABENDs
É quem sabe fazer boas perguntas.
O QUE FALHOU?
ONDE?
QUANDO?
COM QUAL DADO?
SEMPRE ACONTECE?
QUAL FOI A ÚLTIMA EXECUÇÃO BOA?
O QUE MUDOU?
CONSEGUIMOS REPRODUZIR?
QUAL VARIÁVEL ESTAVA ERRADA?
QUEM ALTEROU ESSA VARIÁVEL?
DE ONDE VEIO O DADO?
Cada resposta reduz o espaço de busca.
Debugging é uma batalha contra possibilidades.
Começamos com:
QUALQUER COISA PODE ESTAR ERRADA
e terminamos com:
ESTE BYTE ESTÁ ERRADO.
Isso é lindo.
☕ Professor Pardal termina seu café
Depois de duas horas de investigação encontramos a causa.
Um arquivo recebido por um programa COBOL possuía um registro:
0000000000000012578
e outro:
00000000000000A2578
Um único caractere.
Um miserável:
A
No meio de milhões de registros.
Esse pequeno A atravessou sistemas.
Passou por arquivos.
Entrou no programa.
Chegou a um campo tratado como numérico.
Esperou pacientemente.
Então encontrou uma operação decimal.
E derrubou um JOB gigantesco.
Milhares de linhas COBOL.
Db2.
JES2.
z/OS.
Mainframe de milhões de dólares.
Equipe de operações.
Desenvolvedores.
DBAs.
War Room.
Gestores.
Todos derrotados por:
A
Professor Pardal olha para Lampadinha.
Lampadinha olha para o dump.
O operador pergunta:
— Então era o mainframe?
Pardal responde:
— Não.
— Era COBOL?
— Não.
— Db2?
— Não.
— CICS?
— Também não.
— Então o que era?
Ele aponta para o registro.
A
Silêncio.
O JOB é reprocessado.
IEF142I FATURA01 STEP030 - STEP WAS EXECUTED
IEF285I
MAXCC=0000
E mais uma vez o gigantesco dinossauro de silício volta a trabalhar como se absolutamente nada tivesse acontecido.
🦖 A moral da história
Depois de décadas trabalhando com software, aprendemos uma coisa desconfortável:
os bugs mais difíceis nem sempre são tecnicamente sofisticados.
Às vezes são apenas pequenos.
Escondidos.
Intermitentes.
Dependentes de dados.
Dependentes de sequência.
Dependentes de uma combinação que acontece uma vez a cada cinco milhões de registros.
Por isso ferramentas são importantes.
Mas método é mais importante.
Professor Pardal pode possuir a oficina inteira.
Lampadinha pode possuir inteligência artificial.
Você pode ter o melhor debugger disponível.
Mas no final alguém ainda precisa perguntar:
“O que aconteceu imediatamente antes disso?”
E continuar perguntando.
Até encontrar aquele miserável byte que resolveu transformar uma madrugada tranquila em uma War Room.
☕ Epílogo — Um Café no Bellacosa Mainframe
03:58.
Incidente encerrado.
Professor Pardal guarda suas ferramentas.
Lampadinha desliga a IA.
Operações fecha o chamado.
O gerente pergunta:
“Podemos considerar causa raiz identificada?”
Sim.
“Podemos evitar recorrência?”
Sim.
“Precisamos de reunião amanhã?”
...
Professor Pardal olha para o relógio.
Olha para o mainframe.
Olha para Lampadinha.
Lampadinha discretamente apaga a luz.
E ambos fogem de Patópolis antes que alguém consiga pronunciar:
“Post-Mortem.”
🐔🔧☕🦖
JOB DEBUGPARDAL — MAXCC=0000
E todos viveram felizes...
até o próximo S0C7.
https://eljefemidnightlunch.blogspot.com/2026/06/a-saga-de-vagner-bellacosa-no-reino-dos.html
DISPLAY e BUG TRAP as melhores maneiras de debugar um programa COBOL.
Qual é a sua técnica?
#ibm #mainframe #cobol #debug #trap #bug #returncode #maxcc #jcl #sdsf #job