Rust: Getting Started
Reference
- Documentation:
Hello World
1 | fn main(){ |
- Run:
rustc <file.rs>
- Debug:
rust-gdb
- Unmangle:
rustfilt
1 | strace -f -e trace=file -o log.txt rustc hello.rs |
What is this?
/home/ethanol/.rustup/toolchains/
Macro in C++?
Abstract syntax tree?
fdump-tree-all-graph
Dumping pre-compile stuff
- Documentation: https://doc.rust-lang.org/rustc/command-line-arguments.html#--emit-specifies-the-types-of-output-files-to-generate
1
rustc --emit=dep-info,llvm-ir,asm hello.rs
- Documentation: https://doc.rust-lang.org/rustc/command-line-arguments.html#--emit-specifies-the-types-of-output-files-to-generate
cargo-expand
1
2
3
4
5
6
7
8
9
10#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
{
::std::io::_print(format_args!("Hello, world!\n"));
};
}
Note
- You can’t use unstable features with stable/beta
rustc
. You need a nightly build for that. - Bound checking?
Integer overflow
When you’re compiling in release mode with the --release
flag, Rust does not include checks for integer overflow that cause panics. Instead, if overflow occurs, Rust performs two’s complement wrapping. In short, values greater than the maximum value the type can hold “wrap around” to the minimum of the values the type can hold. In the case of a u8
, the value 256 becomes 0, the value 257 becomes 1, and so on.
- Wrap in all modes with the
wrapping_*
methods, such aswrapping_add
. - Return the
None
value if there is overflow with thechecked_*
methods. - Return the value and a boolean indicating whether there was overflow with the
overflowing_*
methods. - Saturate at the value’s minimum or maximum values with the
saturating_*
methods.
Crypto —> Wrap
Computer graphics —> SaturateDebugging
1
2
3
4
5
6
7
8
9
10rust-gdb
rustfilt <- unmangling
cargo install cargo-expand
cargo expand
file <binary>
hexdump -C
objdump -x
strace -f -e trace=file -o log.txt rustc hello.rsQuestions
Q: What is Result<T, BmpError>
and what is enum?
1 | pub type BmpResult<T> = Result<T, BmpError>; |
A: Result is an enum, and enums are like unions in C/C++, but a bit smarter.
https://doc.rust-lang.org/std/result/
https://doc.rust-lang.org/src/core/result.rs.html#502
Q: What is trait
1 | pub trait Debug { |
Q: The mechanism of the conversion from integer 64 to a string
1 | ::core::fmt::Formatter::debug_tuple_field1_finish(f, "A", &__self_0) |
Q: println formatting
fmt::Debug
: Uses the{:?}
marker. Format text for debugging purposes.fmt::Display
: Uses the{}
marker. Format text in a more elegant, user friendly fashion.
Q: writeln formatting
Q: macro syntax in Rust
Q: Lifetime annotation
Stuff
#[this is an attribute]
OuterAttribute vs InnerAttribute
- Placement: Inner attributes are placed inside the item and use #![…], while outer attributes are placed outside (above) the item and use #[…].
- Scope: Inner attributes typically apply to the module or crate they are placed in, while outer attributes apply to the item they precede.
- Usage: Outer attributes are more commonly used for deriving traits, enabling compiler lints, and other item-level metadata, while inner attributes are often used for crate-level configuration or module-level settings.
Variadic functions vs macro in Rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16macro_rules! sum {
($($num:expr),*) => {
{
let mut total = 0;
$(
total += $num;
)*
total
}
};
}
fn main() {
let result = sum!(1,2,3,4,5);
println!("The sum is: {}", result);
}Basically for Result the
.unwrap()
is the same as.expect("ERROR MESSAGE")
with the exception of the error message.And the
asdf()?
mean “ifasdf()
returns Result or Option, and current function also does so, the return from this function in case of an error passing the Result/Option further along”The question mark operator (
?
) can only be used in a function that returnsResult
orOption
.1
2
3
4
5
6
7
8fn main() {
let x: i32 = "12".parse()?; // Error because main function does not return Return or Option
}
fn parse_int() -> Result<i32, ParseIntError> {
let x: i32 = "12".parse()?; // x = 12
let y: i32 = "12a".parse()?; // return Err() immediatly ---> Not error
}Tuple syntax
1
2let x: (i32, f64, u8) = (500, 6.4, 1);
let asdf = x.2;Command
Cargo expand is doing basically
gcc -E
1
2cargo install cargo-expand
cargo expand
Implement linked-list is nightmare
1 | https://github.com/aodr3w/double-rs/blob/main/src/doubly.rs |
- Ownership
- Smart pointer
- Trait
- Fearless concurrency
It’s time to read Rust book…
Some fun
- In Java, Slice -> Ref Count += 1 -> No use -> but still reference -> GC cannot collect
- In python -> slice copy
Computer Systems Practical - Part 4: Data Sections
Diary 2021 - 2022
Computer Systems Practical - Part 3: Dynamic Linking
Abstract
A shared library, also know as a shareable object files, can be loaded by a dynamic linker to any memory address during the loading or runtime, and linked to a program in memory.
- The link process can be carried out during the loading period or run time. Therefore, after the shared library is updated, it is not necessary to do the static library, and the executable object file must be explicitly relinked.
- Save disk space. The code and data of the shared library are shared by all executable object files that refer to the shared library.
- Save memory space. A copy of the code of the shared library in memory is shared by all processes the refer to the shared library.
Computer Systems Practical - Part 2.3: Static Linking
Updating…
Computer Systems Practical - Part 2.2: Static Linking
Updating…
Computer Systems Practical - Part 2.1: Static Linking
Updating…
Code Debugging with GDB - part 4: Basic Debug Glibc Source Code
Abstract
This article describes the preparations needed to debug glibc source code, including: how to install the glibc shared library with debugging information, how to get the glibc source code that matches the system, how to use the glibc source code in gdb, and through a simple Examples show this process.