<?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.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] 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>
