<?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: João Victor Ignacio</title>
    <description>The latest articles on DEV Community by João Victor Ignacio (@ignaciojvig).</description>
    <link>https://dev.to/ignaciojvig</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%2F585718%2F316e261f-27e0-449b-8f1d-7e3aad93c802.jpeg</url>
      <title>DEV Community: João Victor Ignacio</title>
      <link>https://dev.to/ignaciojvig</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ignaciojvig"/>
    <language>en</language>
    <item>
      <title>Analisando alocações de memória em Rust utilizando GNU Debugger</title>
      <dc:creator>João Victor Ignacio</dc:creator>
      <pubDate>Tue, 30 Mar 2021 00:36:15 +0000</pubDate>
      <link>https://dev.to/ignaciojvig/analisando-alocacoes-de-memoria-em-rust-utilizando-gnu-debugger-34kb</link>
      <guid>https://dev.to/ignaciojvig/analisando-alocacoes-de-memoria-em-rust-utilizando-gnu-debugger-34kb</guid>
      <description>&lt;p&gt;Olá pessoal, como vão vocês?&lt;/p&gt;

&lt;p&gt;Neste artigo, vou mostrar pra vocês um exemplo de como podemos analisar as alocações de memória que são feitas por baixo dos panos em um programa em &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt;. Para conseguirmos analisar essas alocações, vamos utilizar de ferramenta o &lt;a href="https://www.gnu.org/software/gdb/" rel="noopener noreferrer"&gt;GNU Debugger&lt;/a&gt;. Portanto, para seguir adiante, certifiquem-se de que &lt;strong&gt;tanto o Rust quanto o GNU Debugger estejam ambos devidamente instalados&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Para darmos início, é necessário antes abordarmos &lt;strong&gt;dois&lt;/strong&gt; conceitos que são fundamentais para as análises que vamos fazer em diante- e mais do que isso, fundamentais para uma escrita de um código minimamente otimizado:  a &lt;strong&gt;Stack&lt;/strong&gt; e o &lt;strong&gt;Heap&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;&lt;em&gt;Stack&lt;/em&gt;&lt;/strong&gt; é uma região especial da memória de processamento que armazena as variáveis criadas por cada função. A memória necessária para realizar esse armazenamento, para cada função, é chamado de &lt;em&gt;stack frame&lt;/em&gt;. Para cada função chamada, um novo &lt;em&gt;stack frame&lt;/em&gt; específico a ela é alocado no topo da nossa &lt;strong&gt;Stack&lt;/strong&gt;, e a função pode acessar apenas a sua própria &lt;em&gt;stack frame&lt;/em&gt;. Este comportamento é justamente o que define o escopo das funções. Ao trabalharmos com a &lt;strong&gt;Stack&lt;/strong&gt;, o tamanho de cada variável deve ser específicado em &lt;strong&gt;tempo de compilação&lt;/strong&gt;, ou seja, se precisarmos por exemplo trabalhar com um &lt;strong&gt;array&lt;/strong&gt;, utilizando a &lt;strong&gt;Stack&lt;/strong&gt;, este &lt;strong&gt;array&lt;/strong&gt; deve possuir um tamanho exato de quantos elementos vai comportar. Quanto a execução de um programa termina de passar por uma função o &lt;strong&gt;stack frame&lt;/strong&gt; dela é liberado, ou seja, não precisamos nos preocupar em &lt;strong&gt;desalocar manualmente&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Para termos um relance um pouco mais objetivo de como o &lt;strong&gt;Stack&lt;/strong&gt; se comporta, vejamos o exemplo abaixo. Ainda não utilizaremos o GNU Debugger, deixemos ele para o nosso exemplo mais completo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main() {
  let a = 2;
  stack_only(a);
}

fn stack_only(_b: i32) {
  let _c = 3;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O programa em si é muito simples, certo? Ele possui uma função &lt;strong&gt;main&lt;/strong&gt;, onde ele começa declarando uma variável &lt;strong&gt;a&lt;/strong&gt; que recebe o valor 2. Em seguida, ele chama a função &lt;strong&gt;stack_only&lt;/strong&gt; e passa de parâmetro para ela a variável &lt;strong&gt;a&lt;/strong&gt;. A função &lt;strong&gt;stack_only&lt;/strong&gt; tem em sua assinatura que ela espera um parâmetro, que ela denomina de &lt;em&gt;__b&lt;/em&gt;_ do tipo &lt;strong&gt;i32&lt;/strong&gt;, e declara em seu escopo uma variável &lt;em&gt;__c&lt;/em&gt;_ que recebe o valor 3.&lt;/p&gt;

&lt;p&gt;Vamos agora então imaginar o &lt;strong&gt;Stack&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media.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%2F2qu70jd7kr07viif6u17.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2qu70jd7kr07viif6u17.gif" alt="Representação do Stack vazio"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Naturalmente, a &lt;strong&gt;Stack&lt;/strong&gt; vai se iniciar vazia, assim como nossa imagem acima representa. E então, seguindo os procedimentos que também já mencionamos, nossa função &lt;strong&gt;main&lt;/strong&gt; declara uma variável, logo, ela deve possuir um &lt;strong&gt;stack_frame&lt;/strong&gt; que comporte essa mesma. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxchbno8738agsgga582q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxchbno8738agsgga582q.gif" alt="Representação do Stack com o Stack Frame da função main"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em seguida, antes da função &lt;strong&gt;main&lt;/strong&gt; terminar (logo, nada de desalocações do &lt;strong&gt;stack_frame&lt;/strong&gt; dela ainda), uma outra função é chamada: &lt;strong&gt;stack_only&lt;/strong&gt;.&lt;br&gt;
Essa função naturalmente também vai precisar do seu &lt;strong&gt;stack_frame&lt;/strong&gt;, e diferente da &lt;strong&gt;main&lt;/strong&gt;, ela precisará comportar espaço para duas váriáveis: a variável &lt;strong&gt;b&lt;/strong&gt; que é especificada em sua assinatura e recebe o valor da variável &lt;strong&gt;a&lt;/strong&gt;, 2, e a variável &lt;strong&gt;c&lt;/strong&gt; declarada em seu escopo que recebe o valor 3. &lt;br&gt;
&lt;a href="https://media.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%2Fne769jsfys9u67mgycce.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fne769jsfys9u67mgycce.gif" alt="Representação do Stack com o Stack Frame da função main e com o Stack Frame da função stack_only"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora sim. A função &lt;strong&gt;stack_only&lt;/strong&gt; termina e neste instante, seu &lt;strong&gt;stack_frame&lt;/strong&gt; é liberado, o que deixa nosso &lt;strong&gt;Stack&lt;/strong&gt; assim:&lt;br&gt;
&lt;a href="https://media.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%2Fxchbno8738agsgga582q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxchbno8738agsgga582q.gif" alt="Representação do Stack com o Stack Frame da função main após o Stack Frame da função stack_only ter sido desalocado"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Por fim, a função &lt;strong&gt;main&lt;/strong&gt; se encerra e seu &lt;strong&gt;stack_frame&lt;/strong&gt; também é liberado:&lt;br&gt;
&lt;a href="https://media.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%2F2qu70jd7kr07viif6u17.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2qu70jd7kr07viif6u17.gif" alt="Representação do Stack vazio, após o Stack Frame da função Main ter sido desalocado"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;É importante ressaltarmos que o &lt;strong&gt;Stack&lt;/strong&gt; possui um tamanho limitado que é determinado, dentre outros fatores, pela arquitetura do processador, sistema operacional, compilador...&lt;br&gt;
Logo, se utilizarmos por exemplo uma recursão infinita, nossa &lt;strong&gt;Stack&lt;/strong&gt; vai eventualmente ser completamente preenchida e na tentativa de alocarmos mais um &lt;strong&gt;stack_frame&lt;/strong&gt; vamos nos deparar com a famigerada &lt;strong&gt;Stack Overflow Exception&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Simples, certo? As coisas vão mudar um pouco no momento em que introduzirmos um outro conteito: o &lt;strong&gt;Heap&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;Heap&lt;/strong&gt; se difere da &lt;strong&gt;Stack&lt;/strong&gt; por ser uma região da memória de processamento que &lt;strong&gt;não&lt;/strong&gt; é automaticamente gerenciada para nós, logo, nós temos que manualmente alocar memória nela e tão importante quanto, manualmente desalocar a memória dela. &lt;br&gt;
Esquecer de desalocar memórias alocadas no &lt;strong&gt;Heap&lt;/strong&gt; é uma das principais causas de &lt;strong&gt;memory leaks&lt;/strong&gt; em aplicações.&lt;br&gt;
Diferente da &lt;strong&gt;Stack&lt;/strong&gt; que possui seu tamanho definido em &lt;strong&gt;tempo de compilação&lt;/strong&gt;, o &lt;strong&gt;Heap&lt;/strong&gt; não possui um limite específico, mas sim delimitado apenas pela quantidade de recursos físicos que uma máquina conseguirá prover.&lt;/p&gt;

&lt;p&gt;Observemos o exemplo a seguir, analisando apenas as interações com o &lt;strong&gt;Heap&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn main() {
  let a = 2;
  stack_only(a);
  stack_and_heap()
}

fn stack_only(_b: i32) {
  let _c = 3;
}

fn stack_and_heap() {
  let _d = Box::new(4);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Diferente da representação do &lt;strong&gt;Stack&lt;/strong&gt;, o &lt;strong&gt;Heap&lt;/strong&gt; não é uma pilha e muito menos irá 'enpilhar' algo. Podemos visualizá-lo como um espaço onde as alocações irão ocupar blocos cujo tamanho varia conforme o necessário para alocar o desejado. Ele começa vazio, conforme a representação abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4o5pa7jx7n91ffqi0zq7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4o5pa7jx7n91ffqi0zq7.gif" alt="Representação do Heap e da Stack ambos vazios"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Até que a nossa função &lt;em&gt;stack_and_heap&lt;/em&gt; seja executada, nosso &lt;strong&gt;Stack&lt;/strong&gt; nesse exemplo será identico ao exemplo anterior. Portanto, vamos partir do momento em que o &lt;em&gt;stack_frame&lt;/em&gt; da função &lt;em&gt;stack_only&lt;/em&gt; é liberado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4tyy7rmlhuav3krimxy8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4tyy7rmlhuav3krimxy8.gif" alt="Representação do Heap e da Stack, mas a Stack após a função stack_frame ter se encerrado"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao executarmos a função &lt;em&gt;stack_and_heap&lt;/em&gt;, vamos ter um &lt;strong&gt;&lt;em&gt;stack_frame&lt;/em&gt;&lt;/strong&gt; para ela também. Até aqui, nada demais:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fjl2sr1imzgr693akeh4n.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fjl2sr1imzgr693akeh4n.gif" alt="Representação do Heap e da Stack, mas a Stack após a função stack_frame ter se encerrado e agora com um Stack Frame para a função stack_and_heap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora as coisas ficam um pouco diferentes. Em Rust o &lt;strong&gt;&lt;em&gt;Box&lt;/em&gt;&lt;/strong&gt; é um &lt;strong&gt;&lt;em&gt;Smart Pointer&lt;/em&gt;&lt;/strong&gt; que irá, vide nosso exemplo, alocar o valor 4 no &lt;strong&gt;&lt;em&gt;Heap&lt;/em&gt;&lt;/strong&gt; e automaticamente alocar assim que essa função for encerrada. A varíavel &lt;strong&gt;&lt;em&gt;d&lt;/em&gt;&lt;/strong&gt;, ao invés de simplesmente receber o valor 4, diferente das atribuições de variáveis que fizemos até então, receberá o endereço do valor que foi alocado no &lt;strong&gt;&lt;em&gt;Heap&lt;/em&gt;&lt;/strong&gt;, que nada mais é do que o ponteiro que leva a ele.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Flwpjv5e0m7n6q4grhzjy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Flwpjv5e0m7n6q4grhzjy.gif" alt="Representação do Heap e da Stack, com o Heap contento o valor 4 alocado nele e o Stack com um ponteiro para este"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nosso programa poderia ter vários outros objetos alocados no Heap, e ele ficaria mais ou menos assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvi9wp7dyyv45pozdeltp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvi9wp7dyyv45pozdeltp.gif" alt="Representação do Heap e da Stack, com o Heap contento o valor 4 alocado nele e o Stack com um ponteiro para este e vários outros objetos alocados simulando outras alocações"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voltando agora para o nosso exemplo, o &lt;strong&gt;&lt;em&gt;stack_frame&lt;/em&gt;&lt;/strong&gt; da função &lt;em&gt;stack_and_heap&lt;/em&gt; será liberado e o valor 4 será desalocado do &lt;strong&gt;&lt;em&gt;Heap&lt;/em&gt;&lt;/strong&gt;, nos deixando no seguinte caso:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fuoa0aesyhc0l1n1psd6e.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fuoa0aesyhc0l1n1psd6e.gif" alt="Representação do Heap e da Stack, com o stack frame da função stack_and_heap removido e o valor 4 desalocado do Heap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vale ressaltar: o valor 4 está sendo desalocado justamente graças ao &lt;strong&gt;&lt;em&gt;Box&lt;/em&gt;&lt;/strong&gt;, que é um &lt;strong&gt;&lt;em&gt;Smart Pointer&lt;/em&gt;&lt;/strong&gt;. Se estivéssemos utilizando um &lt;strong&gt;&lt;em&gt;raw pointer&lt;/em&gt;&lt;/strong&gt; teríamos que fazer essa desalocação de forma manual ou teríamos um &lt;strong&gt;&lt;em&gt;memory leak&lt;/em&gt;&lt;/strong&gt; como falamos anteriormente, e essa seria a nossa representação:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fhfyhf8ujngmh265btdob.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhfyhf8ujngmh265btdob.gif" alt="Representação do Heap e da Stack, com o stack frame da função stack_and_heap removido mas o valor 4 não desalocado do Heap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O programa se encerraria e a memória anteriormente alocada no &lt;strong&gt;&lt;em&gt;Heap&lt;/em&gt;&lt;/strong&gt; persistiria e o que iria acontecer com ela passa a depender muito do Sistema Operacional e da arquitetura por trás. Em computadores com Windows ou distribuições UNIX, o Sistema Operacional irá simplesmente reinvidicar a memória para si e utilizá-la em outro processo por exemplo, mas isso pode não ser verdade para aplicações embarcadas. &lt;/p&gt;

&lt;p&gt;Os próximos passos do nosso programa são exatamente os mesmos do exemplo anterior e agora consistem de liberar o &lt;strong&gt;&lt;em&gt;stack_frame&lt;/em&gt;&lt;/strong&gt; da função &lt;strong&gt;&lt;em&gt;main&lt;/em&gt;&lt;/strong&gt;, basicamente nos levando de volta para o cenário inicial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F4o5pa7jx7n91ffqi0zq7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F4o5pa7jx7n91ffqi0zq7.gif" alt="Representação do Heap e da Stack ambos vazios"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sem mais delongas e devidamente aquecidos vamos agora para o &lt;strong&gt;&lt;em&gt;GNU Debugger&lt;/em&gt;&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Vamos utilizar o código do nosso último exemplo com pequenas alterações, especificamente para nos ajudar a colocar nossos &lt;strong&gt;&lt;em&gt;breakpoints&lt;/em&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use log::info;

fn main() {
  let a = 2;
  stack_only(a);
  stack_and_heap()
}

fn stack_only(_b: i32) {
  let _c = 3;
  info!("Debugging stack_only")
}

fn stack_and_heap() {
  let _d = Box::new(4);
  info!("Debugging stack_and_heap")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com nosso exemplo compilado, posso iniciá-lo junto ao &lt;strong&gt;&lt;em&gt;gdb&lt;/em&gt;&lt;/strong&gt; da seguinte forma:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2q2ifhbz77hguwrkis4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2q2ifhbz77hguwrkis4w.png" alt="Executando o GNU Debugger com nosso exemplo compilado"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para uma melhor visualização e interação ao &lt;strong&gt;&lt;em&gt;gdb&lt;/em&gt;&lt;/strong&gt;, vou fazer uma pequena alteração com um comando que a própria interface do CLI dele nos dispõe. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fixk5m1xueoesqfi23joy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fixk5m1xueoesqfi23joy.png" alt="Alterando o Layout do gdb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com essa alteração, o seu display do &lt;strong&gt;gdb&lt;/strong&gt; deve ter ficado mais ou menos com a seguinte aparência:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F9k9q20c1rz9gnw8d4pm4.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F9k9q20c1rz9gnw8d4pm4.PNG" alt="Aparencia do Layout do gdb após a alteração"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, podemos por exemplo visualizar nosso código para analisarmos onde podemos colocar alguns &lt;strong&gt;&lt;em&gt;breakpoints&lt;/em&gt;&lt;/strong&gt;. Para isso, podemos utilizar o seguinte comando:&lt;br&gt;
&lt;a href="https://media.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%2F2w9s1l39ict89vd34i5d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2w9s1l39ict89vd34i5d.png" alt="Listando o código exemplo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E nossa visualização no &lt;strong&gt;gdb&lt;/strong&gt; será a seguinte:&lt;br&gt;
&lt;a href="https://media.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%2Fubk8hmn7jayh3cx8pxp9.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fubk8hmn7jayh3cx8pxp9.PNG" alt="Visualização do Código no gdb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para colocarmos um &lt;strong&gt;&lt;em&gt;breakpoint&lt;/em&gt;&lt;/strong&gt; em um ponto específico, podemos utilizar o comando:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F0zcy7iulnffv6cujbzce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0zcy7iulnffv6cujbzce.png" alt="Comando para colocar um Breakpoint no código"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visando já alguns pontos interessantes, vamos colocar nas &lt;strong&gt;linhas 4, 10 e 15&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.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%2Fh7kahkjirrvvkfqg4o5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fh7kahkjirrvvkfqg4o5o.png" alt="Breakpoints para as linhas 4, 10 e 15"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nosso código listado no GDB deve estar agora com as linhas que colocamos os &lt;strong&gt;breakpoints&lt;/strong&gt; devidamente marcadas, como no exemplo abaixo:&lt;br&gt;
&lt;a href="https://media.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%2Fbgyh9i5nbneyu15kvao4.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbgyh9i5nbneyu15kvao4.PNG" alt="Código no gdb com os breakpoints"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora, sem mais delongas, vamos executar nosso código utilizando um comando simples, de uma letra só:&lt;br&gt;
&lt;a href="https://media.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%2Fh4m2l7szt5pfpm8djky7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fh4m2l7szt5pfpm8djky7.png" alt="Executando código"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E agora, nosso código deve ter se iniciado e travado no nosso primeiro &lt;strong&gt;breakpoint&lt;/strong&gt;, na &lt;strong&gt;linha 4&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media.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%2F50lzq7edg5yx59rekal6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F50lzq7edg5yx59rekal6.png" alt="Código executando com Breakpoint na Linha 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como estamos na função &lt;strong&gt;&lt;strong&gt;main&lt;/strong&gt;&lt;/strong&gt;, significa que já temos um &lt;strong&gt;&lt;strong&gt;stack_frame&lt;/strong&gt;&lt;/strong&gt;. Podemos observá-lo utilizando o comando &lt;strong&gt;backtrace&lt;/strong&gt;:&lt;br&gt;
 &lt;a href="https://media.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%2Fpahp4ngsz3udawcie655.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fpahp4ngsz3udawcie655.png" alt="Comando para observar como estão os StackFrames"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como &lt;strong&gt;sabemos&lt;/strong&gt; que temos apenas &lt;strong&gt;1 &lt;strong&gt;stack_frame&lt;/strong&gt;&lt;/strong&gt;, então vamos utilizar o comando passando esse valor. O que nos forneceria o seguinte resultado:&lt;br&gt;
&lt;a href="https://media.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%2Fd83r6dsn1ay0x9v46171.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fd83r6dsn1ay0x9v46171.png" alt="Observando Stack Frame da função main"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contudo, até então, não existe nenhuma variável alocada dentro do &lt;strong&gt;&lt;em&gt;stack_frame&lt;/em&gt;&lt;/strong&gt;, pois a execução do nosso programa para &lt;strong&gt;logo antes de executar a linha em que posicionamos um &lt;strong&gt;breakpoint&lt;/strong&gt;&lt;/strong&gt;. Podemos verificar se houve alguma alocação de variável utilizando o comando:&lt;br&gt;
&lt;a href="https://media.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%2Ftptrbbypubggevei1f7m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftptrbbypubggevei1f7m.png" alt="Comando para verificar alocações de variáveis"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se executarmos esse comando agora, este será o output:&lt;br&gt;
&lt;a href="https://media.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%2Fcdhsqoxmalg29nxzfks3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fcdhsqoxmalg29nxzfks3.png" alt="Verificando alocação de memória antes do nosso breakpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para darmos continuidade, vamos apenas passar pela alocação da variável que nosso &lt;strong&gt;breakpoint&lt;/strong&gt; está segurando, antes de entrarmos nas funções, para conseguirmos observar a alocação. Para isso, podemos utilizar o comando &lt;strong&gt;next&lt;/strong&gt;: &lt;br&gt;
&lt;a href="https://media.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%2Fhg1n9phelh6chvkyfzhx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fhg1n9phelh6chvkyfzhx.png" alt="Comando para passar uma linha na execução dos comandos após um breakpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Que nos dá o seguinte resultado:&lt;br&gt;
&lt;a href="https://media.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%2Fqx5vu6bn8rqw2w5c9gm7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fqx5vu6bn8rqw2w5c9gm7.png" alt="Passado o breakpoint utilizando o comando next"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se agora tentarmos utilizar o comando para analisarmos as alocações de variáveis:&lt;br&gt;
&lt;a href="https://media.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%2Fjb9xn6hcyq4akossxm7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fjb9xn6hcyq4akossxm7i.png" alt="Alocação da variável 'a' recebendo o valor 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos observar agora que, neste &lt;strong&gt;_&lt;em&gt;stack_frame&lt;/em&gt;&lt;/strong&gt;, existe a variável &lt;strong&gt;a&lt;/strong&gt; que recebeu o valor &lt;strong&gt;2&lt;/strong&gt;. &lt;br&gt;
Agora, é interessante que 'entremos' dentro da função &lt;strong&gt;stack_only&lt;/strong&gt; para observamos como o que vimos até então pode mudar. Para isso, podemos utilizar o comando &lt;strong&gt;step&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media.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%2F6961sm3bfmuuqy41azgl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F6961sm3bfmuuqy41azgl.png" alt="Comando para entrarmos em uma função pelo debugger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se tivéssemos utilizado o comando &lt;strong&gt;next&lt;/strong&gt;, a função &lt;strong&gt;stack_only&lt;/strong&gt; teria sido executada e o debugger iria para a função &lt;strong&gt;stack_and_heap&lt;/strong&gt;.&lt;br&gt;
Se o comando &lt;strong&gt;step&lt;/strong&gt; foi utilizado corretamente, seu gdb deve estar assim:&lt;br&gt;
&lt;a href="https://media.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%2F5iqz0sr6231cw7ghphny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5iqz0sr6231cw7ghphny.png" alt="gdb após a execução do comando step"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como estamos em outra função, temos outro &lt;strong&gt;_&lt;em&gt;stack_frame&lt;/em&gt;&lt;/strong&gt;. Como sabemos que temos dois até então, podemos executar o comando &lt;strong&gt;backtrace&lt;/strong&gt; passando o número &lt;strong&gt;2&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media.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%2F305cf2zmx3eahhj2rbpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F305cf2zmx3eahhj2rbpm.png" alt="Analisando agora o stack com dois stack frames"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos inclusive observar como o &lt;strong&gt;&lt;strong&gt;stack_frame&lt;/strong&gt;&lt;/strong&gt; da função &lt;strong&gt;stack_only&lt;/strong&gt; está de fato vindo antes do &lt;strong&gt;&lt;strong&gt;stack_frame&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
  </channel>
</rss>
