Translate

Mostrar mensagens com a etiqueta Work Storage. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Work Storage. Mostrar todas as mensagens

domingo, 10 de fevereiro de 2019

☕💥 A Jornada do Padawan COBOL – Parte 2 Desvendando o Universo dos CALLs no Mainframe Parte II

 

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.


quinta-feira, 3 de janeiro de 2019

☕💥 A Jornada do Padawan COBOL – Parte 1 Desvendando o Universo dos CALLs no Mainframe

 

Bellacosa Mainframe e o CALL em programas COBOL Parte I

☕💥 A Jornada do Padawan COBOL – Parte 1

Desvendando o Universo dos CALLs no Mainframe

Ou como descobrir que chamar um programa em COBOL é quase tão importante quanto saber preparar café às 3 da manhã durante uma janela de produção

Por Vagner Bellacosa – Bellacosa Mainframe


Introdução

Todo desenvolvedor COBOL passa por um momento de iluminação.

Normalmente acontece quando ele abre um programa de produção com 30 mil linhas e encontra algo parecido com isto:

CALL 'PROG0001'
USING WS-AREA.

CALL WS-PROGRAMA
USING WS-COMMAREA.

CALL 'VALIDA01'
USING BY CONTENT WS-DATA.

CALL 'ROTINA99'
USING BY REFERENCE WS-BLOCO.

Neste momento surge a dúvida existencial:

Por que existem tantos tipos de CALL?

Qual é o mais rápido?

Qual gasta menos memória?

O que acontece dentro do z/OS?

O compilador faz mágica?

O Load Module engorda?

Como um banco executa milhões de CALLs por segundo sem explodir?

Prepare seu café.

Vamos abrir a tampa do motor do z/OS.


O que é um CALL?

Simplificando:

CALL significa pedir ajuda para outro programa.

Em vez de colocar 100 mil linhas em um único fonte, quebramos o sistema em pequenas peças reutilizáveis.

Por exemplo:

Programa principal

PROCESSA-CLIENTES

chama

VALIDA-CPF

CALCULA-JUROS

GERA-BOLETO

ENVIA-MQ

ATUALIZA-DB2

Cada um especializado.

É praticamente microserviços.

Só que inventados em 1960.


Por que IBM fez isso?

Porque memória custava uma fortuna.

Década de 70

Memória podia custar mais que um carro.

Era necessário:

reutilizar código

economizar memória

compartilhar lógica

facilitar manutenção

Assim nasceu o CALL.


Anatomia de um programa COBOL

Um programa COBOL compilado produz:

Objeto

Binder

Load Module

PDs Loadlib

Execução

Exemplo:

SYS1.LOADLIB


PROCESSA
VALIDA
JUROS
CPFCHK

O Padawan descobre o Static CALL

Exemplo

CALL 'VALIDA'

Simples.

Mas o compilador já conhece VALIDA.

Ele avisa o Binder:

Inclua VALIDA aqui.


O que acontece no LinkEdit

Binder faz:

PROCESSA


+

VALIDA


+

CPFCHK


+

JUROS


=

EXECUTÁVEL FINAL

Na memória

Antes:

PROCESSA

Depois:

PROCESSA


VALIDA


CPFCHK


JUROS

Tudo junto.

Tudo carregado.


Vantagens

Performance

Excelente.

Não precisa procurar.

Não precisa abrir bibliotecas.

Não precisa localizar módulo.

É praticamente:

BALR

Menor CPU

Menos instruções.

Menos overhead.

Menos I/O.


Desvantagens

Executável cresce.

Muito.

Exemplo

Programa principal

1 MB

Subrotinas

500 KB

Total

1,5 MB


Imagine 200 subrotinas.

Seu módulo vira um Godzilla.


Problema clássico

Padawan:

"Troquei VALIDA"

Produção:

Ainda usa antiga.

Porque precisa relinkar.


Quando usar?

Sempre que:

Programa nunca muda

Alta performance

Rotina crítica

Batch pesado

Exemplo:

Juros

Cálculo tributário

Validação interna


O Dynamic CALL aparece

Padawan evolui.

Descobre:

01 WS-PGM PIC X(8).

MOVE 'VALIDA' TO WS-PGM.

CALL WS-PGM.

O que acontece?

COBOL não sabe quem será chamado.

Somente em execução.


Busca do módulo

zOS procura:

STEPLIB

JOBLIB

LPA

LINKLIST


Exemplo

CALL CPFCHK

Sistema:

Existe?

Não.

Próximo.

Existe?

Sim.

Carrega.

Executa.


Vantagens

Flexibilidade absurda.

Pode trocar programas.

Sem recompilar.

Sem binder.

Sem relink.


Plugins COBOL

Exemplo

Cartão VISA

MOVE 'VISA0001'

Master

MOVE 'MASTER01'

PIX

MOVE 'PIX00001'

Mesmo sistema.

Rotinas diferentes.


Desvantagens

Procura programa.

Mais CPU.

Mais I/O.

Mais tempo.


Mas é lento?

Depende.

Primeira chamada.

Sim.

Segunda.

Muito rápida.

Porque pode ficar residente.


O segredo da residência

zOS é esperto.

Se programa está em memória.

Reutiliza.

Não busca novamente.


Comparação

Static

Casa própria

Dynamic

Airbnb

O executável cresce?

Static

Sim.

Dynamic

Não.

Executável principal fica pequeno.


Exemplo

Static

PROCESSA

1.5 MB

Dynamic

PROCESSA

600 KB

Subrotinas externas.


O que é mais performático?

Resposta curta.

Static.

Fim.

Mas...


O que é melhor?

Depende.

Banco.

Static.

Framework.

Dynamic.

Produtos.

Dynamic.

Rotinas financeiras.

Static.


Como o CALL funciona internamente?

Imagine isto.

Programa principal

00001000
PROCESSA

Subrotina

00025000
VALIDA

CALL executa

Guardar endereço retorno


Ir para 25000


Executar


Voltar

É praticamente um GOTO sofisticado.

Só que elegante.


Erros clássicos

S806

Programa não encontrado.

Mensagem

IEC806I

Causa

Módulo ausente.

STEPLIB errada.

Nome inválido.


S0C1

Executou lixo.

Programa corrompido.


S0C4

Endereço inválido.

Muito comum em parâmetros errados.


Como descobrir

SDSF

JESMSGLG

SYSOUT


Verificar:

STEPLIB

SYSLIB

LOADLIB


Easter Egg IBM

Muitos bancos possuem:

PROG0001

PROG0002

PROG0003

Ninguém sabe o que fazem.

Autor aposentou em 1998.

Documentação desapareceu.

Programa continua funcionando.

Todos têm medo de alterar.

É chamado:

Código Arqueológico Mainframe™


Dicas Bellacosa Mainframe

Dica 1

Static para alta frequência.


Dica 2

Dynamic para produtos.


Dica 3

Nunca fazer:

MOVE WS-USUARIO TO WS-PGM

CALL WS-PGM

Sem validar.

Pode chamar qualquer coisa.

Inclusive algo inexistente.


Dica 4

Validar sempre.

EVALUATE WS-PGM

WHEN 'CPFCHK'

WHEN 'JUROS01'

WHEN 'PIX0001'

WHEN OTHER

DISPLAY 'INVALIDO'

END-EVALUATE

Dica 5

Logar chamadas.

DISPLAY 'CALL=' WS-PGM

Ajuda muito.


A Filosofia Jedi do CALL

O Padawan iniciante pensa:

CALL serve apenas para executar outro programa.

O desenvolvedor intermediário pensa:

CALL serve para reutilizar código.

O Mestre Mainframe entende:

CALL é uma decisão arquitetural.

Ele impacta:

  • CPU

  • Memória

  • Tempo de resposta

  • Tamanho do Load Module

  • Facilidade de manutenção

  • Segurança

  • Escalabilidade

  • Observabilidade

  • Estratégia de deploy

E é exatamente por isso que, cinquenta anos depois, os sistemas bancários que movimentam bilhões de dólares diariamente ainda utilizam a mesma instrução COBOL que um programador digitou em um terminal verde na década de 1970:

CALL 'SUBPGM'

Na próxima etapa da jornada, o Padawan descobrirá que o verdadeiro poder do COBOL não está apenas em chamar programas, mas em como os dados atravessam a fronteira entre eles, mergulhando nos mistérios de BY REFERENCE, BY CONTENT, BY VALUE, ponteiros, Work-Storage, Local-Storage e Language Environment, onde vivem os temidos S0C4, os buffers compartilhados e os segredos que fazem alguns programas parecerem mágicos aos olhos dos desenvolvedores mais jovens.