<?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>Forem: Austin Aigbe</title>
    <description>The latest articles on Forem by Austin Aigbe (@eshikafe).</description>
    <link>https://forem.com/eshikafe</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%2F777998%2F490f5b7d-562f-4b81-8100-2ee41e217cb3.jpeg</url>
      <title>Forem: Austin Aigbe</title>
      <link>https://forem.com/eshikafe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/eshikafe"/>
    <language>en</language>
    <item>
      <title>Deploying Your Rust Apps in the Cloud</title>
      <dc:creator>Austin Aigbe</dc:creator>
      <pubDate>Fri, 04 Mar 2022 05:13:48 +0000</pubDate>
      <link>https://forem.com/rustnigeria/deploying-your-rust-apps-in-the-cloud-7cg</link>
      <guid>https://forem.com/rustnigeria/deploying-your-rust-apps-in-the-cloud-7cg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, I provide a step-by-step guide on how you can easily deploy your Rust application in the cloud with &lt;a href="https://aws.amazon.com/ec2/" rel="noopener noreferrer"&gt;Amazon AWS EC2&lt;/a&gt;. Depending on your system requirements, you can deploy your application in the cloud to save you the hassle of managing the hardware infrastructure yourself so you can focus on what matters - your application and the customers they serve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;I am assuming you already have an AWS account, if not please create one and login as root user. We will be using the AWS EC2 Free Tier &lt;em&gt;t3.micro&lt;/em&gt; compute, as our virtual server in the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1
&lt;/h2&gt;

&lt;p&gt;After logging in as root to your AWS account, switch to the new view and nagivate to EC2 as shown in the screenshot below. Select &lt;code&gt;Services&lt;/code&gt;, &lt;code&gt;Compute&lt;/code&gt; and then click on &lt;code&gt;EC2&lt;/code&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%2Fi.imgur.com%2FY1pffNX.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%2Fi.imgur.com%2FY1pffNX.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2
&lt;/h2&gt;

&lt;p&gt;Click on &lt;code&gt;Launch instances&lt;/code&gt; as shown below.&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%2Fi.imgur.com%2F40nqhzZ.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%2Fi.imgur.com%2F40nqhzZ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3
&lt;/h2&gt;

&lt;p&gt;Under choose AMI, first check the &lt;code&gt;Free tier only&lt;/code&gt; box on the left side of the window and then select any image. I selected &lt;code&gt;Ubuntu Server 20.04 LTS&lt;/code&gt; image. You can experiment with any of the images.&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%2Fi.imgur.com%2FkD3zs7B.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%2Fi.imgur.com%2FkD3zs7B.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4
&lt;/h2&gt;

&lt;p&gt;Make sure you select the t3.micro (it is the &lt;code&gt;free tier&lt;/code&gt; instance type) and then click on &lt;code&gt;Review and Launch&lt;/code&gt; then &lt;code&gt;Launch&lt;/code&gt;. This will display a window asking you to select or create a key pair. Select the applicable option and then click on &lt;code&gt;Launch Instance&lt;/code&gt;&lt;br&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%2Fi.imgur.com%2F2b2UzFh.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%2Fi.imgur.com%2F2b2UzFh.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5
&lt;/h2&gt;

&lt;p&gt;Give your virtual server a name. Mine is named &lt;code&gt;server-01&lt;/code&gt;. Wait for your server to change &lt;code&gt;Instance state&lt;/code&gt; to &lt;code&gt;Running&lt;/code&gt; before you connect to it.&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%2Fi.imgur.com%2FSE9bQwx.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%2Fi.imgur.com%2FSE9bQwx.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6
&lt;/h2&gt;

&lt;p&gt;Now, you can connect to your virtual server using &lt;a href="https://www.putty.org/" rel="noopener noreferrer"&gt;PuTTy&lt;/a&gt;, Powershell, Bash (if you are using Linux), CMD or any client application that supports &lt;code&gt;SSH&lt;/code&gt;. I am using PuTTy. To connect to the &lt;code&gt;compute&lt;/code&gt; or virtual server, ssh to the &lt;code&gt;Public IPv4 DNS&lt;/code&gt; address specified under the &lt;code&gt;Details&lt;/code&gt; tab.&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%2Fi.imgur.com%2FU4QAbAw.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%2Fi.imgur.com%2FU4QAbAw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7
&lt;/h2&gt;

&lt;p&gt;The user name is &lt;code&gt;ubuntu&lt;/code&gt;. The virtual server has access to the internet and you can install any package you need. Now, let's install the Rust compiler.&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%2Fi.imgur.com%2F0yt7Dy8.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%2Fi.imgur.com%2F0yt7Dy8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8
&lt;/h2&gt;

&lt;p&gt;Install Rust and &lt;code&gt;buid-essential&lt;/code&gt; (sudo apt install build-essential).&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%2Fi.imgur.com%2F1i1tawo.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%2Fi.imgur.com%2F1i1tawo.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 9
&lt;/h2&gt;

&lt;p&gt;We will be deploying two types of application on the virtual server - a telecoms application (a &lt;a href="https://en.wikipedia.org/wiki/GPRS_Tunnelling_Protocol" rel="noopener noreferrer"&gt;GTPv2-C&lt;/a&gt; server) and a web application based on the &lt;a href="https://github.com/seanmonstar/warp" rel="noopener noreferrer"&gt;warp&lt;/a&gt; crate. GTPv2C protocol is used in the &lt;a href="https://www.3gpp.org/" rel="noopener noreferrer"&gt;3GPP&lt;/a&gt; based 3G, 4G and 5G networks for signaling and it uses port 2123 and the &lt;a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol" rel="noopener noreferrer"&gt;UDP&lt;/a&gt; transport protocol. We will configure our Rust GTP server to listen on UDP port 2123 in compilance with the &lt;a href="https://www.arib.or.jp/english/html/overview/doc/STD-T63v9_60/5_Appendix/Rel8/29/29274-8b0.pdf" rel="noopener noreferrer"&gt;3GPP TS 29.274&lt;/a&gt; (GTPv2-C) standard.&lt;/p&gt;

&lt;p&gt;The web server will listen on TCP port 3030.&lt;/p&gt;

&lt;p&gt;Configure the &lt;code&gt;Inbound rules&lt;/code&gt; as shown below. AWS EC2 will apply these rules to our virtual server and it will allow our Rust applications to send and receive messages using these rules.&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%2Fi.imgur.com%2FsBnezgP.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%2Fi.imgur.com%2FsBnezgP.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 10
&lt;/h2&gt;

&lt;p&gt;Create your web server application using &lt;code&gt;cargo new web_server&lt;/code&gt; and edit with nano as shown below. The original code is available here:&lt;a href="https://github.com/seanmonstar/warp" rel="noopener noreferrer"&gt;https://github.com/seanmonstar/warp&lt;/a&gt; and it has been slightly modified for this tutorial. Run the web server with &lt;code&gt;cargo run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After this step, you will have two Rust applications running in the cloud. You can use the &lt;code&gt;ps aux | grep target&lt;/code&gt; to check the two processes running (&lt;code&gt;gtp&lt;/code&gt; and &lt;code&gt;web_server&lt;/code&gt;)&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%2Fi.imgur.com%2FrP0uJb2.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%2Fi.imgur.com%2FrP0uJb2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 11
&lt;/h2&gt;

&lt;p&gt;Open another PuTTy session and connect to the virtual server. Clone the GTPv2-C server from  &lt;a href="https://github.com/eshikafe/ngc" rel="noopener noreferrer"&gt;https://github.com/eshikafe/ngc&lt;/a&gt; and edit the &lt;code&gt;ngc/common/gtp/src/main.rs&lt;/code&gt; so that the server listens and accepts conections from any IP address (i.e &lt;code&gt;0.0.0.0&lt;/code&gt;) as shown below. Run the application with &lt;code&gt;cargo run&lt;/code&gt;&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%2Fi.imgur.com%2FbS1uYtr.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%2Fi.imgur.com%2FbS1uYtr.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the screen shot below, a simple &lt;code&gt;Python&lt;/code&gt; script (the client) sends a message to the gtp server application using the &lt;code&gt;Public IP address&lt;/code&gt; and port 2123. The script sends a GTPv2-C &lt;code&gt;Create Session Request&lt;/code&gt; message from my Windows PC, through the internet, to the Rust GTPv2-C server application running in the cloud. This implies that you can deploy a telecom application (based on Rust) in the cloud to serve multiple devices concurrently and efficiently. The sample gtp application uses the &lt;a href="https://tokio.rs/" rel="noopener noreferrer"&gt;tokio&lt;/a&gt; crate to achieve concurrency. Concurrency is a key requirement for a 4G/5G telecom server application.&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%2Fi.imgur.com%2F3RaFT6J.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%2Fi.imgur.com%2F3RaFT6J.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 12
&lt;/h2&gt;

&lt;p&gt;Lastly, open a web browser and paste the following URL in the address bar:&lt;code&gt;{Public IPv4 DNS}:3030/hello/Rustacean&lt;/code&gt;. Replace &lt;code&gt;Public IPv4 DNS&lt;/code&gt; with the domain assigned to your compute. You should see the message below.&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%2Fi.imgur.com%2FqIlyhO4.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%2Fi.imgur.com%2FqIlyhO4.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also use curl to test your web server as shown below.&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%2Fi.imgur.com%2FSfZwGE3.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%2Fi.imgur.com%2FSfZwGE3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To deploy your applications securely in the cloud, you need to understand how the &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html" rel="noopener noreferrer"&gt;AWS EC2 security group&lt;/a&gt; works. Please read the AWS EC2 security group documentation before you deploy your application as a production system in the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=7mgBvbqUVgw&amp;amp;t=1267s" rel="noopener noreferrer"&gt;AWS Tutorial for Beginners - Full Crash Course | Neal Davis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>telecoms</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Rust-y Memory. How Safe?</title>
      <dc:creator>Austin Aigbe</dc:creator>
      <pubDate>Fri, 04 Feb 2022 20:03:34 +0000</pubDate>
      <link>https://forem.com/rustnigeria/rust-y-memory-how-safe-p6g</link>
      <guid>https://forem.com/rustnigeria/rust-y-memory-how-safe-p6g</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jj4EkXgt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5whsu4epptijauzz3vry.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jj4EkXgt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5whsu4epptijauzz3vry.jpg" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;By &lt;a href="https://www.linkedin.com/in/austin-aigbe-1ba59b50/"&gt;Austin Aigbe&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt; programming language is said to be memory-safe but how does it achieve this? Why should we even care about memory safety? It turns out that the major cause of security vulnerabilities in modern day software systems (including Desktop and mobile applications) is due to memory safety issues and to address this, there is a general consensus, which I personally agree to, that a memory-safe systems programming language like &lt;code&gt;Rust&lt;/code&gt; is required. This is one of the reasons big tech companies have decided to &lt;a href="https://foundation.rust-lang.org/members/"&gt;invest in Rust&lt;/a&gt; and re-engineer some of their key products and services with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does &lt;code&gt;Rust&lt;/code&gt; Achieve Memory Safety?
&lt;/h2&gt;

&lt;p&gt;Memory safety is achieved through three key concepts: &lt;code&gt;ownership&lt;/code&gt; (a language feature the compiler uses to free and allocate memory based on the scope of a variable binding), &lt;code&gt;borrow checking&lt;/code&gt; and &lt;code&gt;lifetimes&lt;/code&gt;. All these analyses are done during compile-time.&lt;/p&gt;

&lt;p&gt;For simplicity, I will focus more on the &lt;code&gt;ownership&lt;/code&gt; concept and show us how the compiler guarantees memory safety at compile-time using the scope of a variable binding to determine when to allocate and deallocate memory on the stack. &lt;/p&gt;

&lt;p&gt;Before we proceed, let's review how our code is analyzed by the Rust compiler (&lt;code&gt;rustc&lt;/code&gt;) for memory safety.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Compilation With Memory Management
&lt;/h2&gt;

&lt;p&gt;In simple terms, a &lt;code&gt;memory&lt;/code&gt; is a storage space (e.g &lt;code&gt;RAM&lt;/code&gt;) on your computer where instructions to be executed by the computer's CPU are stored. These instructions are the lines of Rust code you have written and compiled with &lt;code&gt;rustc&lt;/code&gt; (the Rust compiler) or &lt;code&gt;cargo&lt;/code&gt; into a machine executable file (e.g &lt;a href="https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only"&gt;&lt;code&gt;.exe&lt;/code&gt;&lt;/a&gt; file format on Windows and &lt;a href="https://refspecs.linuxfoundation.org/"&gt;&lt;code&gt;elf&lt;/code&gt;&lt;/a&gt; on Linux). The executable file tells the Operating System how to load your &lt;code&gt;Rust&lt;/code&gt; program into &lt;code&gt;memory&lt;/code&gt; for execution by the CPU.&lt;/p&gt;

&lt;p&gt;Now, let's compile a very simple &lt;code&gt;Rust&lt;/code&gt; program with &lt;code&gt;rustc&lt;/code&gt; and examine how memory management (&lt;code&gt;ownership&lt;/code&gt;) works in Rust.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// hello.rs&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rust_edition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, Rust"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{message} {rust_edition}!"&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;Compiling the above code with &lt;code&gt;rustc .\hello.rs&lt;/code&gt; on Windows will produce an executable file,&lt;code&gt;hello.exe&lt;/code&gt; (about 148KB in size), in the same directory as the .rs file.&lt;/p&gt;

&lt;p&gt;Next, let's see how the &lt;code&gt;hello.exe&lt;/code&gt; was produced by &lt;code&gt;rustc&lt;/code&gt; and how the memory-safety checks were done.&lt;/p&gt;

&lt;p&gt;The Rust compiler, &lt;code&gt;rustc&lt;/code&gt;, performed several analyses on the &lt;code&gt;hello.rs&lt;/code&gt; file before it produced the &lt;code&gt;hello.exe&lt;/code&gt; executable file. I will give a high-level overview of this process so we understand how memory safety is achieved by the compiler and at what phase of the compilation process it is done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DZWailFL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/72SEKSw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DZWailFL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/72SEKSw.png" alt="" width="880" height="341"&gt;&lt;/a&gt;&lt;br&gt;
Figure 1: An simplified view of &lt;code&gt;rustc&lt;/code&gt; compilation process &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1&lt;/strong&gt;: &lt;code&gt;hello.rs&lt;/code&gt; was translated to basic tokens using the &lt;code&gt;rustc_lexer&lt;/code&gt; crate and then to Rust &lt;code&gt;tokens&lt;/code&gt; using the &lt;code&gt;rustc_parser&lt;/code&gt; crate. Tokens are easier for the compiler to work with than the text format of your .rs file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2&lt;/strong&gt;:&lt;code&gt;Tokens&lt;/code&gt; were translated to &lt;code&gt;AST&lt;/code&gt; (Abstract Syntax Tree) format. Syntax analysis is done here. Use &lt;code&gt;cargo inspect --unpretty=ast-tree .\hello.rs&lt;/code&gt; to examine the AST output.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SVSYyVLx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/wHwJRPz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SVSYyVLx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/wHwJRPz.png" alt="" width="880" height="567"&gt;&lt;/a&gt;&lt;br&gt;
Figure 2: AST tree of &lt;code&gt;hello.rs&lt;/code&gt; with &lt;code&gt;cargo-inspect&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 3&lt;/strong&gt; The &lt;code&gt;println!&lt;/code&gt; macro was refined (or desugared) to a &lt;code&gt;std::io::_print&lt;/code&gt; statement and &lt;code&gt;core::fmt::Arguments&lt;/code&gt; function calls.The data type of our expressions were inferred and checked. We can say that type safety is guarateed at this phase of the code compilation. The HIR (High-Level Intermediate Representation) is the output of this stage. You can use &lt;code&gt;crago inspect --unpretty=hir .\hello.rs&lt;/code&gt; to view the HIR representation of your Rust code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3EWL3pHu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/kSPdFvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3EWL3pHu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/kSPdFvv.png" alt="" width="851" height="461"&gt;&lt;/a&gt;&lt;br&gt;
Figure 3:&lt;code&gt;println!&lt;/code&gt; macro desugared in the HIR. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 4&lt;/strong&gt; HIR was converted to MIR (Mid-level Intermediate Representation). Ownership, borrow-checking and optimizations are done here. In fact, the MIR shows the scope of each variable and helps the compiler know at what point a variable binding (or ownership) is out of scope and when to dellocate memory from the stack. How the compiler tracks the scope of each variable is indicated in the screenshot below. In fact, the assembly code generated by &lt;a href="https://llvm.org/"&gt;LLVM&lt;/a&gt; (in phase 6) is the machine representation of the MIR (after the ownership, borrow checking and optimizations have been done). In the next phase, the &lt;code&gt;asm&lt;/code&gt; .S file is examined to see how the variables are allocated on the &lt;code&gt;Stack&lt;/code&gt; when they are in scope and how they are deallocated when they are out of scope. In this phase, memory safety is guaranteed by the compiler.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zxdhu2iF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/9BSWZ32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zxdhu2iF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/9BSWZ32.png" alt="" width="880" height="648"&gt;&lt;/a&gt;&lt;br&gt;
Figure 4: MIR representation of &lt;code&gt;hello.rs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 5 and 6&lt;/strong&gt; This is the code generation phase - LLVM was used to generate the final executable file &lt;code&gt;hello.exe&lt;/code&gt; from the optimized and memory-safe MIR representation. Further optimizations can also be done by LLVM. &lt;/p&gt;

&lt;p&gt;Let's briefly examine the assembly code (.S file) generated by LLVM. You can use &lt;code&gt;rustc --emit asm .\hello.rs&lt;/code&gt; to generate the file. To keep things simple, I will only examine how the &lt;code&gt;ownership&lt;/code&gt; memory-safety feature was achieved by the allocation and deallocation of memory on the stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OKe2x8Ax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/E1VoudA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OKe2x8Ax--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/E1VoudA.png" alt="" width="880" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Figure 5: A simplified memory layout of the stack from the perspective of the compiler generated &lt;code&gt;main&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The assembly code for the &lt;code&gt;main&lt;/code&gt; function is shown above (in Figure 5). The entry point is not our &lt;code&gt;hello::main&lt;/code&gt; function. As we will see later, Rust has a runtime (&lt;code&gt;std::rt::lang_start_internal&lt;/code&gt;). This runtime handles a lot of complexities for us that we don't need to bother about when writing our Rust code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Line 516: The compiler generated main function is the entry point for our program.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Line 518: 40 bytes of memory is allocated on the stack.&lt;code&gt;rsp&lt;/code&gt; is the 64-bit stack pointer register for x86_64. It always points to the top the stack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Line 523: &lt;code&gt;_ZN5hello4main17h0767239aa2b5c6caE&lt;/code&gt; is the mangled symbol for our &lt;code&gt;hello.rs&lt;/code&gt; &lt;code&gt;main()&lt;/code&gt; function. The address of our &lt;code&gt;hello::main&lt;/code&gt; function is stored in %rcx and then passed to the runtime function as a reference in line 103.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Line 524: This line calls the Rust runtime function &lt;code&gt;std::rt::lang_start&lt;/code&gt; (defined in line 94) and subsequently, the internal runtime function &lt;code&gt;std::rt::lang_start_internal&lt;/code&gt; (defined in line 104). Rust has a runtime that executes our &lt;code&gt;hello.rs main()&lt;/code&gt; function.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xFB3fJl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/gx2fnqx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xFB3fJl6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/gx2fnqx.png" alt="" width="880" height="469"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Figure 6: Rust runtime function executes our hello::main function&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Lq7MTeF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/hSGodss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Lq7MTeF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/hSGodss.png" alt="" width="880" height="447"&gt;&lt;/a&gt;&lt;br&gt;
Figure 7: Execution of &lt;code&gt;hello::main&lt;/code&gt; (part 1)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RRW4B4m7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/oWxVc3T.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RRW4B4m7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/oWxVc3T.png" alt="" width="880" height="552"&gt;&lt;/a&gt;&lt;br&gt;
Figure 8: Execution of &lt;code&gt;hello::main&lt;/code&gt; (part 2)&lt;/p&gt;

&lt;p&gt;Figures 7 and 8 show how sufficient memory (200 bytes) was first allocated on the stack by the compiler before allocating memory to the two local variables &lt;code&gt;rust_edition&lt;/code&gt; (an &lt;code&gt;i32&lt;/code&gt;), and &lt;code&gt;message&lt;/code&gt; (a &lt;code&gt;&amp;amp;str&lt;/code&gt;). Before returning from the &lt;code&gt;hello::main&lt;/code&gt; function, the compiler deallocates memory on the stack and frees up resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have seen how Rust guarantees memory safety during compile-time by examining the compilation phases and how memory is allocated and deallocated on the stack in assembly code. A very simple Rust program (&lt;code&gt;hello.rs&lt;/code&gt;) was used to examine the output of each compilation phase and the memory management of the stack in assembly code.&lt;/p&gt;

&lt;p&gt;We also learnt that the Rust compiler generates a &lt;code&gt;main&lt;/code&gt; function for us as the entry point of our program. This main function uses the Rust runtime to execute the main function of our Rust program.&lt;/p&gt;

&lt;p&gt;In summary, Rust tries to guaranty memory safety during compile time and it does a pretty good job in ensuring this.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://rustc-dev-guide.rust-lang.org/overview.html"&gt;Overview of the Compiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.rust-lang.org/1.8.0/book/ownership.html"&gt;Ownership&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doc.rust-lang.org/1.8.0/book/references-and-borrowing.html"&gt;References and Borrowing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oracle.com/cd/E19253-01/817-5477/817-5477.pdf"&gt;x86 Assembly Language Reference Manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.princeton.edu/courses/archive/spr16/cos217/lectures/15_AssemblyFunctions.pdf"&gt;Assembly Language: Function Calls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf"&gt;x64 Cheat Sheet&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://courses.cs.washington.edu/courses/cse351/17au/lectures/11/CSE351-L11-procedures-I_17au-ink.pdf"&gt;The Stack &amp;amp; Procedures&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>rust</category>
      <category>rustc</category>
      <category>llvm</category>
      <category>memory</category>
    </item>
  </channel>
</rss>
