Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicitly pass strong ref as raw pointer to prevent UB in Arc::drop #58611

Conversation

vertexclique
Copy link
Member

@vertexclique vertexclique commented Feb 21, 2019

As stated out in #55005 I try to apply the first solution stated by @RalfJung . Which is:

  • Provide a version of fetch_sub that takes a raw pointer, and use that.

I want to add couple of questions and notes about PR:

  • I am unsure how this can be done without extending the public api of Atomic*.
  • mutable borrows can't be done over the ArcInner<T> so while using the fetch_* of strong ref. how we can pass a raw pointer of strong ref? Is it correct way of doing it?
  • how can we test this spooky case? Spawning threads that will lurk behind the Arc::drop? I have no idea.

@rust-highfive
Copy link
Collaborator

r? @aidanhs

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 21, 2019
@vertexclique vertexclique force-pushed the arc-drop-fetch-sub-explicit-impl branch from 7d323b8 to 5f36dc2 Compare February 21, 2019 01:01
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:1103f9c1:start=1550710977374801267,finish=1550711050515666217,duration=73140864950
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---
[00:58:22]  Documenting core v0.0.0 (/checkout/src/libcore)
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:1922:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 1922 | / atomic_int! {
[00:58:38] 1923 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1924 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1925 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] ...    |
[00:58:38] 1934 | |     i8 AtomicI8 ATOMIC_I8_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:1937:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 1937 | / atomic_int! {
[00:58:38] 1938 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1939 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1940 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] ...    |
[00:58:38] 1949 | |     u8 AtomicU8 ATOMIC_U8_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:1952:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 1952 | / atomic_int! {
[00:58:38] 1953 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1954 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1955 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] ...    |
[00:58:38] 1964 | |     i16 AtomicI16 ATOMIC_I16_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:1967:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 1967 | / atomic_int! {
[00:58:38] 1968 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1969 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1970 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] ...    |
[00:58:38] 1979 | |     u16 AtomicU16 ATOMIC_U16_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:1982:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 1982 | / atomic_int! {
[00:58:38] 1983 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1984 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1985 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] ...    |
[00:58:38] 1994 | |     i32 AtomicI32 ATOMIC_I32_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:1997:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 1997 | / atomic_int! {
[00:58:38] 1998 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 1999 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 2000 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] ...    |
[00:58:38] 2009 | |     u32 AtomicU32 ATOMIC_U32_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:2012:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 2012 | / atomic_int! {
[00:58:38] 2013 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 2014 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 2015 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] ...    |
[00:58:38] 2024 | |     i64 AtomicI64 ATOMIC_I64_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:2027:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 2027 | / atomic_int! {
[00:58:38] 2028 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 2029 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] 2030 | |     stable(feature = "integer_atomics_stable", since = "1.34.0"),
[00:58:38] ...    |
[00:58:38] 2039 | |     u64 AtomicU64 ATOMIC_U64_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:2084:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 2084 | / atomic_int!{
[00:58:38] 2085 | |     stable(feature = "rust1", since = "1.0.0"),
[00:58:38] 2086 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:58:38] 2087 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:58:38] ...    |
[00:58:38] 2096 | |     isize AtomicIsize ATOMIC_ISIZE_INIT
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:38] 
[00:58:38] warning: doc comment contains an invalid Rust code block
[00:58:38]     --> src/libcore/num/mod.rs:28:9
[00:58:38]      |
[00:58:38] 28   |           #[doc = $x]
[00:58:38]      | 
[00:58:38]     ::: src/libcore/sync/atomic.rs:2099:1
[00:58:38]      |
[00:58:38]      |
[00:58:38] 2099 | / atomic_int!{
[00:58:38] 2100 | |     stable(feature = "rust1", since = "1.0.0"),
[00:58:38] 2101 | |     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
[00:58:38] 2102 | |     stable(feature = "atomic_debug", since = "1.3.0"),
[00:58:38] 2111 | |     usize AtomicUsize ATOMIC_USIZE_INIT
[00:58:38] 2112 | | }
[00:58:38]      | |_- in this macro invocation
[00:58:38]      |
[00:58:38]      |
[00:58:38]      = help: mark blocks that do not contain Rust code as text: ```text
[00:58:38] 
[00:58:43] error: Could not document `core`.
[00:58:43] 
[00:58:43] Caused by:
[00:58:43]   process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustdoc --crate-name core src/libcore/lib.rs --color always --target x86_64-unknown-linux-gnu -o /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/doc --markdown-css rust.css --markdown-no-toc --generate-redirect-pages --index-page /checkout/src/doc/index.md -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/release/deps` (exit code: 1)
[00:58:43] 
[00:58:43] 
[00:58:43] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "rustdoc" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "panic-unwind backtrace" "--manifest-path" "/checkout/src/libstd/Cargo.toml" "-Z" "unstable-options" "-p" "core" "--" "--markdown-css" "rust.css" "--markdown-no-toc" "--generate-redirect-pages" "--index-page" "/checkout/src/doc/index.md"
[00:58:43] 
[00:58:43] 
[00:58:43] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap doc
[00:58:43] Build completed unsuccessfully in 0:05:47
[00:58:43] Build completed unsuccessfully in 0:05:47
[00:58:43] make: *** [all] Error 1
[00:58:43] Makefile:18: recipe for target 'all' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:04b83f68
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Thu Feb 21 02:03:03 UTC 2019
---
155960 ./obj/build/bootstrap/debug/incremental
142112 ./obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu
142108 ./obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release
141180 ./obj/build/bootstrap/debug/incremental/bootstrap-3i6jt5nchoxcn
141176 ./obj/build/bootstrap/debug/incremental/bootstrap-3i6jt5nchoxcn/s-f9oiz71hb7-158se2x-1wm2zcqodn409
138748 ./obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release/deps
\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:2557844a
travis_time:start:2557844a
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:08553cea
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

pub fn fetch_sub_explicit(f: *const $atomic_type,
val: $int_type,
order: Ordering) -> $int_type {
unsafe { atomic_sub((*f).v.get(), val, order) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the type of atomic_sub? Won't this create a reference again?

Copy link
Member

@bjorn3 bjorn3 Feb 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

atomic_sub takes *mut T:

unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thanks. So this would indeed fix the problem even under the most strict semantics -- but at the cost of duplicating the entire API surface of the Atomic* types.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True that. See my comment under the PR description:

  • I am unsure how this can be done without extending the public api of AtomicUsize.

edit: basically all Atomic* i meant.

@RalfJung
Copy link
Member

Thanks for this PR!

However, I think it is too early to implement something here. We first need to do some design work and figure out how we want to solve this problem -- this has some ecosystem wide consequences in terms of which code is or is not UB.

@vertexclique
Copy link
Member Author

Then, this can stay in here for further reference.

@RalfJung
Copy link
Member

RalfJung commented Feb 21, 2019

Do you mean we should merge this for further experimentation? Or keep the PR?

We don't usually keep PRs open that we do not intend to merge soon. That just clutters the PR list. But you could add a link to #55005, so even if we close it we can still find this proposed solution.

@vertexclique
Copy link
Member Author

Not keeping the PR but the reference to it. It is up to you to merge this or not. Not my word in here, since you want to go to the stacked borrows direction, and major review needs to be done in code and we need to come under a conclusion for UB or not UB condition.

I am adding the reference now. But can't say a word for PR acceptance for experimentation.

@Centril
Copy link
Contributor

Centril commented Feb 22, 2019

r? @RalfJung

@rust-highfive rust-highfive assigned RalfJung and unassigned aidanhs Feb 22, 2019
@vertexclique
Copy link
Member Author

I need to fix the doc example of public api of Atomic*

@RalfJung
Copy link
Member

RalfJung commented Feb 23, 2019

As discussed before, I don't think we want to land this before we decided that we really want to duplicate the Atomic* API surface.

Nevertheless, thanks a lot @vertexclique!

@RalfJung RalfJung closed this Feb 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants