Why does reqwest::blocking::Client panic at the end of my program when used though std::thread_local

Viewed 135

I came across something similar to this in a library and it seems like it's causing Rust to panic at the very end of my program. I stripped out most of the irrelevant code, and this seems to be the minimal example needed to reproduce it.

It seems like this code pretty closely follows the documented use of std::thread_local and with. Is there some kind of destruction going on here that reqwest::blocking::Client doesn't support properly? Or is there some cleanup I'm supposed to do before exiting?

use reqwest::blocking::Client;

std::thread_local!(static CLIENT: Client = Client::new());

fn main() {
    match CLIENT.with(|c| {c.get("https://www.rust-lang.org").send()}) {
        Ok(_) => {
            println!("success!");
        },
        Err(_) => {
            println!("error!");
        }
    }
}

Here's the error I'm getting:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.15s
     Running `target\debug\example.exe`
success!
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:1245:48
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

If I avoid using thread_local and just initialize a regular local variable it works fine:

use reqwest::blocking::Client;

fn main() {
    let client: Client = Client::new();
    match client.get("https://www.rust-lang.org").send() {
        Ok(_) => {
            println!("success!");
        },
        Err(_) => {
            println!("error!");
        }
    }
}

I'm running on Windows 10 with rustc 1.49.0 (e1884a8e3 2020-12-29)

My cargo.toml has reqwest = { version = "0.10", features = ["blocking"] }

If I run with full backtrace I get the following output

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
     Running `target\debug\example.exe`
success!
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\thread\mod.rs:1245:48
stack backtrace:
   0:     0x7ff6f376f54e - std::backtrace_rs::backtrace::dbghelp::trace
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\..\..\backtrace\src\backtrace\dbghelp.rs:108
   1:     0x7ff6f376f54e - std::backtrace_rs::backtrace::trace_unsynchronized
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66
   2:     0x7ff6f376f54e - std::sys_common::backtrace::_print_fmt
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\sys_common\backtrace.rs:67
   3:     0x7ff6f376f54e - std::sys_common::backtrace::_print::{{impl}}::fmt
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\sys_common\backtrace.rs:46
   4:     0x7ff6f37844eb - core::fmt::write
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\core\src\fmt\mod.rs:1078
   5:     0x7ff6f3768d58 - std::io::Write::write_fmt<std::sys::windows::stdio::Stderr>
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\io\mod.rs:1518
   6:     0x7ff6f37720dd - std::sys_common::backtrace::_print
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\sys_common\backtrace.rs:49
   7:     0x7ff6f37720dd - std::sys_common::backtrace::print
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\sys_common\backtrace.rs:36
   8:     0x7ff6f37720dd - std::panicking::default_hook::{{closure}}
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\panicking.rs:208
   9:     0x7ff6f3771cb8 - std::panicking::default_hook
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\panicking.rs:227
  10:     0x7ff6f3772a4f - std::panicking::rust_panic_with_hook
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\panicking.rs:593
  11:     0x7ff6f3772523 - std::panicking::begin_panic_handler::{{closure}}
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\panicking.rs:497
  12:     0x7ff6f376fe8f - std::sys_common::backtrace::__rust_end_short_backtrace<closure-0,!>
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\sys_common\backtrace.rs:141
  13:     0x7ff6f37724a9 - std::panicking::begin_panic_handler
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\panicking.rs:495
  14:     0x7ff6f3782a60 - core::panicking::panic_fmt
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\core\src\panicking.rs:92
  15:     0x7ff6f37829ac - core::panicking::panic
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\core\src\panicking.rs:50
  16:     0x7ff6f363a940 - core::option::Option<core::result::Result<tuple<>, alloc::boxed::Box<Any, alloc::alloc::Global>>>::unwrap<core::result::Result<tuple<>, alloc::boxed::Box<Any, alloc::alloc::Global>>>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\option.rs:386
  17:     0x7ff6f36169bb - std::thread::JoinInner<tuple<>>::join<tuple<>>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:1245
  18:     0x7ff6f36169fb - std::thread::JoinHandle<tuple<>>::join<tuple<>>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:1373
  19:     0x7ff6f32bfac1 - reqwest::blocking::client::{{impl}}::drop::{{closure}}
                               at C:\Users\rober\.cargo\registry\src\github.com-1ecc6299db9ec823\reqwest-0.10.10\src\blocking\client.rs:752
  20:     0x7ff6f32dcde9 - core::option::Option<std::thread::JoinHandle<tuple<>>>::map<std::thread::JoinHandle<tuple<>>,core::result::Result<tuple<>, alloc::boxed::Box<Any, alloc::alloc::Global>>,closure-1>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\option.rs:453
  21:     0x7ff6f32bf8e1 - reqwest::blocking::client::{{impl}}::drop
                               at C:\Users\rober\.cargo\registry\src\github.com-1ecc6299db9ec823\reqwest-0.10.10\src\blocking\client.rs:752
  22:     0x7ff6f32d723f - core::ptr::drop_in_place<reqwest::blocking::client::InnerClientHandle>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\mod.rs:175
  23:     0x7ff6f32e4832 - alloc::sync::Arc<reqwest::blocking::client::InnerClientHandle>::drop_slow<reqwest::blocking::client::InnerClientHandle>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\sync.rs:951
  24:     0x7ff6f32e84a0 - alloc::sync::{{impl}}::drop<reqwest::blocking::client::InnerClientHandle>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\sync.rs:1471
  25:     0x7ff6f32cee8e - core::ptr::drop_in_place<alloc::sync::Arc<reqwest::blocking::client::InnerClientHandle>>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\mod.rs:175
  26:     0x7ff6f32cb1f5 - core::ptr::drop_in_place<reqwest::blocking::client::ClientHandle>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\mod.rs:175
  27:     0x7ff6f32d6afe - core::ptr::drop_in_place<reqwest::blocking::client::Client>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\mod.rs:175
  28:     0x7ff6f32a22b2 - core::ptr::drop_in_place<core::option::Option<reqwest::blocking::client::Client>>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ptr\mod.rs:175
  29:     0x7ff6f32a1c09 - core::mem::drop<core::option::Option<reqwest::blocking::client::Client>>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\mem\mod.rs:882
  30:     0x7ff6f32a2ae2 - std::thread::local::fast::destroy_value<reqwest::blocking::client::Client>
                               at C:\Users\rober\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:519
  31:     0x7ff6f3770b4b - std::sys_common::thread_local_dtor::register_dtor_fallback::run_dtors
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\sys_common\thread_local_dtor.rs:43
  32:     0x7ff6f3775e58 - std::sys::windows::thread_local_key::run_dtors
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\sys\windows\thread_local_key.rs:245
  33:     0x7ff6f3775e58 - std::sys::windows::thread_local_key::on_tls_callback
                               at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca\/library\std\src\sys\windows\thread_local_key.rs:214
  34:     0x7ffa829a5021 - RtlActivateActivationContextUnsafeFast
  35:     0x7ffa829a5103 - RtlActivateActivationContextUnsafeFast
  36:     0x7ffa829eb1b0 - LdrShutdownProcess
  37:     0x7ffa829eafad - RtlExitUserProcess
  38:     0x7ffa8289cdda - ExitProcess
  39:     0x7ffa8019ae58 - o_free
  40:     0x7ffa8019870f - exit
  41:     0x7ff6f378aaf7 - __scrt_common_main_seh
                               at d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:295
  42:     0x7ffa82897c24 - BaseThreadInitThunk
  43:     0x7ffa829ed4d1 - RtlUserThreadStart

It does seem like it has something to do with a destructor of some kind, I see reqwest::blocking::client::{{impl}}::drop in the full stacktrace, but I don't really know enough about Rust to form a more complete theory of what's going on here.

0 Answers
Related