| Bellacosa Mainframe compilacao cobol parte iii |
☕ Um Café no Bellacosa Mainframe
Da Compilação à Execução de um Programa COBOL — Parte III
Compilação, Linkedição e Load Library: Como o Código-Fonte se Transforma em um Programa Executável
Introdução
Na segunda parte desta jornada, vimos que muitos programas COBOL corporativos não seguem diretamente para o compilador.
Antes disso, eles podem passar por outras etapas especializadas.
Comandos como:
EXEC CICS
precisam ser traduzidos.
Comandos como:
EXEC SQL
precisam ser processados pelo pré-compilador ou coprocessador Db2.
Programas IMS utilizam interfaces DL/I, PCBs, PSBs e DBDs.
Aplicações Adabas dependem de control blocks, buffers e módulos de comunicação.
Depois que todo esse material foi preparado, finalmente chega o momento em que o compilador COBOL entra em cena.
É aqui que o texto escrito pelo programador começa a se transformar em instruções realmente compreendidas pela máquina.
Entretanto, existe uma confusão muito comum entre iniciantes:
Compilar não significa necessariamente criar o executável final.
A compilação produz um código objeto.
Depois disso, outra ferramenta, chamada Binder, precisa reunir esse objeto com interfaces, rotinas e módulos necessários.
Esse processo é conhecido como linkedição.
Somente após a linkedição surge o módulo executável que poderá ser gravado em uma load library.
Nesta terceira parte, vamos acompanhar essa transformação passo a passo.
Prepare o café, abra o SDSF e venha entender o que realmente acontece entre o fonte COBOL e o módulo executável.
1. O que significa compilar?
Compilar significa transformar o código-fonte escrito pelo programador em código objeto.
O fluxo mais simples é:
Código-fonte COBOL
↓
Compilador COBOL
↓
Código objeto
O código-fonte é legível para seres humanos treinados em COBOL.
Exemplo:
IDENTIFICATION DIVISION.
PROGRAM-ID. PGMCALC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-VALOR-A PIC S9(09) COMP.
01 WS-VALOR-B PIC S9(09) COMP.
01 WS-TOTAL PIC S9(09) COMP.
PROCEDURE DIVISION.
MOVE 100 TO WS-VALOR-A
MOVE 250 TO WS-VALOR-B
COMPUTE WS-TOTAL =
WS-VALOR-A + WS-VALOR-B
DISPLAY 'TOTAL: ' WS-TOTAL
STOP RUN.
A CPU do IBM Z não executa diretamente instruções como:
MOVE
COMPUTE
DISPLAY
STOP RUN
Essas instruções precisam ser transformadas em instruções de máquina compatíveis com a arquitetura do processador.
O compilador realiza essa conversão.
2. O compilador faz muito mais do que traduzir
Muitos iniciantes imaginam que o compilador apenas troca comandos COBOL por instruções de máquina.
Na realidade, ele executa várias análises.
Entre elas:
verificação de sintaxe;
validação de nomes;
análise de tipos de dados;
cálculo de tamanhos;
validação de referências;
verificação de parágrafos;
resolução de campos;
tratamento de copybooks;
validação de arquivos;
análise de expressões;
geração de código;
otimização;
emissão de mensagens;
criação de listagens;
produção do módulo objeto.
Considere:
01 WS-NOME PIC X(40).
01 WS-IDADE PIC 9(03).
MOVE WS-NOME TO WS-IDADE.
O compilador poderá identificar que um campo alfanumérico está sendo movido para um campo numérico.
Dependendo das opções e do conteúdo, isso poderá produzir:
advertência;
conversão;
risco de erro em execução;
mensagem de diagnóstico.
O compilador é, portanto, uma espécie de auditor técnico do programa.
3. O compilador precisa conhecer os copybooks
Na primeira parte, vimos que um programa pode utilizar:
COPY CPYCLI01.
O compilador precisa localizar esse copybook.
Normalmente, as bibliotecas são indicadas por meio de um DD statement como:
//SYSLIB DD DISP=SHR,
// DSN=EMPRESA.SISTEMA.COPYLIB
Pode haver várias bibliotecas:
//SYSLIB DD DISP=SHR,
// DSN=EMPRESA.SISTEMA.COPYLIB
// DD DISP=SHR,
// DSN=EMPRESA.CORPORATIVO.COPYLIB
// DD DISP=SHR,
// DSN=FORNECEDOR.PRODUTO.COPYLIB
A ordem pode ser importante.
Se duas bibliotecas possuírem um membro com o mesmo nome, o primeiro encontrado poderá ser utilizado.
Imagine:
EMPRESA.TESTE.COPYLIB(CPYCLI01)
EMPRESA.PRODUCAO.COPYLIB(CPYCLI01)
Se a biblioteca errada estiver antes na concatenação, o programa poderá ser compilado com uma versão incorreta do layout.
O fonte estará correto.
O copybook existirá.
A compilação poderá terminar com sucesso.
Mesmo assim, o programa poderá utilizar uma estrutura incompatível.
Essa é uma das razões pelas quais o processo de compilação precisa ser controlado.
4. O compilador trabalha com opções
O comportamento do compilador pode ser alterado por opções.
Essas opções podem controlar:
geração de listagem;
otimização;
tratamento de chamadas;
compatibilidade;
informações de depuração;
aritmética;
encoding;
migração;
geração de dados de teste;
integração com CICS;
integração com Db2;
tratamento de warnings.
Exemplos de opções frequentemente encontradas em ambientes COBOL incluem conceitos como:
OPTIMIZE
LIST
MAP
XREF
SSRANGE
NUMCHECK
RENT
DYNAM
NODYNAM
TEST
ARCH
TUNE
Os nomes e efeitos exatos dependem da versão e da configuração do Enterprise COBOL.
O importante para o Padawan é entender:
O mesmo fonte pode gerar executáveis diferentes conforme as opções utilizadas.
5. Otimização
O compilador pode reorganizar ou melhorar o código gerado para produzir maior eficiência.
Considere:
MULTIPLY WS-VALOR BY 2
GIVING WS-RESULTADO.
O programador descreve a regra.
O compilador decide como representá-la em instruções de máquina.
Com opções de otimização, ele pode:
reduzir instruções;
eliminar operações desnecessárias;
reorganizar processamento;
utilizar recursos modernos da arquitetura;
melhorar acesso a dados;
produzir código mais eficiente.
Porém, níveis elevados de otimização podem tornar a depuração mais complexa.
O código gerado pode não seguir exatamente a ordem visual do fonte.
Por isso, ambientes de desenvolvimento e produção podem utilizar estratégias diferentes.
6. Opções de diagnóstico
Opções como validação de subscritos, verificação numérica e informações de teste podem ajudar a detectar problemas.
Imagine:
01 TABELA-VALORES.
05 ITEM-VALOR OCCURS 10 TIMES
PIC 9(05).
01 WS-INDICE PIC 9(02).
MOVE 15 TO WS-INDICE
MOVE 100 TO ITEM-VALOR(WS-INDICE).
A tabela possui dez elementos.
O programa tenta acessar a posição quinze.
Sem verificações adequadas, o programa pode sobrescrever outra área de memória.
Com opções de runtime e compilação apropriadas, esse erro pode ser detectado.
Entretanto, verificações adicionais também podem consumir mais processamento.
Em produção, as empresas equilibram:
Segurança
Desempenho
Diagnóstico
Governança
7. O que é o código objeto?
O código objeto é o resultado principal da compilação.
Ele contém instruções de máquina e informações necessárias para a próxima fase.
Porém, ele ainda pode possuir referências externas.
Exemplo:
CALL 'PGMVALID'
USING WS-CPF
WS-RETORNO.
O compilador sabe que o programa possui uma referência a PGMVALID.
Dependendo do tipo de chamada e das opções utilizadas, essa referência poderá ser resolvida durante a linkedição ou durante a execução.
O objeto pode conter:
instruções de máquina;
áreas;
referências externas;
símbolos;
informações de relocação;
pontos de entrada;
dados necessários ao Binder.
Podemos pensar assim:
Código objeto = programa parcialmente montado
Ele já deixou de ser fonte, mas ainda pode não estar pronto para ser carregado.
8. O objeto não é o executável final
Essa é uma das maiores confusões entre iniciantes.
Depois da compilação, o programa ainda pode precisar de:
interfaces CICS;
interfaces Db2;
interfaces IMS;
módulos Adabas;
rotinas estáticas;
bibliotecas de suporte;
módulos de linguagem;
pontos de entrada;
resolução de referências.
Por isso, o processo continua:
Código objeto
↓
Binder
↓
Módulo executável
A compilação produz peças.
A linkedição reúne as peças.
9. O que é linkedição?
Linkedição é o processo de combinar o código objeto com outros módulos e referências para criar uma unidade executável.
Em inglês, você poderá encontrar termos como:
Link-edit
Linkage edition
Binding
Em ambientes modernos, a ferramenta principal é o Binder do z/OS.
Em documentações antigas, também aparece o termo Linkage Editor.
Podemos representar assim:
Objeto do programa principal
+
Rotinas externas
+
Interfaces de subsistemas
+
Módulos estáticos
+
Pontos de entrada
↓
Binder
↓
Módulo executável
10. O Binder do z/OS
O Binder é responsável por organizar e combinar os módulos recebidos.
Ele pode:
resolver referências externas;
incluir módulos;
definir pontos de entrada;
organizar seções;
produzir mapas;
gerar referências cruzadas;
identificar símbolos não resolvidos;
criar load modules;
criar program objects;
gravar o resultado em uma biblioteca executável.
Um JCL tradicional pode utilizar:
//LKED EXEC PGM=IEWL
O nome IEWL possui origem histórica no Linkage Editor.
Mesmo com a evolução para o Binder, ele continua aparecendo em muitos JCLs e procedures.
11. Um exemplo simples de compilação
Um JCL conceitual de compilação poderia ser:
//COMPILA JOB (1234),'BELLACOSA',
// CLASS=A,
// MSGCLASS=X,
// NOTIFY=&SYSUID
//*
//COBOL EXEC PGM=IGYCRCTL
//STEPLIB DD DISP=SHR,
// DSN=IGY.V6R5M0.SIGYCOMP
//SYSIN DD DISP=SHR,
// DSN=EMPRESA.SISTEMA.COBOL(PGMCLI01)
//SYSLIB DD DISP=SHR,
// DSN=EMPRESA.SISTEMA.COPYLIB
//SYSLIN DD DISP=(NEW,PASS),
// DSN=&&OBJ,
// UNIT=SYSDA,
// SPACE=(TRK,(5,5))
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD UNIT=SYSDA,
// SPACE=(CYL,(1,1))
Esse exemplo é simplificado.
O compilador lê o fonte em:
//SYSIN
Procura copybooks em:
//SYSLIB
Produz o objeto em:
//SYSLIN
Gera a listagem em:
//SYSPRINT
O dataset:
&&OBJ
é temporário.
Os dois sinais de && indicam um dataset temporário associado ao job.
O parâmetro:
DISP=(NEW,PASS)
significa que ele é criado nessa etapa e passado para a próxima.
12. A etapa de linkedição
Depois da compilação:
//LKED EXEC PGM=IEWL,
// PARM='LIST,MAP,XREF'
//SYSLIN DD DISP=(OLD,DELETE),
// DSN=&&OBJ
//SYSLMOD DD DISP=SHR,
// DSN=EMPRESA.SISTEMA.LOADLIB(PGMCLI01)
//SYSPRINT DD SYSOUT=*
O Binder recebe o objeto por meio de:
//SYSLIN
O resultado é gravado em:
//SYSLMOD
Nesse exemplo:
EMPRESA.SISTEMA.LOADLIB(PGMCLI01)
será o módulo executável.
A saída de diagnóstico será enviada para:
//SYSPRINT
13. O papel de SYSLIN e SYSLMOD
Esses DDNAMEs aparecem frequentemente em processos de linkedição.
SYSLIN
Contém a entrada para o Binder.
Pode incluir:
objetos;
control statements;
referências;
comandos
INCLUDE;instruções de entrada.
SYSLMOD
Define onde o módulo executável será gravado.
Exemplo:
//SYSLMOD DD DISP=SHR,
// DSN=EMPRESA.TESTE.LOADLIB(PGMCLI01)
Podemos resumir:
SYSLIN → entra objeto
SYSLMOD → sai executável
14. Comandos do Binder
O Binder pode receber comandos de controle.
Exemplo conceitual:
ENTRY PGMCLI01
NAME PGMCLI01(R)
O comando ENTRY pode definir o ponto inicial do programa.
O comando NAME pode indicar o nome do módulo que será criado.
Também podem existir comandos como:
INCLUDE
ALIAS
REPLACE
RENAME
SETCODE
A utilização varia conforme o processo e a arquitetura da aplicação.
Em muitas empresas, esses comandos ficam escondidos dentro de procedures ou ferramentas de build.
15. O que é ponto de entrada?
O ponto de entrada representa o local pelo qual a execução começa dentro do módulo.
Em um programa COBOL simples, isso normalmente é definido automaticamente.
Entretanto, módulos mais complexos podem possuir:
mais de um ponto de entrada;
aliases;
rotinas reutilizáveis;
estruturas compostas;
entry points adicionais.
Em COBOL, também existe a instrução:
ENTRY 'OUTROENT'
USING AREA-DADOS.
Esse recurso cria pontos adicionais de entrada em um programa.
Seu uso deve ser controlado, pois pode tornar a manutenção mais complexa.
16. Chamadas estáticas
Considere:
CALL 'PGMVALID'
USING WS-DADOS.
Em uma chamada estática, o módulo chamado é resolvido durante a linkedição.
O Binder precisa localizar PGMVALID.
Ele poderá incorporá-lo ou ligá-lo ao módulo principal.
Fluxo:
Objeto PGMCLI01
+
Objeto ou módulo PGMVALID
↓
Binder
↓
Executável combinado
Vantagens da chamada estática:
resolução antecipada;
menor risco de programa não encontrado em runtime;
controle sobre a versão ligada;
menos busca dinâmica.
Desvantagens:
alteração no subprograma pode exigir relinkedição;
executável pode crescer;
vários chamadores podem precisar ser atualizados;
maior acoplamento entre módulos.
17. Chamadas dinâmicas
Em uma chamada dinâmica, o módulo é localizado durante a execução.
Exemplo com nome variável:
01 WS-PROGRAMA PIC X(08).
MOVE 'PGMVALID' TO WS-PROGRAMA
CALL WS-PROGRAMA
USING WS-DADOS.
O nome está em uma variável.
Isso caracteriza uma chamada dinâmica.
Dependendo das opções do compilador, chamadas literais também podem ser tratadas dinamicamente.
O módulo não precisa ser incorporado ao chamador durante a linkedição.
Na execução, o sistema procurará PGMVALID nas bibliotecas disponíveis.
Vantagens:
atualização independente;
maior reutilização;
executável principal menor;
menor necessidade de relinkedição.
Desvantagens:
o programa pode não ser encontrado;
bibliotecas precisam estar corretas;
versões incompatíveis podem causar falhas;
o problema aparece somente em execução.
18. DYNAM e NODYNAM
Opções de compilação podem influenciar o tratamento das chamadas.
Conceitualmente:
DYNAM → favorece chamadas dinâmicas
NODYNAM → permite resolução estática de chamadas literais
O comportamento exato depende da forma da chamada e das opções utilizadas.
Um iniciante não deve apenas decorar os nomes.
É melhor compreender a pergunta principal:
O módulo chamado será ligado agora ou procurado durante a execução?
Essa resposta influencia:
tamanho do executável;
implantação;
dependências;
manutenção;
diagnóstico.
19. O que acontece quando uma referência não é resolvida?
Imagine que o programa possui:
CALL 'PGMVALID'
USING WS-DADOS.
O Binder espera localizar o módulo, mas ele não está nas bibliotecas informadas.
Pode ocorrer uma referência externa não resolvida.
O Binder poderá emitir mensagens indicando:
símbolo não encontrado;
módulo ausente;
biblioteca incorreta;
erro na resolução;
ponto de entrada inexistente.
Dependendo das opções, o processo poderá:
terminar com erro;
gerar módulo incompleto;
permitir execução com risco;
impedir a gravação do executável.
Por isso, a listagem do Binder precisa ser analisada.
20. Bibliotecas de objetos e módulos
O processo pode utilizar bibliotecas como:
EMPRESA.SISTEMA.OBJLIB
EMPRESA.SISTEMA.LOADLIB
EMPRESA.COMUM.LOADLIB
PRODUTO.INTERFACE.LOADLIB
OBJLIB
Pode armazenar módulos objeto.
Nem todas as empresas mantêm objetos permanentemente.
Algumas utilizam datasets temporários.
LOADLIB
Armazena módulos executáveis.
Bibliotecas comuns
Podem conter:
rotinas reutilizáveis;
interfaces;
subprogramas;
componentes corporativos;
módulos de fornecedores.
O Binder recebe essas bibliotecas por DD statements específicos, muitas vezes como:
//SYSLIB DD DISP=SHR,
// DSN=EMPRESA.COMUM.LOADLIB
21. Load module e program object
Durante décadas, o termo tradicional foi load module.
Com a evolução do z/OS e das bibliotecas PDSE, tornou-se comum utilizar program objects.
Um iniciante poderá ouvir:
load;
load module;
módulo de carga;
program object;
executável;
membro da loadlib.
Embora existam diferenças técnicas de formato e capacidade, todos representam o mesmo conceito geral:
Um artefato preparado para ser localizado, carregado e executado.
O program object moderno pode suportar recursos que os antigos load modules não suportavam da mesma forma.
Porém, no cotidiano, muitos profissionais continuam chamando tudo simplesmente de “load”.
22. A load library
A load library é uma biblioteca que contém módulos executáveis.
Exemplo:
EMPRESA.SISTEMA.LOADLIB
Membros:
PGMCLI01
PGMCLI02
PGMCALC
PGMREL01
PGMVALID
Ao abrir essa biblioteca no ISPF, o conteúdo não será um fonte COBOL legível.
Ela contém estruturas binárias.
O programador normalmente não edita diretamente um load module.
A alteração correta é feita no fonte.
Depois disso, o programa é recompilado e linkedidado.
23. Fonte, objeto e load
É importante visualizar a diferença.
Fonte
EMPRESA.SISTEMA.COBOL(PGMCLI01)
Contém código COBOL.
Objeto
EMPRESA.SISTEMA.OBJLIB(PGMCLI01)
Contém o resultado intermediário da compilação.
Load
EMPRESA.SISTEMA.LOADLIB(PGMCLI01)
Contém o módulo executável.
O mesmo nome pode existir em bibliotecas diferentes.
Isso não significa que sejam o mesmo tipo de conteúdo.
24. O perigo de executar a versão errada
Imagine que o programador compile uma nova versão em:
EMPRESA.TESTE.LOADLIB(PGMCLI01)
Porém, o JCL de teste utiliza:
//STEPLIB DD DISP=SHR,
// DSN=EMPRESA.ANTIGA.LOADLIB
O job executará a versão antiga.
O programador poderá dizer:
“Minha alteração não funcionou.”
Na realidade, o programa correto nunca foi carregado.
Esse problema é extremamente comum.
Sempre verifique:
onde o load foi gravado;
qual biblioteca está no JCL;
qual biblioteca está primeiro na concatenação;
se existe outro membro com o mesmo nome;
se o ambiente online carregou a nova versão.
25. Linkedição de programas CICS
Um programa CICS precisa ser preparado com as interfaces necessárias.
Historicamente, a linkedição poderia incluir módulos específicos do CICS.
Dependendo da arquitetura e versão, o processo pode utilizar stubs ou interfaces fornecidas pelo produto.
Além disso, o executável precisa ser disponibilizado em uma biblioteca acessível à região CICS.
Normalmente, encontramos referências a bibliotecas concatenadas na DFHRPL.
Fluxo simplificado:
Fonte CICS
↓
Tradução
↓
Compilação
↓
Linkedição com interfaces CICS
↓
Load library
↓
Biblioteca acessível ao CICS
Depois, o CICS precisa reconhecer ou atualizar o programa em execução.
Pode ser necessário utilizar recursos como:
new copy;
phase-in;
atualização de definição;
pipeline de deployment;
refresh do programa.
26. Linkedição de programas Db2
Programas Db2 também utilizam interfaces de conexão.
Um programa batch Db2 pode ser linkedidado com componentes apropriados para o método de conexão utilizado.
Além disso, o DBRM precisa passar pelo BIND.
Portanto, existem dois resultados:
Load module COBOL
Package Db2
Os dois precisam estar compatíveis.
Podem ocorrer problemas como:
load novo com package antigo;
package novo com load antigo;
collection incorreta;
plano incorreto;
versão incompatível;
módulo em biblioteca errada.
Esse tipo de situação mostra por que a implantação precisa coordenar artefatos.
27. Linkedição de programas IMS
Programas IMS podem precisar de interfaces DL/I durante a linkedição.
O método exato varia conforme:
tipo de região;
forma de execução;
ambiente IMS;
linguagem;
procedures da empresa.
O módulo executável também precisa ser chamado em conjunto com o PSB adequado.
Isso significa que a execução depende de:
Load module
PSB
PCBs
DBDs
Ambiente IMS
O load sozinho não representa toda a aplicação.
28. Linkedição de programas Adabas
Programas COBOL que acessam Adabas precisam das interfaces correspondentes.
Durante a linkedição, módulos de comunicação e bibliotecas fornecidas pelo ambiente podem ser incluídos ou referenciados.
Na execução, o programa utilizará essas interfaces para se comunicar com o Adabas Nucleus.
Assim como nos demais subsistemas:
Programa COBOL + interface especializada = acesso ao serviço
29. Procedures catalogadas
Em muitas empresas, o programador não escreve manualmente o JCL completo de compilação e linkedição.
Ele utiliza uma procedure catalogada.
Exemplo:
//COMPILA EXEC PROC=COBOLCL
Ou:
//COMPILA EXEC PROC=COB2CL
Ou:
//COMPILA EXEC PROC=COBCICS
A procedure pode esconder:
tradução;
pré-compilação;
compilação;
linkedição;
BIND;
bibliotecas;
opções;
datasets temporários;
controles corporativos.
O Padawan vê uma única linha.
Por trás dela podem existir dezenas de etapas.
30. O que é uma procedure catalogada?
Uma procedure catalogada é um conjunto reutilizável de instruções JCL armazenado em uma biblioteca de procedures.
Exemplo conceitual:
SYS1.PROCLIB
EMPRESA.PROCLIB
Dentro dela:
COBOLCL
COBDB2
COBCICS
COBIMS
A procedure permite padronizar o processo.
Benefícios:
evita duplicação;
centraliza opções;
facilita manutenção;
reduz erros;
garante bibliotecas corretas;
padroniza retorno;
integra ferramentas corporativas.
Porém, também pode esconder detalhes.
Por isso, o iniciante deve aprender a abrir e analisar a procedure.
31. Parâmetros simbólicos
Procedures podem utilizar parâmetros.
Exemplo conceitual:
//COMPILA EXEC COBOLCL,
// MEMBER=PGMCLI01,
// SRCLIB=EMPRESA.SISTEMA.COBOL,
// LOADLIB=EMPRESA.SISTEMA.LOADLIB
Dentro da procedure, podem existir símbolos como:
&MEMBER
&SRCLIB
&LOADLIB
Quando o job é submetido, esses símbolos são substituídos.
Isso permite utilizar a mesma procedure para vários programas.
32. Compilação local, pipeline e ferramentas modernas
Nem todo processo moderno é iniciado manualmente por JCL.
Empresas podem utilizar:
IBM Developer for z/OS;
IBM Z Open Editor;
VS Code;
Git;
Jenkins;
IBM Dependency Based Build;
zBuilder;
UrbanCode Deploy;
Endevor;
ISPW;
ferramentas internas;
pipelines CI/CD.
O desenvolvedor altera o fonte e aciona um pipeline.
O pipeline pode:
detectar dependências;
identificar copybooks alterados;
traduzir CICS;
processar SQL;
compilar COBOL;
linkeditar;
executar testes;
gerar evidências;
promover artefatos;
implantar o load.
Mesmo com automação, os fundamentos continuam iguais.
A ferramenta não elimina as etapas.
Ela apenas as coordena.
33. Análise de impacto de copybook
Imagine que CPYCLI01 seja usado por cem programas.
Uma alteração foi realizada:
05 CLI-LIMITE PIC S9(13)V99 COMP-3.
Antes:
05 CLI-LIMITE PIC S9(11)V99 COMP-3.
Os programas dependentes podem precisar ser recompilados.
Uma ferramenta de build baseada em dependências pode identificar:
CPYCLI01 alterado
↓
PGMCLI01 afetado
PGMCLI02 afetado
PGMREL01 afetado
PGMCRD01 afetado
Esse processo evita que apenas um módulo seja recompilado enquanto outros continuam utilizando o layout antigo.
34. Return codes da compilação
Durante a compilação, o job pode terminar com códigos como:
RC=0000
RC=0004
RC=0008
RC=0012
RC=0016
Uma interpretação geral:
RC 0
Nenhum erro relevante foi encontrado.
RC 4
Foram geradas advertências.
O programa pode ter sido produzido, mas as mensagens precisam ser analisadas.
RC 8
Existem erros significativos.
Em muitos processos, a linkedição não deve continuar.
RC 12
Erros graves impediram a geração correta.
RC 16
Falha severa, problema estrutural ou impossibilidade de processamento.
Os significados exatos dependem da etapa e das mensagens.
Nunca utilize apenas o número como diagnóstico completo.
35. O perigo do RC 4
O programador pode pensar:
“RC 4 é normal.”
Às vezes, a advertência é realmente conhecida.
Mas um RC 4 pode indicar:
campo não utilizado;
conversão perigosa;
valor truncado;
incompatibilidade de tipo;
comportamento obsoleto;
opção ignorada;
possível erro lógico;
recurso que mudará em versões futuras.
Em sistemas críticos, advertências precisam ser classificadas.
O objetivo não é aceitar tudo nem rejeitar tudo.
O objetivo é compreender.
36. Return code do Binder
A linkedição também produz return code.
Problemas podem incluir:
referência externa não resolvida;
módulo ausente;
biblioteca indisponível;
símbolo duplicado;
erro de ponto de entrada;
espaço insuficiente;
formato incompatível;
opção inválida.
O Binder pode gerar o módulo mesmo com algumas advertências.
Porém, isso não significa que o executável esteja seguro.
Leia:
mensagens;
map;
cross-reference;
entry point;
unresolved references;
bibliotecas utilizadas.
37. MAP e XREF
Opções como:
MAP
XREF
LIST
podem gerar informações úteis.
MAP
Mostra o mapa do módulo.
Pode ajudar a entender:
seções;
tamanhos;
endereços relativos;
módulos incluídos;
organização do executável.
XREF
Mostra referências cruzadas.
Ajuda a identificar:
símbolos;
definições;
referências;
módulos que fornecem determinados nomes.
Essas informações são valiosas na investigação de problemas de linkedição.
38. Erros de compilação mais comuns
Entre os erros frequentes:
campo não definido;
palavra reservada usada incorretamente;
parágrafo inexistente;
END-IFausente;ponto final em posição incorreta;
copybook não encontrado;
PIC inválida;
nível hierárquico incorreto;
variável incompatível;
arquivo sem definição adequada;
SQL ou CICS não processado.
Exemplo:
MOVE WS-VALOR TO WS-CAMPO-INEXISTENTE.
O compilador identifica a referência inexistente.
39. Erros de linkedição mais comuns
Entre os erros frequentes:
subprograma estático ausente;
biblioteca não concatenada;
módulo com nome diferente;
interface de subsistema ausente;
símbolo externo não resolvido;
entrada incorreta;
módulo incompatível;
control statements incorretos.
Exemplo:
CALL 'PGMCALC'
Mas a biblioteca possui:
PGMCAL01
O nome não corresponde.
A resolução poderá falhar.
40. Erro de compilação não é erro de execução
É importante separar as fases.
Compilação
Analisa e traduz o fonte.
Linkedição
Monta o executável.
Carga
Localiza o módulo durante a execução.
Runtime
Executa a lógica e acessa dados.
Um problema pode ocorrer em qualquer uma dessas etapas.
Exemplo:
Fonte correto
Compilação RC 0
Linkedição RC 0
Execução S806
Nesse caso, o programa foi criado, mas o sistema não o encontrou na biblioteca de execução.
Outro exemplo:
Compilação RC 0
Linkedição RC 0
Programa executado
FILE STATUS 35
O executável está correto, mas o arquivo não foi localizado ou aberto.
Diagnóstico correto começa pela identificação da fase.
41. O Language Environment
Programas COBOL modernos no z/OS normalmente executam sob o Language Environment.
O Language Environment fornece serviços comuns para linguagens como:
COBOL;
PL/I;
C;
C++.
Ele participa de:
inicialização;
gerenciamento de memória;
parâmetros;
tratamento de condições;
mensagens;
datas;
conversões;
finalização;
dumps;
interoperabilidade.
Durante a linkedição e execução, o programa pode depender de componentes do Language Environment.
Mensagens iniciadas por:
CEE
frequentemente estão relacionadas a esse ambiente.
42. RENT e programas reentrantes
Programas online, especialmente CICS, costumam precisar ser reentrantes.
Um programa reentrante pode ser compartilhado com segurança por várias tasks, desde que não modifique indevidamente áreas comuns de código ou dados.
A opção:
RENT
está associada à geração de código reentrante.
Isso é importante porque o CICS pode atender milhares de transações concorrentes.
O código pode ser compartilhado, enquanto cada task possui suas áreas de trabalho apropriadas.
Um programa não reentrante pode causar:
corrupção de dados;
interferência entre usuários;
resultados imprevisíveis;
falhas de integridade.
43. O perigo de armazenar estado no lugar errado
Imagine um programa CICS que mantém dados mutáveis em uma área compartilhada de forma incorreta.
Duas tasks podem executar o mesmo módulo simultaneamente.
A task A altera uma informação.
A task B enxerga ou sobrescreve essa mesma informação.
O resultado pode ser uma mistura de dados entre transações.
Por isso, programas online utilizam estruturas como:
COMMAREA;
channels e containers;
working-storage gerenciado adequadamente;
áreas fornecidas pelo CICS;
TSQ;
contextos transacionais.
A reentrância não é apenas uma opção técnica.
É uma garantia de convivência segura entre múltiplas execuções.
44. Versionamento do load
Em ambientes corporativos, o load module precisa ser controlado.
Perguntas importantes:
Qual fonte gerou o load?
Qual versão do copybook foi usada?
Qual compilador foi utilizado?
Quais opções foram aplicadas?
Qual pipeline gerou o módulo?
Qual commit corresponde ao executável?
Qual package Db2 foi associado?
Quando o load foi implantado?
Quem aprovou a promoção?
Sem rastreabilidade, o executável vira uma caixa-preta.
45. Programa compilado não significa programa testado
Uma compilação com RC 0 prova apenas que o compilador conseguiu processar o fonte.
Ela não prova que:
a regra de negócio está correta;
os dados foram tratados corretamente;
o SQL possui bom desempenho;
o arquivo está definido corretamente;
a transação CICS funciona;
o programa IMS utiliza o segmento correto;
o código Adabas trata todos os retornos;
o módulo não causa abend;
o programa atende ao requisito.
Compilação é uma etapa de validação técnica.
Teste é outra disciplina.
46. Um fluxo moderno de build
Um pipeline moderno pode executar:
Checkout do fonte
↓
Análise de dependências
↓
Expansão e localização de copybooks
↓
Tradução CICS
↓
Processamento Db2
↓
Compilação COBOL
↓
Linkedição
↓
BIND package
↓
Testes unitários
↓
Análise de qualidade
↓
Empacotamento
↓
Implantação
Esse fluxo parece moderno, mas continua baseado nos mesmos fundamentos utilizados há décadas.
O que mudou foi o nível de automação.
47. Exemplo completo do caminho até o load
Imagine o programa:
PGMCLI01
Ele utiliza:
CPYCLI01
EXEC CICS
EXEC SQL
CALL PGMVALID
O processo poderá ser:
1. Ler PGMCLI01
2. Localizar CPYCLI01
3. Traduzir EXEC CICS
4. Processar EXEC SQL
5. Gerar DBRM
6. Compilar o fonte preparado
7. Gerar objeto PGMCLI01
8. Localizar PGMVALID
9. Incluir interfaces CICS e Db2
10. Executar o Binder
11. Gravar PGMCLI01 na LOADLIB
12. Executar BIND do DBRM
13. Criar package Db2
Ao final:
EMPRESA.SISTEMA.LOADLIB(PGMCLI01)
e:
Package Db2 de PGMCLI01
estarão prontos para a próxima fase.
48. Checklist do Programador COBOL Padawan
Antes de declarar que o programa está pronto, verifique:
O fonte correto foi compilado?
Os copybooks corretos foram utilizados?
A biblioteca de copybooks estava na ordem certa?
Houve tradução CICS?
O SQL foi processado?
O DBRM foi gerado?
O package foi criado?
O compilador terminou com qual RC?
Existem warnings?
O Binder resolveu todas as referências?
O load foi gravado na biblioteca correta?
As chamadas são estáticas ou dinâmicas?
Os módulos chamados estão disponíveis?
A versão do load corresponde ao fonte?
Os testes foram executados?
A implantação utilizará a mesma load library?
Esse checklist evita muitos problemas que parecem misteriosos.
49. O grande mapa mental da Parte III
Podemos resumir toda a transformação:
Fonte preparado
↓
Compilador COBOL
↓
Validação
↓
Geração de instruções
↓
Código objeto
↓
Binder
↓
Resolução de referências
↓
Inclusão de módulos
↓
Definição do ponto de entrada
↓
Load module ou program object
↓
Load library
Em paralelo, quando houver Db2:
DBRM
↓
BIND
↓
Package
50. Uma analogia com uma fábrica
Imagine uma fábrica de automóveis.
O código-fonte é o projeto do veículo.
Os copybooks são padrões de componentes:
medidas;
conectores;
peças;
encaixes.
O compilador transforma o projeto em peças reais.
Ele produz:
motor;
chassis;
painel;
sistemas de controle.
Entretanto, as peças ainda estão separadas.
O Binder é a linha de montagem.
Ele reúne:
objeto principal;
módulos externos;
interfaces;
componentes;
pontos de entrada.
O resultado é o veículo montado.
A load library é o pátio onde os veículos prontos ficam armazenados.
Porém, o carro ainda não saiu do pátio.
Ele ainda precisa ser localizado, ligado e colocado na estrada.
Essa será a missão do próximo capítulo.
51. Conselhos do Mestre Bellacosa
Nunca trate a compilação como um botão misterioso.
Abra as listagens.
Leia as mensagens.
Entenda a procedure.
Descubra:
qual compilador foi utilizado;
quais opções foram aplicadas;
quais bibliotecas foram concatenadas;
quais copybooks foram encontrados;
quais módulos foram incluídos;
onde o objeto foi gravado;
onde o load foi criado;
quais referências foram resolvidas;
quais warnings foram emitidos.
O profissional que entende o processo de build investiga problemas com muito mais precisão.
Ele não diz apenas:
“A compilação falhou.”
Ele diz:
“O pré-processamento terminou corretamente, mas o Binder não resolveu o módulo estático porque a biblioteca de interfaces não estava na concatenação de SYSLIB.”
Esse é o tipo de compreensão que transforma um Padawan em especialista.
Conclusão
A compilação é o processo que transforma o código-fonte COBOL em código objeto.
Durante essa etapa, o compilador verifica sintaxe, campos, tipos de dados, referências, estruturas, opções e dependências.
O código objeto já contém instruções de máquina, mas ainda pode possuir referências externas.
Por isso, ele precisa passar pelo Binder.
A linkedição combina o objeto com módulos, interfaces e rotinas necessárias, resolvendo referências e criando um módulo executável.
Esse resultado é armazenado em uma load library.
Também aprendemos que chamadas podem ser estáticas ou dinâmicas.
Chamadas estáticas são resolvidas durante a linkedição.
Chamadas dinâmicas são localizadas durante a execução.
Vimos ainda que CICS, Db2, IMS e Adabas podem exigir interfaces específicas, e que o programa Db2 precisa coordenar dois artefatos fundamentais:
Load module
Package Db2
Ao final dessa etapa, o programa finalmente existe como executável.
Mas ele ainda está parado dentro de uma biblioteca.
Ele não abriu arquivos.
Não leu registros.
Não consultou tabelas.
Não consumiu CPU.
Não produziu relatórios.
A última etapa da jornada está prestes a começar.
No próximo capítulo
Na Parte IV — Da Load Library à CPU, vamos acompanhar o módulo durante a execução.
Veremos passo a passo:
como o JCL solicita a execução;
como a STEPLIB localiza o programa;
como QSAM e VSAM são conectados por DDNAME;
como o JES2 recebe e organiza o job;
o que é spool;
como o initiator inicia o processamento;
como o loader coloca o programa na memória;
como WLM e dispatcher participam;
como a CPU executa as instruções;
por que tempo de CPU é diferente de tempo decorrido;
como programas CICS, Db2, IMS e Adabas executam no ambiente real.
Prepare a quarta xícara de café.
O programa já nasceu, foi traduzido, compilado e linkedidado.
Agora chegou o momento de fazê-lo trabalhar.
☕
“O Padawan acredita que a compilação cria o programa. O especialista sabe que a compilação cria as peças, a linkedição monta a máquina e a execução provará se toda a engenharia realmente funciona.”
Sem comentários:
Enviar um comentário