mirror of
https://github.com/Noratrieb/blog.git
synced 2026-01-14 12:35:00 +01:00
deploy: 48c76f15e3
This commit is contained in:
parent
be75277094
commit
bd20f8a3bc
5 changed files with 25 additions and 26 deletions
10
index.xml
10
index.xml
|
|
@ -66,6 +66,7 @@ belong to the arcane circles of the select few who were aware of it. So lots of
|
||||||
RAII pointer” (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
RAII pointer” (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
||||||
pointers are concerned.</p>
|
pointers are concerned.</p>
|
||||||
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
|
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
|
||||||
|
<p>TODO: introduce UB by explaining how it allows optimizations like the one above, don&rsquo;t talk in standardese</p>
|
||||||
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
||||||
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
||||||
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
||||||
|
|
@ -104,11 +105,10 @@ note: inside `main` at src/main.rs:12:5
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There&rsquo;s a lot of information here.</p>
|
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There&rsquo;s a lot of information here.</p>
|
||||||
<p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
<p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
||||||
borrow stack. This is something about stacked borrows, the experimental memory model for Rust that is implemented
|
borrow stack of the byte that was accessed. This is something about stacked borrows, the experimental memory model for Rust
|
||||||
in Miri. For an excellent introduction, see this part of the great book <a href="https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html">Learning Rust With Entirely Too Many Linked Lists</a>.</p>
|
that is implemented in Miri. For an excellent introduction, see this part of the great book <a href="https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html">Learning Rust With Entirely Too Many Linked Lists</a>.</p>
|
||||||
<p>In short: each pointer has a unique tag attacked to it. Bytes in memory have a stack of such tags, and only the pointers
|
<p>In short: each pointer has a unique tag attached to it. Each byte in memory has its own &lsquo;borrow stack&rsquo; of these tags,
|
||||||
that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various
|
and only the pointers that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various operations, for example borrowing.</p>
|
||||||
operations, for example borrowing.</p>
|
|
||||||
<p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
<p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
||||||
coerced into a raw pointer) from our box, it got a new tag called <code>&lt;3314&gt;</code>. Then, when we moved the box into the function,
|
coerced into a raw pointer) from our box, it got a new tag called <code>&lt;3314&gt;</code>. Then, when we moved the box into the function,
|
||||||
something happened: The tag was invalidated and popped off the borrow stack. That&rsquo;s because box invalidates all tags when it&rsquo;s
|
something happened: The tag was invalidated and popped off the borrow stack. That&rsquo;s because box invalidates all tags when it&rsquo;s
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<!doctype html><html lang=en><head><title>Box Is a Unique Type :: nilstriebs blog</title><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="About better aliasing semantics for `Box`"><meta name=keywords content="box,noalias"><meta name=robots content="noodp"><link rel=canonical href=/posts/box-is-a-unique-type/><link rel=stylesheet href=/assets/style.css><link rel=apple-touch-icon href=/img/apple-touch-icon-192x192.png><link rel="shortcut icon" href=/img/favicon/orange.png><meta name=twitter:card content="summary"><meta property="og:locale" content="en"><meta property="og:type" content="article"><meta property="og:title" content="Box Is a Unique Type"><meta property="og:description" content="About better aliasing semantics for `Box`"><meta property="og:url" content="/posts/box-is-a-unique-type/"><meta property="og:site_name" content="nilstriebs blog"><meta property="og:image" content="/"><meta property="og:image:width" content="2048"><meta property="og:image:height" content="1024"><meta property="article:published_time" content="2022-07-22 00:00:00 +0000 UTC"></head><body class=orange><div class="container center headings--one-size"><header class=header><div class=header__inner><div class=header__logo><a href=/><div class=logo>nilstriebs blog</div></a></div></div></header><div class=content><div class=post><h1 class=post-title><a href=/posts/box-is-a-unique-type/>Box Is a Unique Type</a></h1><div class=post-meta><span class=post-date>2022-07-22</span>
|
<!doctype html><html lang=en><head><title>Box Is a Unique Type :: nilstriebs blog</title><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="About better aliasing semantics for `Box`"><meta name=keywords content="box,noalias"><meta name=robots content="noodp"><link rel=canonical href=/posts/box-is-a-unique-type/><link rel=stylesheet href=/assets/style.css><link rel=apple-touch-icon href=/img/apple-touch-icon-192x192.png><link rel="shortcut icon" href=/img/favicon/orange.png><meta name=twitter:card content="summary"><meta property="og:locale" content="en"><meta property="og:type" content="article"><meta property="og:title" content="Box Is a Unique Type"><meta property="og:description" content="About better aliasing semantics for `Box`"><meta property="og:url" content="/posts/box-is-a-unique-type/"><meta property="og:site_name" content="nilstriebs blog"><meta property="og:image" content="/"><meta property="og:image:width" content="2048"><meta property="og:image:height" content="1024"><meta property="article:published_time" content="2022-07-22 00:00:00 +0000 UTC"></head><body class=orange><div class="container center headings--one-size"><header class=header><div class=header__inner><div class=header__logo><a href=/><div class=logo>nilstriebs blog</div></a></div></div></header><div class=content><div class=post><h1 class=post-title><a href=/posts/box-is-a-unique-type/>Box Is a Unique Type</a></h1><div class=post-meta><span class=post-date>2022-07-22</span>
|
||||||
<span class=post-author>:: Nilstrieb</span>
|
<span class=post-author>:: Nilstrieb</span>
|
||||||
<span class=post-reading-time>:: 10 min read (2081 words)</span></div><span class=post-tags>#<a href=/tags/rust/>rust</a>
|
<span class=post-reading-time>:: 10 min read (2107 words)</span></div><span class=post-tags>#<a href=/tags/rust/>rust</a>
|
||||||
#<a href=/tags/unsafe-code/>unsafe code</a> </span><div class=post-content><div><p>We have all used <code>Box<T></code> before in our Rust code. It’s a glorious type, with great ergonomics
|
#<a href=/tags/unsafe-code/>unsafe code</a> </span><div class=post-content><div><p>We have all used <code>Box<T></code> before in our Rust code. It’s a glorious type, with great ergonomics
|
||||||
and flexibitility. We can use it to put our values on the heap, but it can do even more
|
and flexibitility. We can use it to put our values on the heap, but it can do even more
|
||||||
than that!</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:#66d9ef>struct</span> <span style=color:#a6e22e>Fields</span> {
|
than that!</p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-rust data-lang=rust><span style=display:flex><span><span style=color:#66d9ef>struct</span> <span style=color:#a6e22e>Fields</span> {
|
||||||
|
|
@ -50,7 +50,7 @@ was affected by this (<a href=https://youtu.be/EY7Wi9fV5bk)>https://youtu.be/EY7
|
||||||
for <a href=https://doc.rust-lang.org/nightly/std/boxed/index.html#considerations-for-unsafe-code><code>std::boxed</code></a>. Well, the nightly or beta docs, because I only added this section very recently. For years, this behaviour was not really documented, and you had to
|
for <a href=https://doc.rust-lang.org/nightly/std/boxed/index.html#considerations-for-unsafe-code><code>std::boxed</code></a>. Well, the nightly or beta docs, because I only added this section very recently. For years, this behaviour was not really documented, and you had to
|
||||||
belong to the arcane circles of the select few who were aware of it. So lots of code was written thinking that box was “just an
|
belong to the arcane circles of the select few who were aware of it. So lots of code was written thinking that box was “just an
|
||||||
RAII pointer” (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
RAII pointer” (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
||||||
pointers are concerned.</p><h1 id=stacked-borrows-and-miri>Stacked Borrows and Miri<a href=#stacked-borrows-and-miri class=hanchor arialabel=Anchor>⌗</a></h1><p><a href=https://github.com/rust-lang/miri>Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
pointers are concerned.</p><h1 id=stacked-borrows-and-miri>Stacked Borrows and Miri<a href=#stacked-borrows-and-miri class=hanchor arialabel=Anchor>⌗</a></h1><p>TODO: introduce UB by explaining how it allows optimizations like the one above, don’t talk in standardese</p><p><a href=https://github.com/rust-lang/miri>Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
||||||
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
||||||
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
||||||
what you intended to happen. Examples of UB include use-after-free, out of bounds reads or data races.</p><p>I cannot recommend Miri highly enough for all unsafe code you’re writing (sadly support for some IO functions
|
what you intended to happen. Examples of UB include use-after-free, out of bounds reads or data races.</p><p>I cannot recommend Miri highly enough for all unsafe code you’re writing (sadly support for some IO functions
|
||||||
|
|
@ -84,10 +84,9 @@ note: inside `main` at src/main.rs:12:5
|
||||||
12 | takes_box_and_ptr_to_it(b, ptr);
|
12 | takes_box_and_ptr_to_it(b, ptr);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There’s a lot of information here.</p><p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There’s a lot of information here.</p><p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
||||||
borrow stack. This is something about stacked borrows, the experimental memory model for Rust that is implemented
|
borrow stack of the byte that was accessed. This is something about stacked borrows, the experimental memory model for Rust
|
||||||
in Miri. For an excellent introduction, see this part of the great book <a href=https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html>Learning Rust With Entirely Too Many Linked Lists</a>.</p><p>In short: each pointer has a unique tag attacked to it. Bytes in memory have a stack of such tags, and only the pointers
|
that is implemented in Miri. For an excellent introduction, see this part of the great book <a href=https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html>Learning Rust With Entirely Too Many Linked Lists</a>.</p><p>In short: each pointer has a unique tag attached to it. Each byte in memory has its own ‘borrow stack’ of these tags,
|
||||||
that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various
|
and only the pointers that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various operations, for example borrowing.</p><p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
||||||
operations, for example borrowing.</p><p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
|
||||||
coerced into a raw pointer) from our box, it got a new tag called <code><3314></code>. Then, when we moved the box into the function,
|
coerced into a raw pointer) from our box, it got a new tag called <code><3314></code>. Then, when we moved the box into the function,
|
||||||
something happened: The tag was invalidated and popped off the borrow stack. That’s because box invalidates all tags when it’s
|
something happened: The tag was invalidated and popped off the borrow stack. That’s because box invalidates all tags when it’s
|
||||||
moved. The tag was popped off the borrow stack and we tried to read from it anyways - undefined behaviour happened!</p><p>And that’s how our code wasn’t a miscompilation, but undefined behaviour. Quite surprising, isn’t it?</p><h1 id=noalias-nothanks>noalias, nothanks<a href=#noalias-nothanks class=hanchor arialabel=Anchor>⌗</a></h1><p>Many people, myself included, don’t think that this is a good thing.</p><p>First of all, it introduces more UB that could have been defined behaviour instead. This is true for almost all UB, but usually,
|
moved. The tag was popped off the borrow stack and we tried to read from it anyways - undefined behaviour happened!</p><p>And that’s how our code wasn’t a miscompilation, but undefined behaviour. Quite surprising, isn’t it?</p><h1 id=noalias-nothanks>noalias, nothanks<a href=#noalias-nothanks class=hanchor arialabel=Anchor>⌗</a></h1><p>Many people, myself included, don’t think that this is a good thing.</p><p>First of all, it introduces more UB that could have been defined behaviour instead. This is true for almost all UB, but usually,
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ belong to the arcane circles of the select few who were aware of it. So lots of
|
||||||
RAII pointer&rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
RAII pointer&rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
||||||
pointers are concerned.</p>
|
pointers are concerned.</p>
|
||||||
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
|
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
|
||||||
|
<p>TODO: introduce UB by explaining how it allows optimizations like the one above, don&rsquo;t talk in standardese</p>
|
||||||
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
||||||
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
||||||
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
||||||
|
|
@ -104,11 +105,10 @@ note: inside `main` at src/main.rs:12:5
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There&rsquo;s a lot of information here.</p>
|
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There&rsquo;s a lot of information here.</p>
|
||||||
<p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
<p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
||||||
borrow stack. This is something about stacked borrows, the experimental memory model for Rust that is implemented
|
borrow stack of the byte that was accessed. This is something about stacked borrows, the experimental memory model for Rust
|
||||||
in Miri. For an excellent introduction, see this part of the great book <a href="https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html">Learning Rust With Entirely Too Many Linked Lists</a>.</p>
|
that is implemented in Miri. For an excellent introduction, see this part of the great book <a href="https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html">Learning Rust With Entirely Too Many Linked Lists</a>.</p>
|
||||||
<p>In short: each pointer has a unique tag attacked to it. Bytes in memory have a stack of such tags, and only the pointers
|
<p>In short: each pointer has a unique tag attached to it. Each byte in memory has its own &lsquo;borrow stack&rsquo; of these tags,
|
||||||
that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various
|
and only the pointers that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various operations, for example borrowing.</p>
|
||||||
operations, for example borrowing.</p>
|
|
||||||
<p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
<p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
||||||
coerced into a raw pointer) from our box, it got a new tag called <code>&lt;3314&gt;</code>. Then, when we moved the box into the function,
|
coerced into a raw pointer) from our box, it got a new tag called <code>&lt;3314&gt;</code>. Then, when we moved the box into the function,
|
||||||
something happened: The tag was invalidated and popped off the borrow stack. That&rsquo;s because box invalidates all tags when it&rsquo;s
|
something happened: The tag was invalidated and popped off the borrow stack. That&rsquo;s because box invalidates all tags when it&rsquo;s
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ belong to the arcane circles of the select few who were aware of it. So lots of
|
||||||
RAII pointer&rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
RAII pointer&rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
||||||
pointers are concerned.</p>
|
pointers are concerned.</p>
|
||||||
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
|
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
|
||||||
|
<p>TODO: introduce UB by explaining how it allows optimizations like the one above, don&rsquo;t talk in standardese</p>
|
||||||
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
||||||
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
||||||
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
||||||
|
|
@ -104,11 +105,10 @@ note: inside `main` at src/main.rs:12:5
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There&rsquo;s a lot of information here.</p>
|
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There&rsquo;s a lot of information here.</p>
|
||||||
<p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
<p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
||||||
borrow stack. This is something about stacked borrows, the experimental memory model for Rust that is implemented
|
borrow stack of the byte that was accessed. This is something about stacked borrows, the experimental memory model for Rust
|
||||||
in Miri. For an excellent introduction, see this part of the great book <a href="https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html">Learning Rust With Entirely Too Many Linked Lists</a>.</p>
|
that is implemented in Miri. For an excellent introduction, see this part of the great book <a href="https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html">Learning Rust With Entirely Too Many Linked Lists</a>.</p>
|
||||||
<p>In short: each pointer has a unique tag attacked to it. Bytes in memory have a stack of such tags, and only the pointers
|
<p>In short: each pointer has a unique tag attached to it. Each byte in memory has its own &lsquo;borrow stack&rsquo; of these tags,
|
||||||
that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various
|
and only the pointers that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various operations, for example borrowing.</p>
|
||||||
operations, for example borrowing.</p>
|
|
||||||
<p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
<p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
||||||
coerced into a raw pointer) from our box, it got a new tag called <code>&lt;3314&gt;</code>. Then, when we moved the box into the function,
|
coerced into a raw pointer) from our box, it got a new tag called <code>&lt;3314&gt;</code>. Then, when we moved the box into the function,
|
||||||
something happened: The tag was invalidated and popped off the borrow stack. That&rsquo;s because box invalidates all tags when it&rsquo;s
|
something happened: The tag was invalidated and popped off the borrow stack. That&rsquo;s because box invalidates all tags when it&rsquo;s
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ belong to the arcane circles of the select few who were aware of it. So lots of
|
||||||
RAII pointer&rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
RAII pointer&rdquo; (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
|
||||||
pointers are concerned.</p>
|
pointers are concerned.</p>
|
||||||
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
|
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
|
||||||
|
<p>TODO: introduce UB by explaining how it allows optimizations like the one above, don&rsquo;t talk in standardese</p>
|
||||||
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefined behaviour.
|
||||||
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
Undefined behaviour, UB for short, is behaviour of a program upon which no restrictions are imposed. If UB is executed,
|
||||||
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
<em>anything</em> can happen, including segmentation faults, silent memory corruption, leakage of private keys or exactly
|
||||||
|
|
@ -104,11 +105,10 @@ note: inside `main` at src/main.rs:12:5
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There&rsquo;s a lot of information here.</p>
|
</code></pre><p>This behaviour does indeed not look very defined at all. But what went wrong? There&rsquo;s a lot of information here.</p>
|
||||||
<p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
<p>First of all, it says that we attempted a read access, and that this access failed because the tag does not exist in the
|
||||||
borrow stack. This is something about stacked borrows, the experimental memory model for Rust that is implemented
|
borrow stack of the byte that was accessed. This is something about stacked borrows, the experimental memory model for Rust
|
||||||
in Miri. For an excellent introduction, see this part of the great book <a href="https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html">Learning Rust With Entirely Too Many Linked Lists</a>.</p>
|
that is implemented in Miri. For an excellent introduction, see this part of the great book <a href="https://rust-unofficial.github.io/too-many-lists/fifth-stacked-borrows.html">Learning Rust With Entirely Too Many Linked Lists</a>.</p>
|
||||||
<p>In short: each pointer has a unique tag attacked to it. Bytes in memory have a stack of such tags, and only the pointers
|
<p>In short: each pointer has a unique tag attached to it. Each byte in memory has its own &lsquo;borrow stack&rsquo; of these tags,
|
||||||
that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various
|
and only the pointers that have their tag in the stack are allowed to access it. Tags can be pushed and popped from the stack through various operations, for example borrowing.</p>
|
||||||
operations, for example borrowing.</p>
|
|
||||||
<p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
<p>In the code example above, we get a nice little hint where the tag was created. When we created a reference (that was then
|
||||||
coerced into a raw pointer) from our box, it got a new tag called <code>&lt;3314&gt;</code>. Then, when we moved the box into the function,
|
coerced into a raw pointer) from our box, it got a new tag called <code>&lt;3314&gt;</code>. Then, when we moved the box into the function,
|
||||||
something happened: The tag was invalidated and popped off the borrow stack. That&rsquo;s because box invalidates all tags when it&rsquo;s
|
something happened: The tag was invalidated and popped off the borrow stack. That&rsquo;s because box invalidates all tags when it&rsquo;s
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue