-- Leo's gemini proxy

-- Connecting to gmi.noulin.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

Trying rust


Feed


date: 2022-08-29 07:40:23


categories: programming


firstPublishDate: 2021-02-20 15:36:20


Rust is not easy to learn for beginner programmers. I suggest beginner programers start learning python or javascript then C and then rust. Learning C helps understanding the kind of issues that are detected by the rust compiler. There are tools for C for detecting the memory issues but they run in the tests (CI) but they don't detect all issues. Rust shows the issues earlier at compile time when the program is under development.


I think getting issues at compile time saves development time.


I checked which SEI CERT C rules apply for Rust.

SEI CERT C rules


The following rules apply:


INT30-C. Ensure that unsigned integer operations do not wrap

INT32-C. Ensure that operations on signed integers do not result in overflow


In debug mode, it panics. A fix for this is to use the SEI CERT C compliant solution. I found some discussion around this:

RFC discussion


PR


To explicitly handle the possibility of overflow, you can use these families of methods provided by the standard library for primitive numeric types:


Wrap in all modes with the wrapping_* methods, such as wrapping_add


Return the None value if there is overflow with the checked_* 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 saturating_* methods


INT33-C. Ensure that division and remainder operations do not result in divide-by-zero errors


INT35-C. Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand


When INT35 is violated, it panics.


ARR30-C. Do not form or use out-of-bounds pointers or array subscripts

ARR32-C. Ensure size arguments for variable length arrays are in a valid range


When out-of-bounds accesses are done on static arrays or vectors, it panics.


FIO32-C. Do not perform operations on devices that are only appropriate for files

FIO39-C. Do not alternately input and output from a stream without an intervening flush or positioning call

FIO45-C. Avoid TOCTOU race conditions while accessing files

ENV33-C. Do not call system()


In rust, system() is: std::process::Command, it is vulnerable when the path to the command is incorrectly specified.


SIG* -- not checked

MSC32-C. Properly seed pseudorandom number generators

MSC41-C. Never hard code sensitive information

POS35-C. Avoid race conditions while checking for the existence of a symbolic link (TOCTOU)

POS36-C. Observe correct revocation order while relinquishing privileges

POS37-C. Ensure that privilege relinquishment is successful

POS38-C. Beware of race conditions when using fork and file descriptors

POS39-C. Use the correct byte ordering when transferring data between systems


The following rules don't apply:


PRE* - there is no string based preprocessor

DCL*

DCL30-C. Declare objects with appropriate storage durations

DCL31-C. Declare identifiers before using them

DCL36-C. Do not declare an identifier with conflicting linkage classifications

DCL37-C. Do not declare or define a reserved identifier

DCL38-C. Use the correct syntax when declaring a flexible array member

DCL39-C. Avoid information leakage when passing a structure across a trust boundary

DCL40-C. Do not create incompatible declarations of the same function or object

DCL41-C. Do not declare variables inside a switch statement before the first case label

EXP*

EXP30-C. Do not depend on the order of evaluation for side effects

EXP32-C. Do not access a volatile object through a nonvolatile reference

EXP33-C. Do not read uninitialized memory

EXP34-C. Do not dereference null pointers

EXP35-C. Do not modify objects with temporary lifetime

EXP36-C. Do not cast pointers into more strictly aligned pointer types

EXP37-C. Call functions with the correct number and type of arguments

EXP39-C. Do not access a variable through a pointer of an incompatible type

EXP40-C. Do not modify constant objects

EXP42-C. Do not compare padding data

EXP43-C. Avoid undefined behavior when using restrict-qualified pointers

EXP44-C. Do not rely on side effects in operands to sizeof, _Alignof, or _Generic

EXP45-C. Do not perform assignments in selection statements

EXP46-C. Do not use a bitwise operator with a Boolean-like operand

EXP47-C. Do not call va_arg with an argument of the incorrect type

INT31-C. Ensure that integer conversions do not result in lost or misinterpreted data

INT35-C. Use correct integer precisions

INT36-C. Converting a pointer to integer or integer to pointer

FLP30-C. Do not use floating-point variables as loop counters

FLP32-C. Prevent or detect domain and range errors in math functions


The result is NaN.


FLP34-C. Ensure that floating-point conversions are within range of the new type

FLP36-C. Preserve precision when converting integral values to floating-point type

FLP37-C. Do not use object representations to compare floating-point values

ARR36-C. Do not subtract or compare two pointers that do not refer to the same array

ARR37-C. Do not add or subtract an integer to a pointer to a non-array object

ARR38-C. Guarantee that library functions do not form invalid pointers

ARR39-C. Do not add or subtract a scaled integer to a pointer

STR30-C. Do not attempt to modify string literals

STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator

STR32-C. Do not pass a non-null-terminated character sequence to a library function that expects a string

STR34-C. Cast characters to unsigned char before converting to larger integer sizes

STR37-C. Arguments to character-handling functions must be representable as an unsigned char

STR38-C. Do not confuse narrow and wide character strings and functions

MEM-*

MEM30-C. Do not access freed memory

MEM31-C. Free dynamically allocated memory when no longer needed

MEM33-C. Allocate and copy structures containing a flexible array member dynamically

MEM34-C. Only free memory allocated dynamically

MEM35-C. Allocate sufficient memory for an object

MEM36-C. Do not modify the alignment of objects by calling realloc()

FIO30-C. Exclude user input from format strings

FIO34-C. Distinguish between characters read from a file and EOF or WEOF

FIO37-C. Do not assume that fgets() or fgetws() returns a nonempty string when successful

FIO38-C. Do not copy a FILE object

FIO40-C. Reset strings on fgets() or fgetws() failure

FIO41-C. Do not call getc(), putc(), getwc(), or putwc() with a stream argument that has side effects

FIO42-C. Close files when they are no longer needed

FIO44-C. Only use values for fsetpos() that are returned from fgetpos()

FIO46-C. Do not access a closed file

FIO47-C. Use valid format strings

ENV30-C. Do not modify the object referenced by the return value of certain functions

ENV31-C. Do not rely on an environment pointer following an operation that may invalidate it

ENV32-C. All exit handlers must return normally

ENV34-C. Do not store pointers returned by certain functions

ERR*

ERR30-C. Take care when reading errno

ERR32-C. Do not rely on indeterminate values of errno

ERR33-C. Detect and handle standard library errors

ERR34-C. Detect errors when converting a string to a number

CON* -- not checked

MSC30-C. Do not use the rand() function for generating pseudorandom numbers

MSC33-C. Do not pass invalid data to the asctime() function

MSC37-C. Ensure that control never reaches the end of a non-void function

MSC38-C. Do not treat a predefined identifier as an object if it might only be implemented as a macro

MSC39-C. Do not call va_arg() on a va_list that has an indeterminate value

MSC40-C. Do not violate constraints

POS30-C. Use the readlink() function properly

POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument

POS44-C. Do not use signals to terminate threads

POS47-C. Do not use threads that can be canceled asynchronously

POS48-C. Do not unlock or destroy another POSIX thread's mutex

POS49-C. When data must be accessed by multiple threads, provide a mutex and guarantee no adjacent data is also accessed

POS50-C. Declare objects shared between POSIX threads with appropriate storage durations

POS51-C. Avoid deadlock with POSIX threads by locking in predefined order

POS52-C. Do not perform operations that can block while holding a POSIX lock

POS53-C. Do not use more than one mutex for concurrent waiting operations on a condition variable

POS54-C. Detect and handle POSIX library errors


Rust supports multiple program styles in a good way: imperative, object oriented, functional programming.


Rust is not stable and still evolving, for example last year printing variables in format strings was added `println!("{var}");` but printing a struct member is not supported and under discussion:

allow arbitrary expressions in format string


// Code:
      struct D<'a> { s: &'a str }$
      let s = D { s : "ad"};$
      println!("{}", s.s);$
.     println!("{s.s}"); // Doesn't compile

error: invalid format string: expected `'}'`, found `'.'`
  --> src/main.rs:11:17
   |
11 |     println!("{s.s}");
   |               - ^ expected `}` in format string
   |               |
   |               because of this opening brace
   |
   = note: if you intended to print `{`, you can escape it using `{{`

error: could not compile `minigrep` due to previous error

Most changes are additions so current code is likely to compile with future compiler versions. There is a tool (cargo fix) to update code to newer version of rust.


Declarations can be put in any order (except macros, macros have to be written before first use), for example a struct can be used before it is declared in the same file.


When memory errors are detected, the program panics. The panics have to be handle gracefully and all unhandled panics have to be found with static analysis or dynamic testing (tests and fuzzing). The libraries have to also handle the panics gracefully.


In general, it is easier to collaborate with other developers in projects compare to C. With C, a set of rules (quite large) has to be decided: memory management, naming and style formating (clang-format), file and directory organization, testing, secure conding rules. The tooling has be chosen: build system, test library, sanitizers, static analyzers, fuzzers. With Rust, only testing rules have to be decided. Memory management is done automatically, the compiler suggest snake case and there is rust-fmt, file and directory organization is suggested by the compiler and cargo. Build system, test library, fuzzers are provided, the need for sanitizers and static analyzers is lower than for C.


In C, I use macros as closures, it is quite inconvenient to use because it is prone to mistake and can be debugged only with prints. Closures in rust are much better.


I think the Drop trait is better than having `__attribute__((cleanup(func)))` on variable declarations.


Rust warns about unused return values and unused parameters, with GNU C the attributes `__attribute__ ((warn_unused_result))` and `__attribute__ ((unused))` have to be added to each function.


Functions can return multiple values, so it is uniform and easy to separate return values from errors (with Result<> or Option<>).


There are namespaces and names can be changed locally where the object is used (use crate as myname;).


The compiler messages are helpful and directly gives solutions to compilation issues (sometime the messages are misguiding).


crates.io has only one namespace so there will be name squatters. There are crates not implemented as I want, so I create local crates and declare them with path in cargo.toml dependencies:


[dependencies]
mycrate = { path = "../mycrate"}

The documentation is good but incomplete:

The Rust Reference


The Rustonomicon


The toolchain is 1GB per version. The rust system takes a lot of disk space.


Lots rust programs claim to be blazing fast, it seems.


It did a benchmark on a program parsing a 91MB log file with about 1 million lines:


Rust Debug                 25sec
C Debug                     3.8sec
Rust -O                     1.48sec (13 million allocations)
C -O3                       2.2sec (31 million allocations)
C -O3 with less allocations 0.5sec (1 million allocations)

Rust debug is slow and the rust optimized version is fast without optimizing the code. It is possible to get the same performance as C by reducing the allocations.


Case


Rustc issues a warning when names don't have the default case:


snake_case for (`an_example`): crate names, function names

upper camel case for (`AnExample`): struct, enum, members UpperCamel

const and static variables are in capital letters (`AN_EXAMPLE`)


Coredump


Coredump are not well supported. By default panics don't generate a coredump and panic = "abort" doesn't generate a coredump either. In Cargo.toml


[profile.release]
panic = "abort"

To generate a coredump, register a panic handler and trigger sigabrt like this:


use libc::kill;
use libc::SIGABRT;
unsafe { kill(0, SIGABRT);}

Code coverage


Code coverage is available in nightly. To setup nightly in a project, do this:


create a new project

install the nightly toolchain `rustup toolchain install nightly`

run `rustup override set nightly`

setup environment:


export RUSTFLAGS="-Zprofile"
export CARGO_INCREMENTAL=0

Then build normally with `cargo build` and for gcov coverage run:


llvm-cov-11 gcov ./target/debug/deps/nightly-6cea039c96dffc6e.gcda
vi main.rs.gcov

For llvm code coverage, run:


llvm-profdata merge -sparse default.profraw -o default.profdata
llvm-cov show -Xdemangler=rustfilt target/debug/nightly -instr-profile=default.profdata -show-line-counts-or-regions -show-instantiations

Llvm in debian bullseye doesn't support profraw format generated by rustc, so I compiled the latest llvm from source (it takes more than 10GB disk space).


Documentation


Get started


lean


The Rust Programming Language


The Rust Reference


Command Line Applications in Rust


Rust By Example


The Rustonomicon


The Rust Unstable Book


Rust Cookbook


The Rust Standard Library


The Cargo Book


Rust Design Patterns


A peer-reviewed collection of articles/talks/repos which teach concise, idiomatic Rust.


algorithms


Articles about Rust


Rust from the ground up book


Rust feature compare to C


variables are immutable by default

let can redeclare variables with identical names

variables can't be assigned in if,while,for statements. if (a = f(3))

all {} blocks are mandatory if (b) return true; is not allowed if b {true}

return can be omitted, the last statement without ; is the return value

enum are more like structs

only bool can be without compare in conditionals let b = true; if b {println!("yes");} let b = 1; if b {println!("yes");} // compile error if b = 1 {println!("yes");} // compile error

return errors are separated from return values

reference &var (pointer) and dereference *var are similar.

there are no ++ or -- operators

function definitions can be written in any order

macros have to be written before the first use

functions have fixed number of parameters

the use statements can be written anywhere in the code

modules can be renamed when they are included: use std::process as p; it is easier to avoid namespace collisions

`__FUNC__` is missing


Good ideas in rust ecosystem


documentation as comments

documentation server and generator in cargo

code styling in cargo and rustc

test runner in cargo

variable and reference to variable are identical when calling functions or accessing struct members

registry index is a git repo

when running a program for first time, `cargo run` downloads and installs the missing crates


FFI


wrapper functions in rust code are needed

types need to be converted. There is an easier solution for extern types under development.


Stability


Rust has evolved a lot last few years, most of the code snippets I find either don't compile or are wrong.


The Rust toolchain has requirements on Linux and Glibc versions, this can force users to update systems or compile the Rust toolchain to the latest version compatible with the system.


Some packages might only work with edition 2021 which is not supported by older systems, forcing a system update. Also some packages might be abandoned and may not work with available rust toolchain forcing a package upgrade and a new security review.


I wonder if the rust toolchain glibc support is aligned with Red Hat support. Rust 1.64 depends on glibc 2.17 and it is the glibc in Red Hat 7 which will go out of support in 2024. So I suppose soon the oldest supported glibc will be the one in Red Hat 8.


Minimal rust install


A minimal rust install is about 500MB (without the documentation).


PATH has to be set like this:


export PATH=/home/$USER/.cargo/bin:$PATH

And these files are needed in home:


.cargo/bin/cargo
.cargo/bin/rustfilt
.cargo/bin/rustup
.cargo/bin/rustc
.cargo/bin/rust-gdb
.cargo/bin/rust-gdbgui

.rustup/tmp
.rustup/update-hashes
.rustup/update-hashes/stable-x86_64-unknown-linux-gnu
.rustup/settings.toml
.rustup/downloads
.rustup/toolchains
.rustup/toolchains/stable-x86_64-unknown-linux-gnu
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/zsh
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/zsh/site-functions
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/zsh/site-functions/_cargo
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-run.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-report.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-metadata.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-help.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-locate-project.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-tree.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-doc.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-check.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-version.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-uninstall.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-build.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/rustc.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-install.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-package.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-vendor.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/rustdoc.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-verify-project.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-init.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-login.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-fix.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-bench.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-rustdoc.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-pkgid.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-rustc.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-owner.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-update.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-publish.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-test.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-fetch.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-add.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-new.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-clean.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-yank.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-search.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/share/man/man1/cargo-generate-lockfile.1
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/librustc_driver-d680884a73809b24.so
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/libtest-50b9616eedb811b7.so
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/libstd-8f1929c73c3f8167.so
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/libLLVM-14-rust-1.63.0-stable.so
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/components
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/rust-installer-version
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/multirust-channel-manifest.toml
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/manifest-rustfmt-preview-x86_64-unknown-linux-gnu
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/manifest-cargo-x86_64-unknown-linux-gnu
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/gdb_load_rust_pretty_printers.py
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/gdb_providers.py
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/lldb_providers.py
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/__pycache__
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/__pycache__/gdb_providers.cpython-39.pyc
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/__pycache__/rust_types.cpython-39.pyc
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/__pycache__/gdb_lookup.cpython-39.pyc
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/rust_types.py
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/lldb_commands
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/lldb_lookup.py
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/etc/gdb_lookup.py
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libproc_macro-f46062bad18d692a.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-19c77e4dc3dcb87e.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc-stable_rt.tsan.a
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-63f8356c87a0d0e8.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-fb44a42088c9369a.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-65c63cf3af0af657.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libprofiler_builtins-02287944b380ef08.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-682a81c4b2133b72.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-4a53f0a2785abc6a.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-9d7c322d48daa475.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-e359d865975ccf21.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgetopts-754da76e30d40e26.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-a506e577d917828c.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-7b5ec4c918d9f957.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-868e2d515c28d027.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc-stable_rt.msan.a
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-8f1929c73c3f8167.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libtest-50b9616eedb811b7.so
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-8f1929c73c3f8167.so
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-fc1fb63210fdafad.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-394ad2d73aede76a.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-08ae1606a951cabe.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-c21be34a5cae8449.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_abort-2ef255b89354cca0.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-b886fd10c5a7c7c0.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-a73b3512c88de071.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libtest-50b9616eedb811b7.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc-stable_rt.lsan.a
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunicode_width-abff7c50c58df25c.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_std-89f1a8c8e39f4a91.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc-stable_rt.asan.a
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-61a7402e61a5b0e0.rlib
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/rust-lld
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld/ld
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/multirust-config.toml
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/manifest-clippy-preview-x86_64-unknown-linux-gnu
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/manifest-rust-docs-x86_64-unknown-linux-gnu
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/manifest-rustc-x86_64-unknown-linux-gnu
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/manifest-rust-std-x86_64-unknown-linux-gnu
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/etc
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/etc/bash_completion.d
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/etc/bash_completion.d/cargo
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/libexec
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/libexec/cargo-credential-1password
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/cargo
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rust-gdb
.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rust-gdbgui

Post version 1


2021-02-20 15:36:20 Versions: rustc 1.50 and rustc 1.52(nightly)


Installing rust


I followed the instructions on the

install page of rust-land

and ran rustup like this:


curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

It downloaded a dozen of archives (megabytes) and installed rust in home under `~/.cargo/bin`.


Compiling rust from source


I used a Dell XPS 13 9350 and I compiled rust version 1.52, latest in the git repo with these commands:


./x.py build
./x.py install

`x.py build` took 1 hour and `/x.py install` took 1.5 hour to finish.


Code coverage


I decided to try code coverage, it is an unstable feature:


unstable compiler options are not available in the release version of rust (1.50)

when I compile with the options `-Zprofile=y` or `-Zinstrument-coverage=y`, it fails to compile


The compile error I get is:


error[E0463]: can't find crate for `profiler_builtins`
  |
  = note: the compiler may have been built without the profiler runtime

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.

To fix this error, read the instructions in the

nightly unstable documentation

.


Debugging


I compiled my code with `rustc -Cdebuginfo=2` to emit the full debug information.


I have gdb 10.0 installed on my machine and when I run `rust-gdb` it starts gdb 10.0.


To debug, I use the command (my program is called `h`):


rust-gdb -tui h

when I put a breakpoint on main, it stops in `library/std/src/rt.rs` and the function is `lang_start`, it doesn't work as expected

when I put a breakpoint on a statement in main and run, it stops on the correct line


Stability


In Rust by example, I read:


Since Rust 1.45, the `as` keyword performs a *saturating cast* when casting from float to int.

Reading the release notes, I notice there are many features that are unstable, deprecated or changing.


It means my source code needs to be tested for each new release of rust and then time needs to be spent to fix the issues.


If one decides to not fix the issues, the specific rust version for the source code has to be keep available and multiple version of rust might be needed.


Conclusion


As of today, the cost of using rust is far too high compare to the benifits it gives. The system is too unstable and the tools are not mature.


hashtags: #rust


Feed

-- Response ended

-- Page fetched on Tue May 21 14:41:39 2024