rust 中看似非常简单操作,竟然导致段错误

查看 44|回复 3
作者:bli22ard   
环境
windows wsl
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS
arch x86_64
rust version
stable-x86_64-unknown-linux-gnu (default)
rustc 1.83.0 (90b35a623 2024-11-26)
Cargo.toml
[package]
name = "demo"
version = "0.1.0"
edition = "2021"
[dependencies]
reqwest = {version = "0.11",default-features = false,features = ["rustls-tls"]}
tokio = {version = "1.42",features = ["full"]}
复现方法
main.rs
#[tokio::main]
async fn main() {
    let mut tasks=vec![];
    for _i in 0..2{
        let t=tokio::spawn(async move {
            let result=reqwest::get("https://github.com").await;
            if let Ok(result) = result {
                println!("{:?}",result.status());
            }
        });
        tasks.push(t);
    }
    for t in tasks {
        t.await.expect("Something went wrong");
    }
}
```bash
root@computer1:/demo/# RUSTFLAGS="-Ctarget-feature=+crt-static" cargo run --target x86_64-unknown-linux-gnu
root@computer1:/demo/# Segmentation fault
原因
在开启静态链接情况下,该代码会导致段错误。具体导致的原因
hyper#2537
主要是因为"github.com:443".to_socket_addrs(); 并发会导致段错误。
main.rs 这个代码也可以出发这个段错误
use std::net::ToSocketAddrs;
#[tokio::main]
async fn main() {
    let mut tasks=vec![];
    for _i in 0..2{
        let t=tokio::spawn(async move {
            // let result=reqwest::get("https://github.com").await;
            // if let Ok(result) = result {
            //     println!("{:?}",result.status());
            // }
            "github.com:443".to_socket_addrs();
        });
        tasks.push(t);
    }
    for t in tasks {
        t.await.expect("Something went wrong");
    }
}
更底层的原因是,这位老哥的说的getaddrinfo
个人看法
这意味着你要静态链接,http 或者其他什么涉及到主机名转换并发调用了 getaddrinfo 就会大概率会出现段错误,进程就会直接没了。rust 的静态链接和交叉编译,太菜鸡了😂。
如果你不使用静态链接,而使用动态链接,那么你最好保证你的开发机器软件包版本和你生产环境的软件版本保持一致,不然动态链接 openssl ,在生成看起来已经安装了 openssl ,但是提示找不到😮‍💨。静态链接这一点,golang👍️践踏 rust👎️
aloxaf   
issue 里和 stackoverflow 里不都说了么,glibc 压根不支持静态链接,尤其是 gethostbyname 。
想静态链接就用 musl ,ssl 切换到 rustls 。
dilfish   
这个问题我遇到过,你想静态编译 redis 也会警告。
go 是自己写了一套,rust 也有对应的库,
wolfsun   
同意楼上,楼主非要踩一捧一,在智商这一点,狗👍️践踏楼主👎️
您需要登录后才可以回帖 登录 | 立即注册

返回顶部