<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Plínio Balduino</title>
    <description>The latest articles on DEV Community by Plínio Balduino (@pbalduino).</description>
    <link>https://dev.to/pbalduino</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F335931%2F5ae6241b-74de-4c8e-bedb-a14e2fcd8d0d.jpg</url>
      <title>DEV Community: Plínio Balduino</title>
      <link>https://dev.to/pbalduino</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pbalduino"/>
    <language>en</language>
    <item>
      <title>[pt-BR] AWS Landing Zones na prática - Parte 1</title>
      <dc:creator>Plínio Balduino</dc:creator>
      <pubDate>Wed, 19 Aug 2026 15:00:00 +0000</pubDate>
      <link>https://dev.to/pbalduino/aws-landing-zones-na-pratica-parte-1-3847</link>
      <guid>https://dev.to/pbalduino/aws-landing-zones-na-pratica-parte-1-3847</guid>
      <description>&lt;p&gt;Quando uma organização começa a utilizar AWS, é relativamente comum que tudo nasça dentro de uma única conta.&lt;/p&gt;

&lt;p&gt;No começo, isso parece razoável. Uma conta contém algumas VPCs, aplicações, bancos de dados, buckets e usuários. Com o crescimento do ambiente, porém, começam a surgir perguntas mais difíceis:&lt;/p&gt;

&lt;p&gt;Produção e desenvolvimento deveriam estar na mesma conta?, Onde devem ficar os logs de auditoria?, Como impedir que uma equipe desative controles de segurança?, Como conceder acesso a dezenas ou centenas de contas?, Como garantir que novas contas sejam criadas seguindo os mesmos padrões?, Como aplicar políticas corporativas sem configurar cada conta individualmente? e Como separar workloads, segurança, infraestrutura compartilhada e billing?.&lt;/p&gt;

&lt;p&gt;É nesse contexto que surge o conceito de &lt;strong&gt;Landing Zone&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é uma Landing Zone?
&lt;/h2&gt;

&lt;p&gt;A AWS define uma Landing Zone como um &lt;strong&gt;framework de orquestração para o ambiente AWS fundamental da organização&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ela estabelece uma baseline para aspectos como:&lt;/p&gt;

&lt;p&gt;arquitetura multi-account, Identity and Access Management, governança, segurança de dados, arquitetura de rede, logging, estrutura de contas, billing e mecanismos de customização..&lt;/p&gt;

&lt;p&gt;Portanto, uma Landing Zone não é simplesmente uma VPC preparada para receber aplicações.&lt;/p&gt;

&lt;p&gt;Também não é apenas uma estrutura de AWS Organizations.&lt;/p&gt;

&lt;p&gt;E não é sinônimo de AWS Control Tower.&lt;/p&gt;

&lt;p&gt;Uma maneira útil de pensar no conceito é:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A Landing Zone é a fundação sobre a qual os workloads da organização serão construídos.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Antes de migrarmos ou criarmos aplicações, estabelecemos as regras do terreno.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uma arquitetura multi-account
&lt;/h2&gt;

&lt;p&gt;Um dos princípios centrais de uma Landing Zone é utilizar &lt;strong&gt;AWS Accounts como fronteiras de isolamento&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Em vez de construir algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Account
├── VPC Development
├── VPC Staging
├── VPC Production
├── Security
├── Logs
└── Shared Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;podemos estabelecer uma estrutura semelhante a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Organization
│
├── Security OU
│   ├── Log Archive Account
│   └── Audit Account
│
├── Infrastructure OU
│   ├── Network Account
│   └── Shared Services Account
│
├── Workloads OU
│   ├── Development Account
│   ├── Staging Account
│   └── Production Account
│
└── Sandbox OU
    ├── Developer A
    └── Developer B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa separação cria fronteiras mais fortes entre workloads e responsabilidades.&lt;/p&gt;

&lt;p&gt;Uma falha de configuração em uma conta de desenvolvimento, por exemplo, não precisa conceder acesso aos recursos da conta de produção.&lt;/p&gt;

&lt;p&gt;A AWS recomenda que workloads de produção não sejam executados na management account de uma organização gerenciada pelo Control Tower.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que uma Landing Zone deve resolver?
&lt;/h2&gt;

&lt;p&gt;Segundo a AWS Prescriptive Guidance, a configuração inicial deve tratar pelo menos de estrutura de contas, identidade, governança, segurança, rede, logging, billing e mecanismos de customização.&lt;/p&gt;

&lt;h3&gt;
  
  
  Estrutura de contas
&lt;/h3&gt;

&lt;p&gt;É necessário definir como as AWS Accounts serão organizadas e quais Organizational Units (OUs) serão utilizadas.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Root
├── Security
├── Infrastructure
├── Workloads
└── Sandbox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Estrutura de rede
&lt;/h3&gt;

&lt;p&gt;A Landing Zone deve estabelecer padrões de conectividade e governança para componentes como:&lt;/p&gt;

&lt;p&gt;VPCs, subnets, DNS, Transit Gateway, conectividade híbrida, Direct Connect, VPN, firewalls e IP Address Management..&lt;/p&gt;

&lt;p&gt;Ela não precisa necessariamente criar toda a infraestrutura de rede de cada workload, mas deve definir como essa infraestrutura será organizada e governada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identity
&lt;/h3&gt;

&lt;p&gt;Também é necessário definir como pessoas e sistemas acessam as contas.&lt;/p&gt;

&lt;p&gt;Isso normalmente envolve:&lt;/p&gt;

&lt;p&gt;IAM, IAM Identity Center, roles, permission sets e federação com provedores de identidade corporativos..&lt;/p&gt;

&lt;h3&gt;
  
  
  Logging e auditoria
&lt;/h3&gt;

&lt;p&gt;Logs de auditoria não deveriam existir apenas dentro da própria conta que está sendo auditada.&lt;/p&gt;

&lt;p&gt;Uma arquitetura comum centraliza esses registros em uma conta dedicada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application Accounts
        │
        ├── CloudTrail
        ├── AWS Config
        └── Security Logs
                │
                ▼
        Log Archive Account
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso reduz a possibilidade de um comprometimento da conta de workload resultar também na destruição das evidências necessárias para auditoria ou investigação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Governance
&lt;/h3&gt;

&lt;p&gt;A organização precisa determinar quais ações são permitidas ou proibidas.&lt;/p&gt;

&lt;p&gt;AWS Organizations permite, por exemplo, utilizar &lt;strong&gt;Service Control Policies (SCPs)&lt;/strong&gt; para estabelecer limites máximos de permissões.&lt;/p&gt;

&lt;p&gt;Em vez de depender de cada equipe para configurar individualmente todos os controles, podemos estabelecer políticas organizacionais como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Workloads não podem desabilitar determinados mecanismos de segurança.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Landing Zone não é Control Tower
&lt;/h2&gt;

&lt;p&gt;Essa distinção é importante.&lt;/p&gt;

&lt;p&gt;A documentação da AWS diferencia duas abordagens principais:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;uma &lt;strong&gt;service-based landing zone&lt;/strong&gt;, utilizando AWS Control Tower;&lt;/li&gt;
&lt;li&gt;uma &lt;strong&gt;customized landing zone&lt;/strong&gt;, construída pela própria organização.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O AWS Control Tower é, portanto, uma implementação gerenciada do conceito de Landing Zone — não o conceito em si.&lt;/p&gt;

&lt;h2&gt;
  
  
  Landing Zone com AWS Control Tower
&lt;/h2&gt;

&lt;p&gt;O AWS Control Tower automatiza boa parte da criação e governança de um ambiente multi-account.&lt;/p&gt;

&lt;p&gt;Ele orquestra diferentes serviços AWS envolvidos nessa fundação, incluindo AWS Organizations, IAM Identity Center, AWS Service Catalog, AWS CloudTrail e AWS Config.&lt;/p&gt;

&lt;p&gt;Uma estrutura inicial típica inclui:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Management Account
│
└── AWS Organization
    │
    ├── Security OU
    │   ├── Log Archive
    │   └── Audit
    │
    └── Workload OUs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;strong&gt;Log Archive Account&lt;/strong&gt; funciona como repositório central para logs, enquanto o &lt;strong&gt;Audit Account&lt;/strong&gt; fornece capacidades destinadas às equipes de segurança e compliance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Controls
&lt;/h3&gt;

&lt;p&gt;Outro componente importante são os &lt;strong&gt;Controls&lt;/strong&gt;, anteriormente conhecidos principalmente como &lt;em&gt;guardrails&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Eles representam mecanismos de governança aplicados ao ambiente. O Control Tower trabalha com controles de diferentes comportamentos, incluindo:&lt;/p&gt;

&lt;p&gt;preventive, detective e proactive..&lt;/p&gt;

&lt;p&gt;Um control pode impedir determinadas operações, enquanto outro pode detectar recursos que deixaram de atender a uma regra.&lt;/p&gt;

&lt;p&gt;Isso muda a natureza da governança:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Provisionar → Configurar → Torcer para ninguém alterar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;passa a ser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Provisionar
     ↓
Aplicar baseline
     ↓
Monitorar continuamente
     ↓
Detectar ou impedir desvios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Account Factory
&lt;/h3&gt;

&lt;p&gt;Outro recurso importante é o &lt;strong&gt;Account Factory&lt;/strong&gt;, usado para padronizar o provisionamento de novas contas.&lt;/p&gt;

&lt;p&gt;Em vez de:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ticket → Cloud Team → configuração manual → nova conta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;podemos caminhar para:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Solicitação
     ↓
Account Factory
     ↓
AWS Account
     ↓
Baseline
     ↓
OU
     ↓
Controls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso se torna especialmente relevante em organizações que administram dezenas ou centenas de AWS Accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Landing Zone customizada
&lt;/h2&gt;

&lt;p&gt;Também é possível construir uma Landing Zone sem utilizar Control Tower.&lt;/p&gt;

&lt;p&gt;Nesse cenário, podemos combinar diretamente serviços como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Organizations
+
Organizational Units
+
SCPs
+
IAM Identity Center
+
CloudTrail
+
AWS Config
+
Security Hub
+
GuardDuty
+
VPC / Transit Gateway
+
Infrastructure as Code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terraform, CloudFormation ou outras ferramentas podem então automatizar essa arquitetura.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Terraform
   │
   ├── AWS Organizations
   ├── Organizational Units
   ├── Accounts
   ├── SCPs
   ├── IAM
   ├── Logging
   └── Networking
   │
   ▼
Custom Landing Zone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse modelo, a organização possui maior liberdade sobre a implementação.&lt;/p&gt;

&lt;p&gt;O preço dessa liberdade é assumir também a responsabilidade pela evolução, manutenção, testes, upgrades e tratamento de drift da plataforma.&lt;/p&gt;

&lt;h2&gt;
  
  
  Control Tower versus Landing Zone customizada
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspecto&lt;/th&gt;
&lt;th&gt;Control Tower&lt;/th&gt;
&lt;th&gt;Customizada&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Provisionamento inicial&lt;/td&gt;
&lt;td&gt;Mais simples&lt;/td&gt;
&lt;td&gt;Mais complexo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS best practices&lt;/td&gt;
&lt;td&gt;Incorporadas ao modelo&lt;/td&gt;
&lt;td&gt;Precisam ser implementadas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexibilidade&lt;/td&gt;
&lt;td&gt;Alta, dentro do modelo do serviço&lt;/td&gt;
&lt;td&gt;Muito alta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Governança&lt;/td&gt;
&lt;td&gt;Controls integrados&lt;/td&gt;
&lt;td&gt;Implementação própria&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Account provisioning&lt;/td&gt;
&lt;td&gt;Account Factory&lt;/td&gt;
&lt;td&gt;Pipeline próprio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manutenção&lt;/td&gt;
&lt;td&gt;Parcialmente gerenciada pela AWS&lt;/td&gt;
&lt;td&gt;Responsabilidade da equipe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curva de aprendizado&lt;/td&gt;
&lt;td&gt;Menor&lt;/td&gt;
&lt;td&gt;Maior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customização extrema&lt;/td&gt;
&lt;td&gt;Pode exigir adaptações&lt;/td&gt;
&lt;td&gt;Natural&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drift management&lt;/td&gt;
&lt;td&gt;Integrado ao modelo do Control Tower&lt;/td&gt;
&lt;td&gt;Precisa ser projetado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integração com legado&lt;/td&gt;
&lt;td&gt;Pode exigir adaptação&lt;/td&gt;
&lt;td&gt;Maior liberdade&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Essa comparação não significa que Control Tower seja uma solução para iniciantes e uma Landing Zone customizada seja uma solução para arquitetos experientes.&lt;/p&gt;

&lt;p&gt;A decisão é arquitetural.&lt;/p&gt;

&lt;p&gt;Uma organização grande pode preferir Control Tower justamente para &lt;strong&gt;reduzir a quantidade de plataforma que precisa manter internamente&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Outra organização pode possuir requisitos de rede, compliance, identidade ou provisionamento tão específicos que uma implementação customizada faça mais sentido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vantagens
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Isolamento
&lt;/h3&gt;

&lt;p&gt;AWS Accounts tornam-se fronteiras de segurança.&lt;/p&gt;

&lt;p&gt;Um comprometimento em uma conta de desenvolvimento não implica automaticamente comprometimento da conta de produção.&lt;/p&gt;

&lt;h3&gt;
  
  
  Governança centralizada
&lt;/h3&gt;

&lt;p&gt;Políticas podem ser aplicadas no nível da organização ou de uma OU:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Organization
     │
     ├── SCPs
     ├── Controls
     ├── Identity
     └── Logging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso reduz configurações divergentes entre contas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escalabilidade organizacional
&lt;/h3&gt;

&lt;p&gt;Criar a décima conta manualmente talvez seja aceitável.&lt;/p&gt;

&lt;p&gt;Criar a conta número 500 dessa maneira provavelmente não será.&lt;/p&gt;

&lt;p&gt;Uma Landing Zone transforma a criação e configuração de contas em uma capacidade da plataforma.&lt;/p&gt;

&lt;h3&gt;
  
  
  Segurança
&lt;/h3&gt;

&lt;p&gt;A separação entre workloads, security, audit, logging e infrastructure reduz o &lt;em&gt;blast radius&lt;/em&gt; e melhora a segregação de responsabilidades.&lt;/p&gt;

&lt;h3&gt;
  
  
  Migrações
&lt;/h3&gt;

&lt;p&gt;Landing Zones são particularmente importantes em programas de cloud migration.&lt;/p&gt;

&lt;p&gt;Antes de migrar centenas de workloads, cria-se uma fundação comum para recebê-los.&lt;/p&gt;

&lt;p&gt;A AWS Prescriptive Guidance trata a Landing Zone como uma base segura para suportar migração e posterior customização do ambiente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Desvantagens
&lt;/h2&gt;

&lt;p&gt;Landing Zones também possuem custos arquiteturais.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complexidade
&lt;/h3&gt;

&lt;p&gt;Uma arquitetura multi-account introduz conceitos adicionais:&lt;/p&gt;

&lt;p&gt;cross-account IAM, SCPs, Organizations, resource sharing, centralized networking, centralized logging e account lifecycle..&lt;/p&gt;

&lt;p&gt;Para uma aplicação pequena, isso pode representar complexidade desnecessária.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custo operacional
&lt;/h3&gt;

&lt;p&gt;Mais contas normalmente significam mais infraestrutura compartilhada e serviços de governança.&lt;/p&gt;

&lt;p&gt;Logs, AWS Config, NAT Gateways, Transit Gateway, serviços de segurança e observabilidade podem gerar custos relevantes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Troubleshooting
&lt;/h3&gt;

&lt;p&gt;Em uma arquitetura simples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application → Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o troubleshooting tende a permanecer dentro de uma conta.&lt;/p&gt;

&lt;p&gt;Em uma arquitetura corporativa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application Account
        ↓
Transit Gateway
        ↓
Network Account
        ↓
Firewall
        ↓
Shared Services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o problema pode atravessar várias fronteiras administrativas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restrições de governança
&lt;/h3&gt;

&lt;p&gt;Governança forte também pode reduzir autonomia.&lt;/p&gt;

&lt;p&gt;Um desenvolvedor pode possuir &lt;code&gt;AdministratorAccess&lt;/code&gt; dentro de uma conta e ainda assim não conseguir executar determinada operação porque uma SCP estabelece um limite organizacional.&lt;/p&gt;

&lt;p&gt;Isso é proposital, mas pode gerar atrito se a Landing Zone for mal projetada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando usar?
&lt;/h2&gt;

&lt;p&gt;Landing Zones fazem bastante sentido quando existe:&lt;/p&gt;

&lt;p&gt;estratégia multi-account, múltiplos ambientes, vários times, workloads críticos, requisitos de compliance, necessidade de auditoria, migração de múltiplos sistemas, necessidade de padronização e crescimento significativo esperado..&lt;/p&gt;

&lt;p&gt;Para um cenário como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uma aplicação
+
uma equipe pequena
+
uma conta AWS
+
baixo requisito regulatório
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;uma Landing Zone completa pode ser excessiva.&lt;/p&gt;

&lt;p&gt;Para um cenário como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;50 aplicações
+
20 equipes
+
produção
+
requisitos regulatórios
+
múltiplas regiões
+
centenas de AWS Accounts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a ausência de uma estratégia de Landing Zone tende a se tornar um problema arquitetural.&lt;/p&gt;

&lt;h2&gt;
  
  
  Control Tower ou customizada?
&lt;/h2&gt;

&lt;p&gt;Uma pergunta inicial razoável é:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Existe alguma exigência concreta que impeça ou torne inadequado o uso do Control Tower?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se a resposta for &lt;strong&gt;não&lt;/strong&gt;, Control Tower normalmente merece ser considerado primeiro.&lt;/p&gt;

&lt;p&gt;A AWS gerencia parte importante da orquestração e fornece controles, Account Factory e uma baseline baseada nas práticas recomendadas da plataforma.&lt;/p&gt;

&lt;p&gt;Uma Landing Zone customizada passa a ser particularmente interessante quando requisitos organizacionais não se encaixam adequadamente nesse modelo.&lt;/p&gt;

&lt;p&gt;Existe ainda uma terceira possibilidade bastante importante: &lt;strong&gt;Control Tower + customizações&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Não precisamos escolher exclusivamente entre:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Control Tower
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tudo construído manualmente
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos ter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AWS Control Tower
       │
       ├── baseline
       ├── governance
       ├── account lifecycle
       │
       ▼
Customizações
       │
       ├── Terraform
       ├── CloudFormation
       ├── networking
       ├── security tooling
       └── corporate standards
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para muitas organizações, esse é um ponto de equilíbrio interessante entre padronização e flexibilidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nas próximas partes
&lt;/h2&gt;

&lt;p&gt;Agora temos uma distinção fundamental:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Landing Zone ≠ AWS Control Tower
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Control Tower é uma das formas de implementar e operar uma Landing Zone.&lt;/p&gt;

&lt;p&gt;Na &lt;strong&gt;Parte 2&lt;/strong&gt;, construiremos uma Landing Zone programaticamente utilizando &lt;strong&gt;AWS CLI&lt;/strong&gt;, explorando AWS Organizations, AWS Control Tower, o Landing Zone Manifest e o acompanhamento das operações assíncronas.&lt;/p&gt;

&lt;p&gt;Na &lt;strong&gt;Parte 3&lt;/strong&gt;, abordaremos a implementação utilizando &lt;strong&gt;Terraform&lt;/strong&gt;, transformando a fundação da organização em Infrastructure as Code e discutindo uma questão importante: &lt;strong&gt;quem deve ser responsável pelo lifecycle da Landing Zone — Terraform ou Control Tower?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Também veremos como o recurso &lt;code&gt;aws_controltower_landing_zone&lt;/code&gt; do AWS Provider for Terraform permite administrar uma Landing Zone do Control Tower por Infrastructure as Code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/strategy-migration/aws-landing-zone.html" rel="noopener noreferrer"&gt;AWS Prescriptive Guidance — Set up a secure AWS landing zone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html" rel="noopener noreferrer"&gt;AWS Control Tower User Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/controltower/latest/userguide/how-control-tower-works.html" rel="noopener noreferrer"&gt;AWS Control Tower — How AWS Control Tower works&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/controltower/create-landing-zone.html" rel="noopener noreferrer"&gt;AWS CLI — &lt;code&gt;controltower create-landing-zone&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/controltower_landing_zone" rel="noopener noreferrer"&gt;Terraform AWS Provider — &lt;code&gt;aws_controltower_landing_zone&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ptbr</category>
      <category>aws</category>
      <category>architecture</category>
    </item>
    <item>
      <title>[pt-BR] Depurando um crash de use-after-free no meniOS</title>
      <dc:creator>Plínio Balduino</dc:creator>
      <pubDate>Tue, 14 Oct 2025 22:32:52 +0000</pubDate>
      <link>https://dev.to/pbalduino/depurando-um-crash-de-use-after-free-no-menios-2140</link>
      <guid>https://dev.to/pbalduino/depurando-um-crash-de-use-after-free-no-menios-2140</guid>
      <description>&lt;p&gt;Há uns dois anos, escrevi aqui que estava escrevendo um sistema operacional chamado meniOS, quase do zero. (&lt;a href="https://dev.to/pbalduino/criando-um-sistema-operacional-quase-do-zero-27m8"&gt;Leia aqui&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Novamente fiquei um bom tempo parado, com a vida e a correria engolindo nossos momentos de lazer, mas voltei a brincar com ele.&lt;/p&gt;

&lt;p&gt;A coisa avançou bastante nos últimos tempos, e atualmente é possível executar pequenos binários fora do kernel, na área chamada user space, onde rodam quase todos os softwares que usamos no dia a dia.&lt;/p&gt;

&lt;p&gt;Conforme o sistema vai crescendo, cada vez mais partes vão trabalhando juntas e dependendo umas das outras, e vai ficando cada vez mais difícil entender porque um erro acontece.&lt;/p&gt;

&lt;p&gt;Para ajudar a navegar entre vários e vários logs cheios de números hexadecimais que eu mesmo mandei imprimir mas não entendia muito bem o que significavam, criei esse pequeno guia, que mostra, passo a passo, como diagnosticar um crash provocado por acesso a memória já liberada (&lt;em&gt;use-after-free&lt;/em&gt;). O objetivo é destacar o processo e as ferramentas que uso no meniOS, como &lt;code&gt;nm&lt;/code&gt;, &lt;code&gt;objdump&lt;/code&gt; e um script em Python com &lt;code&gt;pyelftools&lt;/code&gt;, para transformar um endereço de falha em uma linha de código. Ao final, teremos um roteiro reaproveitável para incidentes parecidos.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Prepare o cenário
&lt;/h2&gt;

&lt;p&gt;O binário de exemplo é intencionalmente falho: ele libera um ponteiro e logo em seguida tenta escrever naquele endereço. Não por coincidência, essa é uma das principais causas de tela azul no Windows, ou seja lá que cor estejam usando hoje em dia.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"malloc"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dereferencing freed pointer...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Use-after-free: provoca crash&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value: %c&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compilar com símbolos de depuração deixa o código-fonte acessível na desmontagem e nas tabelas DWARF; esse formato armazena metadados de depuração no ELF, incluindo o mapeamento entre endereços de instruções, arquivos e números de linha, o que é essencial para relacionar endereços a trechos de código.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;-O0&lt;/span&gt; &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-Wextra&lt;/span&gt; use_after_free.c &lt;span class="nt"&gt;-o&lt;/span&gt; use_after_free
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O meniOS executa binários no formato ELF, sigla para Executable and Linkable Format. Esse contêiner descreve cabeçalhos, seções e tabelas necessárias para carregar o programa na memória, incluindo as tabelas de símbolos que &lt;code&gt;nm&lt;/code&gt; lê e as seções de código que &lt;code&gt;objdump&lt;/code&gt; desmonta. Como o ELF também embute as extensões de depuração DWARF geradas pelo compilador, conseguimos cruzar endereços de instruções com arquivos de origem e, a partir disso, chegar rapidamente à linha com defeito.&lt;/p&gt;

&lt;p&gt;Enquanto não há suporte a bibliotecas compartilhadas (&lt;code&gt;.so&lt;/code&gt;), cada aplicativo do meniOS é entregue como um executável ELF independente. Compilo esses binários na máquina host e copio o resultado para a mesma imagem de disco utilizada no boot do sistema, mantendo o fluxo de build simples e previsível.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Reproduza o crash e capture o endereço
&lt;/h2&gt;

&lt;p&gt;Executando o programa no meniOS, ou no ambiente host caso esteja testando localmente, o kernel interrompe o processo assim que detecta o acesso inválido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dereferencing freed pointer...
  User page fault at 0x0000555555555000 (present=yes write=yes), terminating pid=17
proc_exit: Process init/use_after_free exited with status 11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando o crash é coletado via console serial do meniOS, o log inclui ainda o contexto de sistema de chamadas. Logo antes da falha, a saída típica de &lt;code&gt;write(1, …)&lt;/code&gt; registra o ponto para o qual a execução retornaria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;syscall_dispatch: pid=17 number=1 rip=40112f cs=3b rsp=bfdfd0
syscall_dispatch: post-handler rip=401168 cs=3b rsp=bfdf10 rax=32
mosh: process terminated by signal 11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anote dois dados essenciais: &lt;code&gt;rip=0x401168&lt;/code&gt;, que aponta para a instrução que falhou, e o nome do binário (&lt;code&gt;use_after_free&lt;/code&gt;), porque é nele que vou procurar a origem.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Descubra o símbolo com &lt;code&gt;nm&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Comece localizando qual função cobre o endereço problemático. O &lt;code&gt;nm&lt;/code&gt; lista a tabela de símbolos do executável, indicando o intervalo de cada função.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nm &lt;span class="nt"&gt;-an&lt;/span&gt; use_after_free | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Saída típica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;00000000004010f0 t _start
0000000000401120 T main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;main&lt;/code&gt; começa em &lt;code&gt;0x401120&lt;/code&gt;. Como &lt;code&gt;0x401168&lt;/code&gt; ainda está próximo, é razoável assumir que a falha ocorreu dentro dessa função, mas é prudente confirmar.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Navegue no assembly com &lt;code&gt;objdump&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;objdump&lt;/code&gt; permite correlacionar instruções com o código-fonte. Use as opções &lt;code&gt;--source&lt;/code&gt; e &lt;code&gt;--line-numbers&lt;/code&gt; para misturar C e assembly; limite a saída a um trecho curto com &lt;code&gt;sed&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;objdump &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--no-show-raw-insn&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &lt;span class="nt"&gt;--line-numbers&lt;/span&gt; use_after_free &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'35,60p'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trecho relevante:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use_after_free.c:16
    *ptr = 'A';  // Use-after-free: provoca crash
  401164:  mov    -0x8(%rbp),%rax
  401168:  movb   $0x41,(%rax)          ; 0x41 == 'A'

use_after_free.c:17
    printf("Value: %c\n", *ptr);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso confirma visualmente: a instrução em &lt;code&gt;0x401168&lt;/code&gt; é exatamente a escrita com &lt;code&gt;'A'&lt;/code&gt;. Se o log apontar um endereço alguns bytes adiante, use o mesmo procedimento para encontrar a linha correspondente.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Resolver linha e arquivo com Python + &lt;code&gt;pyelftools&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;As tabelas DWARF do executável guardam, para cada unidade de compilação, a sequência de endereços e as respectivas linhas do código-fonte. Para automatizar o mapeamento de endereços, um script curto em Python consulta esse material. Esse procedimento economiza tempo quando coleto crashes em lote ou quando quero integrar a análise em pipelines de CI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;elftools.elf.elffile&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ELFFile&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;elf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ELFFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;dwarf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;elf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_dwarf_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cu&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dwarf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_CUs&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;lineprog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dwarf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;line_program_for_CU&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lineprog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_entries&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end_sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;file_entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lineprog&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file_entry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="n"&gt;comp_dir_attr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_top_DIE&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DW_AT_comp_dir&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;comp_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;comp_dir_attr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                        &lt;span class="n"&gt;comp_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comp_dir_attr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comp_dir&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;file_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dir_index&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                        &lt;span class="n"&gt;include_dirs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lineprog&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;include_directory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                            &lt;span class="n"&gt;comp_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;include_dirs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;file_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dir_index&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                        &lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;full_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;full_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;
                &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;file_entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lineprog&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;file_entry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="n"&gt;comp_dir_attr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_top_DIE&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DW_AT_comp_dir&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;comp_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comp_dir_attr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;comp_dir_attr&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
                &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comp_dir&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;file_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dir_index&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;include_dirs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lineprog&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;include_directory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                    &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;comp_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;include_dirs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;file_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dir_index&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="n"&gt;full_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;full_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Uso: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &amp;lt;ELF&amp;gt; &amp;lt;endereco_hex&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;raw_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Endereço não encontrado.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./resolve_addr.py use_after_free 0x401168
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Saída:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/path/para/use_after_free.c:16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integre o script ao seu fluxo de crash dumps no meniOS: basta salvar o endereço de &lt;code&gt;rip&lt;/code&gt; e, depois, usar a ferramenta para apontar diretamente para a linha culpada.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Confirme a correção
&lt;/h2&gt;

&lt;p&gt;Depois de identificar a origem, ajuste o código para evitar o uso após &lt;code&gt;free&lt;/code&gt;. Um fix simples é atrasar a chamada de &lt;code&gt;free&lt;/code&gt; ou zerar o ponteiro antes de qualquer acesso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dereferencing freed pointer...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value: %c&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recompile, execute e confirme que o crash desapareceu. Aproveite para rodar o binário antigo novamente e validar que seu processo de depuração continua funcionando.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dicas extras
&lt;/h2&gt;

&lt;p&gt;Garanta que o console serial do meniOS esteja ligado durante os testes. Como o sistema roda hoje em emuladores QEMU ou Bochs, redireciono a porta serial primária para &lt;code&gt;com1.log&lt;/code&gt; (ou &lt;code&gt;com1bochs.log&lt;/code&gt;, no caso do Bochs); esse console funciona como uma janela de logs do kernel, exibindo tudo o que o sistema imprime por &lt;code&gt;kprintf&lt;/code&gt;, incluindo o endereço de instrução, o PID e a syscall ativa no momento do crash; como cada serviço roda em um executável ELF independente, repita o procedimento com o binário correspondente na imagem do meniOS; se quiser detectar problemas dessa classe automaticamente em paralelo no host, compile versões instrumentadas com AddressSanitizer e execute-as no Linux ou no macOS, onde o runtime já está disponível.&lt;/p&gt;

&lt;p&gt;Seguindo esses passos você transforma um crash misterioso em uma linha específica do código-fonte.&lt;/p&gt;

&lt;p&gt;Achei importante documentar isso aqui para, caso eu pare novamente de brincar com isso, ao voltar eu consiga me virar com certa rapidez. E também para que você, leitor(a) se sinta convidado(a) a participar desse desenvolvimento.&lt;/p&gt;

</description>
      <category>operatingsystem</category>
      <category>osdev</category>
      <category>ptbr</category>
      <category>opensource</category>
    </item>
    <item>
      <title>[pt-BR] Criando um sistema operacional (quase) do zero</title>
      <dc:creator>Plínio Balduino</dc:creator>
      <pubDate>Wed, 20 Sep 2023 17:16:53 +0000</pubDate>
      <link>https://dev.to/pbalduino/criando-um-sistema-operacional-quase-do-zero-27m8</link>
      <guid>https://dev.to/pbalduino/criando-um-sistema-operacional-quase-do-zero-27m8</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Há uns três anos, sem nenhum bom motivo, eu resolvi que iria escrever um sistema operacional do zero. Comecei com o bootloader, depois parti para o kernel e fiquei empacado. Bateu o desânimo, a falta de tempo, e o projeto ficou lá, abandonado.&lt;/p&gt;

&lt;p&gt;Recentemente, novamente sem qualquer bom motivo, resolvi resgatar esse projeto e usar as lições aprendidas no processo e nesses anos afastado.&lt;/p&gt;

&lt;p&gt;Meu plano ao escrever aqui é compartilhar os aprendizados, em Português, e explicar passo a passo o que é cada uma das partes envolvidas que fazem o seu computador funcionar e permitem que você esteja lendo este texto agora.&lt;/p&gt;

&lt;p&gt;Não garanto que eu vá chegar ao final, já que desenvolver um sistema operacional é um trabalho gigantesco, mas já será uma grande vitória se isso aqui servir de material de pesquisa para os(as) próximos desenvolvedores(as) que se aventurarem nessa tarefa.&lt;/p&gt;

&lt;p&gt;Espero também cobrir uma lacuna nos materiais online, que geralmente estão obsoletos ou incorretos ou mal explicados ou geralmente as três situações ao mesmo tempo.&lt;/p&gt;

&lt;p&gt;A ideia também é ir adicionando aqui os links para os próximos passos, então salve este post aqui nos seus favoritos para facilitar a leitura.&lt;/p&gt;

</description>
      <category>operatingsystem</category>
      <category>opensource</category>
      <category>ptbr</category>
      <category>osdev</category>
    </item>
    <item>
      <title>[pt-BR] Usando o shell além do básico</title>
      <dc:creator>Plínio Balduino</dc:creator>
      <pubDate>Wed, 01 Jun 2022 01:10:37 +0000</pubDate>
      <link>https://dev.to/pbalduino/pt-br-usando-o-shell-alem-do-basico-1adc</link>
      <guid>https://dev.to/pbalduino/pt-br-usando-o-shell-alem-do-basico-1adc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Imagem: &lt;a href="https://www.deviantart.com/shiiftyshift/art/Hackerman-643435212" rel="noopener noreferrer"&gt;Hackerman&lt;/a&gt;, de shiiftyshift.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tudo bem, talvez não sejam realmente indispensáveis, mas aprendê-las vai fazer com que você se sinta a própria Hackerperson.&lt;/p&gt;

&lt;p&gt;Quando você lida com um sistema operacional compatível com POSIX (alguma variação de UNIX, BSD, Linux, MacOS X, etc), internamente existem dois canais principais para entrada e saída de dados: o &lt;em&gt;stdin&lt;/em&gt; e o &lt;em&gt;stdout&lt;/em&gt;. Existem mais, mas vamos focar nesses dois.&lt;/p&gt;

&lt;p&gt;Um executável pode ler dados de &lt;em&gt;stdin&lt;/em&gt; e gravar dados em &lt;em&gt;stdout&lt;/em&gt;. Um exemplo disso acontecendo é quando o programa lê dados do teclado e grava, ou exibe, na tela.&lt;/p&gt;

&lt;p&gt;O pulo do gato acontece quando você conecta o &lt;em&gt;stdout&lt;/em&gt; de um programa com o &lt;em&gt;stdin&lt;/em&gt; de outro usando um recurso chamado pipe (cano ou encanamento). O que um programa exibiria na tela passa a ser enviado para o &lt;em&gt;stdin&lt;/em&gt; do programa seguinte, que processa aquelas entradas e devolve para o &lt;em&gt;stdout&lt;/em&gt;. Você pode conectar inúmeros programas uns nos outros através do &lt;em&gt;pipe&lt;/em&gt;, fazendo com que cada pecinha resolva uma parte do problema, transformado o dado e passando para o próximo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fst4ymex0c304uykwumv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fst4ymex0c304uykwumv3.png" alt="O fundamento mais básico da computação" width="546" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para nosso exemplo, vamos baixar um arquivo com praticamente todas as palavras da Língua Portuguesa &lt;a href="https://github.com/pythonprobr/palavras/raw/master/palavras.txt" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Executando &lt;code&gt;cat palavras.txt&lt;/code&gt; serão exibidas na tela as mais de trezentas e vinte mil palavras do arquivo. &lt;code&gt;cat&lt;/code&gt; lê o arquivo e joga seu conteúdo para &lt;em&gt;stdout&lt;/em&gt;, que neste caso é a própria tela.&lt;/p&gt;

&lt;p&gt;Vamos usar o pipe para exibir o arquivo em ordem alfabética invertida usando &lt;code&gt;sort&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;palavras.txt | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, com o caracter de &lt;em&gt;pipe&lt;/em&gt;, o &lt;code&gt;|&lt;/code&gt;, direcionamos o conteúdo da saída padrão de &lt;code&gt;cat&lt;/code&gt; para a entrada padrão de &lt;code&gt;sort&lt;/code&gt;, exibindo assim o arquivo em ordem alfabética invertida.&lt;/p&gt;

&lt;p&gt;Pode pode paginar a visualização do arquivo usando &lt;code&gt;less&lt;/code&gt; e outro pipe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;palavras.txt | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; | less
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pressione espaço para ir para a próxima página, ou Q para sair.&lt;/p&gt;

&lt;p&gt;Vamos exibir apenas as palavras do dicionário que contenham o texto &lt;em&gt;pli&lt;/em&gt;. Para isso usamos &lt;code&gt;grep&lt;/code&gt;, que retorna apenas as entradas que contenham o texto informado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;palavras.txt | &lt;span class="nb"&gt;grep &lt;/span&gt;pli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Sim, você pode usar &lt;code&gt;grep palavras.txt pli&lt;/code&gt; também, mas a ideia aqui é encadear vários &lt;em&gt;pipes&lt;/em&gt; para fins didáticos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E vamos usar &lt;code&gt;sed&lt;/code&gt; para deixar a primeira letra de cada palavra em maiúscula. &lt;code&gt;sed&lt;/code&gt; aplica uma expressão regular na entrada e retorna o resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;palavras.txt | &lt;span class="nb"&gt;grep &lt;/span&gt;pli | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/[a-z]/\U&amp;amp;/'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para sabermos quantas palavras existem em nossa seleção, usamos &lt;code&gt;wc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;palavras.txt | &lt;span class="nb"&gt;grep &lt;/span&gt;pli | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 382
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, em outro exemplo, vamos listar os arquivos em um diretório qualquer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjye4qshy4idt0f495jp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjye4qshy4idt0f495jp.png" alt="ls -l" width="800" height="283"&gt;&lt;/a&gt;&lt;br&gt;
Perceba que os dados vieram exibidos em colunas. Para pegar o conteúdo de apenas uma das colunas, usamos &lt;code&gt;awk&lt;/code&gt;, que usa uma linguagem própria com o mesmo nome. Os nomes dos arquivos estão na nona coluna. Então, para selecioná-la, passamos essa informação para o &lt;code&gt;awk&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $9}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvq4zsk3zr5j08wp9njyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvq4zsk3zr5j08wp9njyh.png" alt="ls -l | awk '{print $9}'" width="331" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sim, você poderia ter usado &lt;code&gt;file&lt;/code&gt; para isso, mas estou claramente inventando situações para poder demonstrar as ferramentas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por fim, vamos usar &lt;code&gt;xargs&lt;/code&gt;, que pega os valores que chegam pelo &lt;em&gt;stdin&lt;/em&gt; e passam como parâmetros para o comando seguinte. Por exemplo, vamos listar os arquivos e os conteúdos dos diretórios usando &lt;code&gt;ls&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $9}'&lt;/span&gt; | xargs &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzj05wyexcc4wpx40cbl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzj05wyexcc4wpx40cbl1.png" alt="ls -l | awk '{print $9}' | xargs ls" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>shell</category>
      <category>intermediate</category>
      <category>ptbr</category>
      <category>quick</category>
    </item>
    <item>
      <title>[pt-BR] Como aprendi (e continuo aprendendo) Inglês</title>
      <dc:creator>Plínio Balduino</dc:creator>
      <pubDate>Wed, 18 May 2022 16:35:26 +0000</pubDate>
      <link>https://dev.to/pbalduino/pt-br-como-aprendi-e-continuo-aprendendo-ingles-13j0</link>
      <guid>https://dev.to/pbalduino/pt-br-como-aprendi-e-continuo-aprendendo-ingles-13j0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este texto foi publicado originalmente em 2017 no meu antigo site no Medium. Tenho uma vaga lembrança dele ter sido publicado em outro lugar antes disso, mas o importante aqui é de que se trata de um texto antigo e a evolução não parou de lá para cá.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Antes de mais nada, é válido deixar claro que estou compartilhando aqui minha experiência pessoal. O que funcionou comigo pode não funcionar com você, assim como minha realidade e minhas experiências podem parecer totalmente estranhas para você. Filtre o que você achar importante e relevante, ignore o resto e segue a vida.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Assim como emagrecer, acordar cedo ou começar a fazer exercícios, aprender Inglês é algo que, para a maioria das pessoas, acaba sempre ficando em segundo ou terceiro plano.&lt;/p&gt;

&lt;p&gt;No meu caso não foi nada diferente. Desde muito novo eu tive contato com materiais em Inglês, mas sempre tive para mim que eu sabia a linguagem. Eu estava no numeroso grupo que coloca “Inglês Intermediário” no currículo.&lt;/p&gt;

&lt;p&gt;Aos vinte eu comecei um curso numa escola que prometia ‘Inglês em 100 horas’. O método deles, ao menos para mim, funcionou muito bem.&lt;/p&gt;

&lt;p&gt;Era uma escola onde os professores não conversavam em Português com os alunos. Mesmo com todo o cuidado e toda a didática, era uma situação que te forçava a participar, entender e falar em Inglês. Infelizmente, se você é do tipo tímido ou introvertido, são grandes as chances de evitar interagir num curso desses. Nesse caso eu recomendo outra metodologia ou tentar lutar contra o próprio bloqueio. Não tenho a resposta.&lt;/p&gt;

&lt;p&gt;No meu caso, que era tímido e introvertido, ajudou demais ter feito o curso com um amigo que não parava de falar. Eu me sentia à vontade para conversar com ele em Inglês e a coisa fluiu bem.&lt;/p&gt;

&lt;p&gt;Por trabalhar com TI, as principais fontes de informação sempre estiveram em Inglês, o que me deixou habituado a ler, mas não a escrever ou conversar. Livros técnicos traduzidos costumam ser péssimos. Os melhores conseguem ser apenas horríveis.&lt;/p&gt;

&lt;p&gt;O fato foi que, ao menos por um tempo, esse curso conseguiu melhorar muito a minha conversação e minha compreensão de texto, mas eu ainda não era fluente no idioma.&lt;/p&gt;

&lt;p&gt;Eis que, após três meses de curso, sofri um acidente voltando para casa e deixei os estudos de lado por anos.&lt;/p&gt;

&lt;p&gt;Como eu disse no começo do texto, aprender um idioma é como emagrecer ou começar fazer exercícios. Para a maioria das pessoas esse hábito só vem depois que algo ruim acontece. Um infarto ou, no meu caso, uma vaga para ganhar quatro vezes mais.&lt;/p&gt;

&lt;p&gt;Eu trabalhava numa empresa pequena, realmente pequena, onde havia mais um programador além de mim. O faturamento era pouco, o salário era baixo e minha ambição era nula.&lt;/p&gt;

&lt;p&gt;Então me aparece essa oportunidade para trabalhar em uma multinacional suíça e ganhar quatro vezes mais do que eu ganhava:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Você sabe X?"&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Sei&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"E Y?"&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Sei&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"E o Inglês?"&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Precisa ser fluente?&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"Não existe outro. Ou você sabe, ou não sabe."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;E a pré-entrevista acabou ali mesmo.&lt;/p&gt;

&lt;p&gt;Fiquei olhando para o telefone. Minha incipiente carreira tinha acabado de sofrer um infarto.&lt;/p&gt;

&lt;p&gt;Eu tinha duas opções: reclamar de como a vida era injusta e de como empresas pediam Inglês avançado ou fluente sem a menor necessidade, ou eu poderia aproveitar o tranco para me mexer e sair do marasmo. Como já me disseram, &lt;em&gt;"até um pé na bunda te empurra para frente"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Pensando bem, essa oportunidade já tinha sido perdida mesmo. Uma próxima eu não deixaria escapar. Se for para cair, que seja para cima.&lt;/p&gt;

&lt;p&gt;Saí em busca de uma escola de idiomas para voltar a estudar. As melhores estavam bem além do meu orçamento. Sobravam poucas opções. Todas elas franquias de bairro com reputação bem ruim.&lt;/p&gt;

&lt;p&gt;Fiz uma entrevista com a coordenadora do curso. Eram sete módulos de seis meses cada, se não me falha a memória, e entrei no quarto. Bom, pelo menos eu estaria convivendo com pessoas que já estavam estudando continuamente há um ano e meio.&lt;/p&gt;

&lt;p&gt;No primeiro dia de aula chamei a professora de canto e expliquei o que tinha acontecido. Pedi a ela que, se possível, falasse comigo apenas em Inglês e eu que me virasse para entender e responder. Ela ficou surpresa e feliz com o pedido e já me respondeu em Inglês mesmo, concordando.&lt;/p&gt;

&lt;p&gt;Para minha surpresa, os demais alunos pareciam estar ali apenas para cumprir horário. Conversavam entre si em Português e tinham dificuldades de leitura. Me perguntei até que ponto o curso era realmente ruim ou se eram os alunos que nem ao menos se esforçavam.&lt;/p&gt;

&lt;p&gt;Um amigo me indicou podcasts para ouvir no ônibus, em Inglês. English as a Second Language, por exemplo, começava com um texto sendo lido bem devagar, em seguida havia uma explicação sobre as palavras chaves ou termos novos e então, o texto ou o diálogo ocorria em velocidade normal.&lt;/p&gt;

&lt;p&gt;Ao mesmo tempo, no curso, a professora só conversava comigo em Inglês e, logo, alguns alunos resolveram entrar na brincadeira.&lt;/p&gt;

&lt;p&gt;Nesse meio tempo, algo estranho começou a acontecer: eu saia do curso pensando em Inglês e ia assim até chegar em casa. Para mim era algo totalmente estranho pensar em Inglês, sem precisar antes formular a ideia em Português e, só então, traduzir. Era como se tivesse descoberto uma chavinha no cérebro que trocava o idioma. Uma tecla SAP.&lt;/p&gt;

&lt;p&gt;Esse amigo que recomendou os podcasts, que inclusive foi o mesmo que me barrou logo na pré-entrevista, comentou que uma forma de falar melhor era ficar bêbado.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Comigo funcionou”&lt;/em&gt;, ele disse.&lt;/p&gt;

&lt;p&gt;Eu mal conseguia falar corretamente quando estava sóbrio e também não bebia. Não fazia o menor sentido.&lt;/p&gt;

&lt;p&gt;Meses após ter perdido aquela oportunidade, surgiu outra na mesma empresa. O salário seria menor, mas ainda assim era muito mais do que eu recebia na época. Eu era Roberto Baggio novamente na marca do pênalti.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Você sabe X?”&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Sei&lt;/em&gt;&lt;br&gt;
&lt;em&gt;“E Y?”&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Sei&lt;/em&gt;&lt;br&gt;
&lt;em&gt;“E o Inglês?”&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Fluente&lt;/em&gt;&lt;br&gt;
&lt;em&gt;“Tem certeza? Encara uma entrevista toda em Inglês?”&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Opa. Vamos lá.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vamos ser honestos: eu não era fluente. Acho bem pouco provável que alguém passe do ponto do &lt;em&gt;"Inglês Intermediário"&lt;/em&gt;, do &lt;em&gt;"sei mais ou menos"&lt;/em&gt; para a fluência em pouco mais de seis meses. Mas o raio não cairia três vezes no mesmo lugar e eu estava me preparando justamente para uma situação assim. Tinha que dar certo. Se eu não acreditasse em mim, ninguém mais acreditaria.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Entenda que o objetivo desse texto não é ser motivacional nem vender uma solução milagrosa para pessoas desesperadas. Estou narrando de forma desnecessariamente honesta e sincera o que eu passei e como eu reagi para que você perceba que tudo é uma questão de tirar a bunda da cadeira e de mudar de postura. Seja por um infarto, seja por um tombo na carreira.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fiz um pequeno teste prático, recebi algum feedback do avaliador e fui chamado para a entrevista.&lt;/p&gt;

&lt;p&gt;Eis que eu estava na recepção da empresa, tremendo, pálido, mal conseguindo falar Português. Havia uma cultura de sigilo na empresa em que mesmo o principal negócio dela não tinha ficado claro para mim até então.&lt;/p&gt;

&lt;p&gt;Simplesmente não dava para ficar tranquilo. Tinha tudo para dar errado. O estádio em silêncio, a bola na marca do pênalti, o goleiro olhando para mim como se soubesse que eu ia errar.&lt;/p&gt;

&lt;p&gt;Entro na sala de reunião. Um gerente suíço que não falava Português e um engenheiro que falava Inglês tão depressa quanto um americano que tomou muito café.&lt;/p&gt;

&lt;p&gt;Começam a me contar sobre a empresa, sobre o projeto e sobre o que era esperado que eu fizesse lá. Em Inglês. Minha cabeça funcionando a cento e dez por cento com medo de perder uma só palavra e botar tudo a perder.&lt;/p&gt;

&lt;p&gt;Então preciso contar de forma resumida o que eu tinha feito até então, em que projetos já tinha trabalhado e qual era a minha experiência.&lt;/p&gt;

&lt;p&gt;Não teve nada de mágico: gaguejei, tropecei, troquei palavras. Minha pronúncia foi horrível e, em vários momentos, eu precisei repetir a frase de uma forma diferente para que todos entendessem.&lt;/p&gt;

&lt;p&gt;O gerente então fez uma pergunta sobre part numbers que fugiu totalmente do escopo da conversa. Olhei em volta, perdido. Vi um quadro branco.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Can I use the whiteboard?"&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Sure, please.&lt;/em&gt;_&lt;/p&gt;

&lt;p&gt;Para minha sorte, eu já havia trabalhado com um sistema que controlava listas de partes de produtos industrializados. É, como o nome diz, uma lista contendo todas as peças, quantidades e códigos (os tais &lt;em&gt;part numbers&lt;/em&gt;) que formam um produto pronto.&lt;/p&gt;

&lt;p&gt;Então eu fui ao quadro branco, fiz diagramas, setas e rabiscos explicando, em Inglês, minha ideia sobre o que ele havia perguntado. Levantei cenários alternativos e situações que poderiam ter uma abordagem diferente. De repente, explicando algo que eu conhecia bem, eu não estava mais nervoso. O Inglês, mesmo tosco e manco, era apenas um detalhe. Uma ferramenta.&lt;/p&gt;

&lt;p&gt;O gerente gostou. O engenheiro balançou a cabeça aprovando.&lt;/p&gt;

&lt;p&gt;Passei.&lt;/p&gt;

&lt;p&gt;Gol.&lt;/p&gt;

&lt;p&gt;No primeiro mês de empresa fui enviado para um treinamento de um mês na Suíça.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz81t1f9bv2l9mishdb35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz81t1f9bv2l9mishdb35.png" alt="Pôr do Sol em Lausanne, Suíça. 2008." width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Me enrolei para falar com os comissários de bordo. Me enrolei na imigração. Me enrolei para comprar pão. Me enrolei para entender que diabos o engenheiro que estava dando o treinamento estava falando. Eu esqueci inclusive as palavras para comprar um barbeador e um sabonete.&lt;/p&gt;

&lt;p&gt;Na primeira semana lá fui chamado pelos outros colegas para conhecer uma casa noturna da cidade. "Tem música lá, é legal". Fomos.&lt;/p&gt;

&lt;p&gt;"E aí, você bebe o que?"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Não bebo
"Nada?"&lt;/li&gt;
&lt;li&gt;Nada alcoolico.
"Certo."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E pediu vodka com Virgin Cola para o bartender. Tomei meio a contragosto, mas pensei comigo que já estava ali, que tinha conseguido. Por que não relaxar e comemorar um pouco?&lt;/p&gt;

&lt;p&gt;Não sei quantas eu tomei, lembro que conversamos a noite toda sobre a vida na Suíça, na França, no Brasil, sobre música e, em algum momento eu estava de volta ao hotel. Falando Inglês, pensando Inglês, alcoolizado demais para conseguir desligar a chavinha e voltar a pensar e falar em Português. A recepcionista me perguntou algo, eu respondi em Francês. Tosco, quebrado e errado, mas era Francês.&lt;/p&gt;

&lt;p&gt;Descobri. O que me fez falar mais e melhor não foi o álcool, mas a completa perda de inibição. Exatamente como quando fiz o curso de com um amigo na sala. Dane-se que estou falando errado. As pessoas estão entendendo. O errado eu corrijo com o tempo e com a prática.&lt;/p&gt;

&lt;p&gt;Aquele camarada sabia das coisas.&lt;/p&gt;

&lt;p&gt;De volta ao Brasil, alguém no escritório encontrou um professor particular nativo que aceitou dar aula para três alunos por um preço pagável.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Vale lembrar que, também nessa época, descobri o Duolingo. Apesar das frases estranhas sobre tartarugas que falam e vacas, é gratuito e ajuda muito a melhorar o vocabulário.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Para mim esta foi a forma mais efetiva de aprender Inglês sem precisar sair do país. Se você tiver dinheiro para investir, recomendo de verdade. Quatro aulas por mês custavam uma vez e meia a mensalidade de um curso franqueado de bairro.&lt;/p&gt;

&lt;p&gt;Dois anos atrás apareceu uma oportunidade de trabalhar fora. As coisas nessa empresa já não estavam boas, as chances de haver uma demissão em massa eram reais e eu já não estava mais fazendo as aulas particulares. Fiz o processo remotamente e a entrevista por Skype.&lt;/p&gt;

&lt;p&gt;Reprovado.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Gostei da conversa, você tem experiência, conhece as ferramentas, mas não senti firmeza no seu Inglês. Estude mais, pratique mais e, se você ainda tiver interesse, voltaremos a nos novamente falar em um ano".&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Mais um chute na bunda. Hora de me mexer.&lt;/p&gt;

&lt;p&gt;Voltamos a nos falar um ano depois. Dessa vez fui reprovado sem ao menos ir para a entrevista por Skype. Não tem problema, eu estava fazendo duas entrevistas por semana, toda semana, em Inglês, por Skype e telefone. Estava treinando durante o jogo. Era o que dava pra fazer.&lt;/p&gt;

&lt;p&gt;Atualmente eu consigo conversar tranquilamente em Inglês, viajei para o exterior algumas vezes e consegui me virar bem conversando. Sites como o Linguee me ajudam demais a escrever, podcasts e vídeos em Inglês me ajudam a manter o cérebro acostumado com o idioma. O Duolingo ainda me acompanha, mas tem servido bem para aprender Holandês, Alemão ou Sueco.&lt;/p&gt;

&lt;p&gt;Uma vez que você consegue fluência em um idioma, o esforço para conseguir fluência em outro é relativamente menor. Seu cérebro já passou por aquilo antes e consegue repetir o processo com menor esforço.&lt;/p&gt;

&lt;p&gt;Meus próximos passo são conseguir um trabalho no exterior, conseguir uma boa pontuação no IELTS e, quem sabe, estudar lá fora. Por isso eu treino, treino, estudo e estudo. Sem um objetivo, um foco, uma necessidade real, dificilmente eu teria conseguido me mexer e me esforçar.&lt;/p&gt;

&lt;p&gt;Assim como emagrecer, acordar cedo ou começar a fazer exercícios, a maioria das pessoas, incluindo eu, só se mexe quando a água bate forte na bunda.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Update em 18/05/2022: Depois desse texto eu passei num processo seletivo para uma empresa sueca, e morei em Estocolmo por dois anos, me virando na maior parte do tempo em Inglês. Nesse meio tempo fui aprovado também para uma vaga de Líder Técnico no Booking, em Amsterdam, com um processo também totalmente em Inglês, mas acabei recusando.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ptbr</category>
      <category>career</category>
    </item>
    <item>
      <title>[pt-BR] Consumindo conteúdo HTTP no Terraform</title>
      <dc:creator>Plínio Balduino</dc:creator>
      <pubDate>Mon, 16 May 2022 16:27:09 +0000</pubDate>
      <link>https://dev.to/pbalduino/consumindo-conteudo-http-no-terraform-196e</link>
      <guid>https://dev.to/pbalduino/consumindo-conteudo-http-no-terraform-196e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Parte de uma série de posts curtos com conhecimentos que podem ser úteis no dia a dia e quero compartilhar. Muitas vezes eles exigem um conhecimento prévio da ferramenta ou da linguagem.&lt;/p&gt;

&lt;p&gt;Esses textos curtos são publicados sob a tag #quick.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Existem situações em que você precisa armazenar o conteúdo de um endpoint ou de um arquivo que está online, e esse conteúdo não será modificado dentro daquele contexto.&lt;/p&gt;

&lt;p&gt;Por exemplo, trabalhei num projeto em que a geração de tokens JWT era feita pelo AWS Cognito. Para validar o token recebido pelo client e garantir que ele era legítimo, permitindo a liberação do acesso à API, é necessário verificar se o token foi gerado com a mesma chave do Cognito.&lt;/p&gt;

&lt;p&gt;Para isso, todo User Pool do Cognito gera um documento público que pode ser consumido pelo seu código. Esse documento fica em &lt;code&gt;https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Como o conteúdo desse documento nunca será alterado, é um desperdício fazer uma requisição HTTP para esse endereço toda vez que precisarmos validar um token. Como a validação precisa ser rápida e, no contexto de um recurso serverless, somos cobrados pelos tempo de uso, esse acesso extra causa um aumento desnecessário de custos.&lt;/p&gt;

&lt;p&gt;Para resolver isso, a requisição HTTP é feita uma única vez, durante o build da aplicação, e esse valor é passado para o código como uma variável de ambiente.&lt;/p&gt;

&lt;p&gt;Usando Terraform, bastou fazer assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;
&lt;span class="c1"&gt;# Aqui criamos o User Pool onde serão armazenadas &lt;/span&gt;
&lt;span class="c1"&gt;# as credenciais dos usuários&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_cognito_user_pool"&lt;/span&gt; &lt;span class="s2"&gt;"exemplo"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"exemplo"&lt;/span&gt;

  &lt;span class="c1"&gt;# um monte de configurações&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Aqui armazenamos os dados da região AWS atual&lt;/span&gt;
&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"aws_region"&lt;/span&gt; &lt;span class="s2"&gt;"current"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;# E aqui fazemos a requisição HTTP, que terá os &lt;/span&gt;
&lt;span class="c1"&gt;# parâmetros automaticamente atualizados se você&lt;/span&gt;
&lt;span class="c1"&gt;# mudar de região ou recriar seu User Pool&lt;/span&gt;
&lt;span class="k"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"http"&lt;/span&gt; &lt;span class="s2"&gt;"cognito_jwks"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://cognito-idp.&lt;/span&gt;&lt;span class="k"&gt;${data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_region&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.amazonaws.com/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;aws_cognito_user_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exemplo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.well-known/jwks.json"&lt;/span&gt;

  &lt;span class="nx"&gt;request_headers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Accept&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Finalmente, exportamos o conteúdo da requisição &lt;/span&gt;
&lt;span class="c1"&gt;# para que seja usada em outros módulos do seu projeto&lt;/span&gt;
&lt;span class="k"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"cognito_jwks"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cognito_jwks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E, no módulo onde você definiu a Lambda, você faz assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="c1"&gt;# essa variável terá um valor atribuído&lt;/span&gt;
&lt;span class="k"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"cognito_jwks"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_lambda_function"&lt;/span&gt; &lt;span class="s2"&gt;"exemplo"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;variables&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;COGNITO_JWKS&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cognito_jwks&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso funciona com qualquer outro recurso que você criar, não precisa ser necessariamente uma Lambda. COGNITO_JWKS contém um texto e você pode usá-lo da maneira que for melhor para o seu caso.&lt;/p&gt;

&lt;p&gt;Ao gerar a Lambda, o conteúdo do arquivo estará disponível como uma variável de ambiente, podendo ser acessado no código com &lt;code&gt;process.env.COGNITO_JWKS&lt;/code&gt;, caso você esteja usando JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixvngb1n3cjxf4datmg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixvngb1n3cjxf4datmg5.png" alt="Variável de ambiente da AWS Lambda" width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>quick</category>
      <category>intermediate</category>
      <category>terraform</category>
      <category>ptbr</category>
    </item>
    <item>
      <title>[pt-BR] Convertendo callbacks em promises em JavaScript</title>
      <dc:creator>Plínio Balduino</dc:creator>
      <pubDate>Mon, 16 May 2022 15:39:33 +0000</pubDate>
      <link>https://dev.to/pbalduino/convertendo-callbacks-em-promises-em-javascript-1egi</link>
      <guid>https://dev.to/pbalduino/convertendo-callbacks-em-promises-em-javascript-1egi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Primeiro de uma série de posts curtos com conhecimentos que podem ser úteis no dia a dia e quero compartilhar. Muitas vezes eles exigem um conhecimento prévio da ferramenta ou da linguagem.&lt;/p&gt;

&lt;p&gt;Esses textos curtos serão publicados sob a tag &lt;a href="https://dev.to/t/quick"&gt;#quick&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Existem situações em que você precisa fazer com que um código que foi pensado para ser executado assincronamente seja executado de forma síncrona. Ao usar &lt;em&gt;promises&lt;/em&gt;, você faz isso com o uso da palavra chave &lt;code&gt;await&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;algoAssincrono&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;succeeded&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Uhu!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;failed&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Deu ruim&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A execução do código vai aguardar até que a &lt;em&gt;promise&lt;/em&gt; seja finalizada para só então prosseguir.&lt;/p&gt;

&lt;p&gt;Quando você está escrevendo um código que exige um comportamento síncrono, como uma &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; ou o equivalente de qualquer outro fornecedor de &lt;em&gt;Cloud&lt;/em&gt;, você precisa garantir que todos os processos terminaram de ser executados antes do retorno da função:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;processoAssincrono&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;failure&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;processoAssincrono&lt;/code&gt; trata o evento recebido pela Lambda e, caso esteja tudo certo, retorna um status HTTP 200 e um conteúdo que será consumido pelo client, ou um status HTTP 400 caso não esteja tudo certo, com o motivo pelo qual a requisição falhou.&lt;/p&gt;

&lt;p&gt;O nosso exemplo &lt;code&gt;processoAssincrono&lt;/code&gt; foi pensado para ser assíncrono. Talvez ele consulte um banco de dados, uma API, ou qualquer recurso que poderia causar o bloqueio do &lt;em&gt;event loop&lt;/em&gt;, então essa decisão faz todo o sentido, mas dentro de uma Lambda nós precisamos que o processo seja finalizado para só então retornarmos um valor. Com o uso de &lt;code&gt;await&lt;/code&gt;, só retornamos um valor depois que a &lt;em&gt;promise&lt;/em&gt; terminar sua execução, garantindo que a execução seja síncrona.&lt;/p&gt;

&lt;p&gt;Quando você usa um código feito com &lt;em&gt;callbacks&lt;/em&gt;, não existe essa possibilidade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;assincronoComCallbacks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;succeeded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Funcionou&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; 
  &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Deu erro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para resolver isso, podemos criar uma &lt;em&gt;promise&lt;/em&gt; que só segue em frente quando os callbacks forem executados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;fulfill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;assincronoComCallbacks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;succeeded&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fulfill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;succeeded&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;failed&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;succeeded&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Uhu!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;failed&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Deu ruim&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função com &lt;em&gt;callbacks&lt;/em&gt; continua sendo assíncrona, mas estará encapsulada numa &lt;em&gt;promise&lt;/em&gt;, permitindo assim o uso de &lt;code&gt;await&lt;/code&gt;, tornando o processo seja executado como se fosse síncrono.&lt;/p&gt;

</description>
      <category>quick</category>
      <category>intermediate</category>
      <category>javascript</category>
      <category>ptbr</category>
    </item>
  </channel>
</rss>
