面临意外的“未对齐指针取消引用:地址必须是 0x8 的倍数,但为 0x__”错误

Dhr*_*ali 3 pointers rust

我正在尝试使用库users[ Docs.rs ] [ GitHub ]。

当我在 macOS 上尝试获取用户号 5(即“操作员”)的详细信息时,使用以下代码...

use users::get_group_by_gid;

fn main() {
    let group = get_group_by_gid(5).unwrap();
    println!("{:?}", group.name());
}
Run Code Online (Sandbox Code Playgroud)

...我收到意外错误:

thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x8 but is 0x14400880b', /Users/dhruvkb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/users-0.11.0/src/base.rs:297:34
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'panic in a function that cannot unwind', library/core/src/panicking.rs:126:5
stack backtrace:
   0:        0x104fe684c - std::backtrace_rs::backtrace::libunwind::trace::h0a647ce7e8dc2fab
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:        0x104fe684c - std::backtrace_rs::backtrace::trace_unsynchronized::hea920694a2a8ac80
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x104fe684c - std::sys_common::backtrace::_print_fmt::h7b4e20c1da2ebb61
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/sys_common/backtrace.rs:65:5
   3:        0x104fe684c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h819e9cbdf1a9e730
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/sys_common/backtrace.rs:44:22
   4:        0x104ff80e0 - core::fmt::write::ha5e9bf3131ecb7c0
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/fmt/mod.rs:1254:17
   5:        0x104fe46b0 - std::io::Write::write_fmt::h414ce9994bf17404
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/io/mod.rs:1698:15
   6:        0x104fe6660 - std::sys_common::backtrace::_print::h28d98f2094da6d1d
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/sys_common/backtrace.rs:47:5
   7:        0x104fe6660 - std::sys_common::backtrace::print::h8072db0bbd5bcc3d
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/sys_common/backtrace.rs:34:9
   8:        0x104fe7b80 - std::panicking::default_hook::{{closure}}::h2c85c5b0c2ede151
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:269:22
   9:        0x104fe7940 - std::panicking::default_hook::hcf2f70992d02f6fe
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:288:9
  10:        0x104fe8058 - std::panicking::rust_panic_with_hook::h023af7f90b47eb8b
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:691:13
  11:        0x104fe7f4c - std::panicking::begin_panic_handler::{{closure}}::h14283519edc1d634
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:580:13
  12:        0x104fe6c6c - std::sys_common::backtrace::__rust_end_short_backtrace::hc366c0b0cef5b747
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/sys_common/backtrace.rs:150:18
  13:        0x104fe7d20 - rust_begin_unwind
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:578:5
  14:        0x104fff6b8 - core::panicking::panic_nounwind_fmt::h48fca0782e5a5b33
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/panicking.rs:96:14
  15:        0x104fff734 - core::panicking::panic_nounwind::hc8dbc36c10163a33
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/panicking.rs:126:5
  16:        0x104fff82c - core::panicking::panic_cannot_unwind::h8bbe98643cda7e5c
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/panicking.rs:188:5
  17:        0x104fca054 - users::base::members::h897f0606a81fa18e
                               at /Users/dhruvkb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/users-0.11.0/src/base.rs:291:1
  18:        0x104fc9bb0 - users::base::os::unix::GroupExtras::from_struct::hdb1f84273e3fef19
                               at /Users/dhruvkb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/users-0.11.0/src/base.rs:1060:33
  19:        0x104fc9e44 - users::base::struct_to_group::h968dc5b5260e3ea2
                               at /Users/dhruvkb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/users-0.11.0/src/base.rs:280:19
  20:        0x104fca3bc - users::base::get_group_by_gid::hbcac997dd823548f
                               at /Users/dhruvkb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/users-0.11.0/src/base.rs:473:26
  21:        0x104fc875c - ug::main::h9b6b146ea9ce450b
                               at /Users/dhruvkb/Developer/personal/test/ug/src/main.rs:4:17
  22:        0x104fc8908 - core::ops::function::FnOnce::call_once::h7e6c46cf308f75b9
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/ops/function.rs:250:5
  23:        0x104fc8874 - std::sys_common::backtrace::__rust_begin_short_backtrace::h1d5bc4a1fd871dea
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/sys_common/backtrace.rs:134:18
  24:        0x104fc89ac - std::rt::lang_start::{{closure}}::hd278346b68dd1f23
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/rt.rs:166:18
  25:        0x104fe2408 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h6f7eb9f266759f90
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/ops/function.rs:287:13
  26:        0x104fe2408 - std::panicking::try::do_call::h54b2febb9ea02379
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:485:40
  27:        0x104fe2408 - std::panicking::try::h95a2f9f45aeb75ea
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:449:19
  28:        0x104fe2408 - std::panic::catch_unwind::h9686256fa0fc97a1
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panic.rs:140:14
  29:        0x104fe2408 - std::rt::lang_start_internal::{{closure}}::h227e8b10bc4e486b
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/rt.rs:148:48
  30:        0x104fe2408 - std::panicking::try::do_call::h414d500a3ee5fa44
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:485:40
  31:        0x104fe2408 - std::panicking::try::h4f025820961f1c3f
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panicking.rs:449:19
  32:        0x104fe2408 - std::panic::catch_unwind::h0b71dfe3538d125d
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/panic.rs:140:14
  33:        0x104fe2408 - std::rt::lang_start_internal::h8ee16b8f6c950a26
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/rt.rs:148:20
  34:        0x104fc8978 - std::rt::lang_start::hb3f96d07eed31802
                               at /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/std/src/rt.rs:165:17
  35:        0x104fc8854 - _main
thread caused non-unwinding panic. aborting.
[1]    12348 abort      cargo run
Run Code Online (Sandbox Code Playgroud)

此错误是意外的,因为它适用于其他组 ID,例如 0(即“root”)或 20(即“staff”)。

这发生在我的应用程序中,所以我创建了一个绿地项目,没有其他依赖项,除了users它也发生在那里。我知道,一个流行的 CLI 应用程序使用这个库,所以我克隆了它的存储库,并从我的to函数exa中添加了相同的行。main()examain()

它在那里工作,这更令人困惑。

exa的main函数中添加了代码

exa 打印“operator”,这意味着它可以工作

Cha*_*man 7

group.gr_memlibc返回的列表中的某些指针getgrgid_r()未对齐。这可能是 C 库或文档中的错误,但可能不是 Rust 库中的错误,因为我在文档中没有找到任何相关内容。这会导致UB,这意味着编译器可以为所欲为。以前,“无论它想要什么”几乎都会忽略它(减去应用利用这一事实的优化)。从最新的 Rust 版本 (1.70.0) 开始,编译器开始通过检查调试版本中未对齐的指针来帮助防止 UB。这导致您的代码崩溃。如果您愿意,您可以静默此检查。这不会解决 UB 的实际问题,但至少不会使您的程序崩溃,并且您可以希望编译器不会应用任何优化,这些优化会突然以难以预料的方式破坏您的代码。

通过禁用调试断言来静默此检查。在您的 Cargo.toml 中:

[profile.dev]
debug-assertions = false
Run Code Online (Sandbox Code Playgroud)

这不是一个好主意。这甚至不是一个坏主意。这是一个糟糕的主意。这会禁用所有调试断言,甚至是不相关的断言,并且只是使 UB 保持沉默,而没有实际解决它。但这可能是您能得到的最好的。

更好的选择是修补依赖项以避免 UB。修补users依赖项src/base.rs并替换第 291-306 行(整个函数)的代码members()

unsafe fn members(groups: *mut *mut c_char) -> Vec<OsString> {
    let mut members = Vec::new();

    for i in 0.. {
        let username = groups.offset(i);

        if username.is_null() || (*username).is_null() {
            break;
        }
        else {
            members.push(from_raw_buf(*username));
        }
    }

    members
}
Run Code Online (Sandbox Code Playgroud)

到:

unsafe fn members(groups: *mut *mut c_char) -> Vec<OsString> {
    let mut members = Vec::new();

    for i in 0.. {
        let username = groups.offset(i);

        if username.is_null() || username.read_unaligned().is_null() {
            break;
        }
        else {
            members.push(from_raw_buf(username.read_unaligned()));
        }
    }

    members
}
Run Code Online (Sandbox Code Playgroud)

您可能想发送 PR,但我不知道这是否是操作系统或文档中的错误,因此我不知道是否应该在 Rust 库中修复此问题。