| Bellacosa Mainframe explora o comando CALL no COBOLparte II |
☕💥 A Jornada do Padawan COBOL – Parte 2
Desvendando o Universo dos CALLs no Mainframe
Os Segredos de BY REFERENCE, BY CONTENT, BY VALUE, Ponteiros, Work-Storage e Local-Storage
Ou como descobrir que um simples CALL pode criar um S0C4 capaz de assombrar um desenvolvedor por semanas
Por Vagner Bellacosa – Bellacosa Mainframe
A Hora em que o Padawan descobre que CALL não é magia
Na Parte 1 descobrimos que existem dois grandes reinos:
Static CALL
Dynamic CALL
Mas ainda falta compreender algo muito mais importante.
O que realmente acontece quando passamos dados para outro programa?
Porque é aqui que nascem aproximadamente 70% dos S0C4 que já vi em produção.
E quase todos começam com uma frase inocente:
"Só acrescentei um campo..."
O Grande Segredo do COBOL
Muitos desenvolvedores vindos de Java imaginam algo parecido com:
funcao(cliente);
Criou cópia.
Passou objeto.
Garbage Collector resolve.
No Mainframe não existe fada madrinha.
Existe endereço de memória.
E apenas endereço.
O padrão COBOL
O padrão do COBOL é:
BY REFERENCE
Mesmo quando você não escreve.
CALL 'SUBPGM'
USING WS-CLIENTE.
É equivalente a:
CALL 'SUBPGM'
USING BY REFERENCE WS-CLIENTE.
Como funciona na memória
Programa principal
MAIN
00010000
WS-NOME
JOAO
CALL
Passa:
00010000
Subprograma
LINKAGE
LK-NOME
Recebe
00010000
Mesmo local.
Diagrama
MAIN
WS-NOME
+---------+
| JOAO |
+---------+
|
|
V
SUBPGM
LK-NOME
+---------+
| JOAO |
+---------+
A magia acontece
Subrotina
MOVE 'MARIA' TO LK-NOME
Retorno
Main
MARIA
Mudou.
Porque é o mesmo endereço.
Vantagens
Muito rápido
Pouca memória
Zero cópia
Ideal tabelas grandes
VSAM
DB2
Buffers
Desvantagens
Subprograma pode destruir dados.
Sem querer.
Ou querendo.
O pesadelo do suporte
Programa A
passa saldo
Programa B
zera saldo
Programa A
grava no DB2
Cliente perde dinheiro.
O truque Jedi
Criar cópia antes.
MOVE WS-AREA TO WS-BACKUP
Quando usar
Grandes estruturas
100 mil registros
buffers VSAM
SQLDA
COMMAREA
CALL BY CONTENT
Agora o Padawan ganha maturidade.
Quer proteger dados.
Exemplo
CALL 'VALIDA'
USING
BY CONTENT WS-DATA
O compilador cria
uma área temporária.
Na memória
Original
WS-DATA
20250623
Cópia
TEMP
20250623
Subprograma recebe
TEMP
Alterações desaparecem
Subprograma
MOVE ZEROS TO LK-DATA
Volta
Main
Continua
20250623
Vantagens
Segurança
Proteção
Imutabilidade
Desvantagens
Consome memória.
Faz cópia.
CPU extra.
Benchmark imaginário
Estrutura
2 MB
1000 chamadas
By Reference
2 MB
By Content
2000 MB movimentados
O Mestre Mainframe pensa
Preciso alterar?
Não.
By Content.
Preciso compartilhar?
Reference.
CALL BY VALUE
Pouco conhecido.
Muito poderoso.
Surge com LE.
Language Environment.
Exemplo
CALL 'MINHAROT'
USING
BY VALUE WS-ID
Subrotina recebe
valor.
Não endereço.
É muito usado com
C
Assembler
LE APIs
Exemplo famoso
CALL 'CEE3ABD'
USING
BY VALUE 4095
O universo dos Ponteiros
Padawan vê isso.
USAGE POINTER
E fica com medo.
Com razão.
Exemplo
01 PTR USAGE POINTER.
Setar endereço
SET PTR TO ADDRESS OF WS-CLIENTE
PTR
00001000
Pode passar
CALL 'ROTINA'
USING PTR
Subprograma
recebe
endereço bruto.
É perigoso?
Muito.
Erro clássico
PTR inválido.
Resultado
S0C4
S0C4 explicado
CPU tenta acessar
endereço inexistente.
Exemplo
00000000
Crash.
LINKAGE SECTION
O portal interdimensional do COBOL.
Exemplo
LINKAGE SECTION.
01 LK-CLIENTE.
05 LK-NOME.
05 LK-ID.
Procedure Division
PROCEDURE DIVISION USING LK-CLIENTE.
Não aloca memória.
Nunca.
Apenas mapeia.
Work-Storage
Existe durante toda execução.
Carregado
uma vez.
Ideal
cache
tabelas
constantes
Exemplo
WORKING-STORAGE SECTION.
01 WS-CONTADOR PIC 9(9).
Local-Storage
Poucos usam.
Deveriam usar mais.
É recriado.
Toda chamada.
Exemplo
LOCAL-STORAGE SECTION.
01 LS-AREA.
05 LS-TEMP.
Diferença
WS
Persiste.
LS
Nasce.
Morre.
Exemplo
Chamada 1
contador=1
Chamada 2
contador=0
Excelente para
subrotinas reentrantes.
CICS.
LE.
Threads.
Reentrant
IBM adora isso.
Programa
não compartilha estado.
Evita corrupção.
Compilar
RENT
Erros clássicos
S0C4
Parâmetro errado
S0C7
Campo inválido
U4038
LE erro
S806
Programa não encontrado
Como validar
Antes do CALL
IF WS-PGM = SPACES
DISPLAY 'ERRO'
STOP RUN
END-IF
Conferir quantidade de parâmetros
IBM fornece
CEE3PRM
Easter Egg IBM
Muitos bancos possuem
CALL 'GENERICA'
Dentro.
EVALUATE WS-CODIGO
Mais de 300 WHEN.
Documentação
nenhuma.
Autor
aposentado em 2003.
Programa
continua funcionando.
Ninguém toca.
É conhecido como:
O Dragão Adormecido do Mainframe™
Dicas Bellacosa Mainframe
Dica 1
By Reference
90% dos casos.
Dica 2
By Content
Dados protegidos.
Dica 3
By Value
LE.
C.
Assembler.
Dica 4
Local-Storage
Muito subestimado.
Dica 5
Nunca assumir layout.
Validar tamanho.
Dica 6
Documente interfaces.
Algo parecido com:
************************************************
* ENTRADA
* CLIENTE
* DATA
*
* SAIDA
* RC
************************************************
A Filosofia Jedi do CALL – Parte 2
O Padawan iniciante pensa:
"Passar parâmetro é fácil."
O desenvolvedor intermediário pensa:
"By Reference é mais rápido."
O Mestre Mainframe entende:
"Passagem de parâmetros é um contrato binário entre programas."
E sabe que uma única alteração aparentemente inocente, como adicionar um campo em uma estrutura passada por referência, pode fazer um sistema bancário inteiro produzir S0C4, S0C7, dados corrompidos, abends misteriosos e algumas noites muito longas acompanhadas por café requentado e dumps de 500 MB.
Na próxima parte da jornada, o Padawan descobrirá os segredos de RETURN-CODE, GOBACK, STOP RUN, CEE3DMP, IPCS, CEEDUMP, rastreamento de CALLs, técnicas avançadas de troubleshooting, otimização de performance, análise de dumps e as ferramentas secretas usadas pelos Mestres Jedi do z/OS para domar os dragões da produção.