rust 中看似非常简单操作,竟然导致段错误 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
bli22ard
V2EX    程序员

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

  •  
  •   bli22ard 355 天前 3551 次点击
    这是一个创建于 355 天前的主题,其中的信息可能已经有所发展或是发生改变。

    环境

    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

    18 条回复    2024-12-17 09:34:25 +08:00
    aloxaf
        1
    aloxaf  
       355 天前
    issue 里和 stackoverflow 里不都说了么,glibc 压根不支持静态链接,尤其是 gethostbyname 。

    想静态链接就用 musl ,ssl 切换到 rustls 。
    dilfish
        2
    dilfish  
       355 天前 via Android
    这个问题我遇到过,你想静态编译 redis 也会警告。

    go 是自己写了一套,rust 也有对应的库,
    wolfsun
        3
    wolfsun  
       355 天前   9
    同意楼上,楼主非要踩一捧一,在智商这一点,狗践踏楼主
    virusdefender
        4
    virusdefender  
       355 天前
    glibc 根本不能静态链接,有些里面的函数你用到的时候还会动态寻找其他的 so ,比如一些密码类的
    hingle
        5
    hingle  
       355 天前
    OP 就是专门踩 rust 捧 go 的。https://v2ex.com/t/1090526
    bli22ard
        6
    bli22ard  
    OP
       355 天前
    @aloxaf
    我测试了一下,musl 静态链接这个代码确实没有问题。linux 静态链接还是得 musl 。
    @dilfish 下次可以试试 musl 静态链接


    @virusdefender 看来 glibc 确实是不能静态链接。即使静态链接编译成功也是假象,段错误在运行时等着。
    bli22ard
        7
    bli22ard  
    OP
       355 天前
    @wolfsun 上来就开喷,不进行一下准备工作吗?比如列一丁点事实?
    bli22ard
        8
    bli22ard  
    OP
       355 天前
    @hingle 列的都是客观事实
    adoal
        9
    adoal  
       355 天前   1
    glibc 大毒瘤
    dogfeet
        10
    dogfeet  
       355 天前
    我都是:

    不使用 native-tls ,专用 rustls
    使用 cargo zigbuild ,还可以指定 glibc 版本,挺无脑的,没你说的那么费劲。
    dogfeet
        11
    dogfeet  
       355 天前
    对了,刚忘说了,我是直接在 windows 上交叉编译 linux 的。安装下 ziglang 和 zigbuild 就行了。
    没觉得比 Golang 麻烦在哪里。
    kagenomirai
        12
    kagenomirai      355 天前
    OP 说的也不算事实。链接不是 rust 的责任。你换了 C C++ 或者 D 你都得链接一个 libc ,除非你不调系统的 api 或者有一层 vm 的包装。而 glibc 众所周知是不可以静态链接的。rust 这类系统级编程语言是不可能脱离 c 的 api ,顶多帮你做一些 dirty work ,到头来免不了做系统层面上的兼容。所有 OP 拿 go 和 rust 比就好像拿 lua 和 c 比一样,都不是同一个类语言,在设计上解决的问题也不同。
    归根结底,比较两个(针对某一问题设计的)语言根本没有意义。比较锤子和螺丝刀有意义吗?
    bli22ard
        13
    bli22ard  
    OP
       355 天前
    @adoal 感觉有点道理


    @dogfeet cargo zigbuild 没试过,我是用 https://github.com/cross-rs/cross 交叉编译。zigbuild 不静态链接,到运行的机器容易提示找不到对应 so 吧?静态链接,最佳实战应该就是 musl 了。



    @kagenomirai
    glibc 众所周知是不可以静态链接的,这个我见识短,之前不知道。
    和 lua 比不合适,lua 需要依赖解释器。rust 和 golang 编译输出都是可执行程序,所以它们比较有可比性。编译和链接这块 golang 难道不比 rust 方便? go buid 指定 os 和 arch ,就可以了。
    dogfeet
        14
    dogfeet  
       355 天前
    @bli22ard 是的,想要不依赖 glibc 就用 musl ,想要不依赖 openssl ,就是用 rustls 。
    至于要方便的交叉编译,直接使用 cargo zigbuild 就行。

    大致就是这么简单。
    dogfeet
        15
    dogfeet  
       355 天前
    @dogfeet 我一般还是用 glibc ,但是不用 native-tls(openssl)。虽然很多人说 musl 性能较 musl 差,但其实我并不在乎这个,只是没觉得 glibc 问题有那么严重。毕竟这玩意和内核关系紧密,不像 openssl 。
    在加上 zigbuild 能很方便的指定 glibc 的版本,没觉得这个有啥麻烦的地方。所以继续 glibc
    bli22ard
        16
    bli22ard  
    OP
       355 天前
    @dogfeet zigbuild 我试了下,使用 rustls , 指定低版本的 glibc ,比如 2.22 ,那大多数服务器都可以兼容,不知道这样做有没有什么坏处
    capric
        17
    capric  
       354 天前   2
    建议用 https://github.com/rust-cross/cargo-zigbuild 或者 https://github.com/cross-rs/cross 静态链接 musl ,不要静态链接 glibc ,可以动态链接 2012 年的 glibc2.17 ,就可以在主流相同指令集的 linux 上跑起来,比如 cargo zigbuild --target aarch64-unknown-linux-gnu.2.17
    bli22ard
        18
    bli22ard  
    OP
       349 天前
    > 建议用 https://github.com/rust-cross/cargo-zigbuild 或者 https://github.com/cross-rs/cross 静态链接 musl ,不要静> 态链接 glibc ,可以动态链接 2012 年的 glibc2.17 ,就可以在主流相同指令集的 linux 上跑起来,比如 cargo zigbuild > --target aarch64-unknown-linux-gnu.2.17


    @capric rust 编译最佳实战
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3489 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 10:41 PVG 18:41 LAX 02:41 JFK 05:41
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86