Skip to content

[Debug Info] Gracefully handle invalid String/Vec#155509

Merged
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
Walnut356:string_crash
May 22, 2026
Merged

[Debug Info] Gracefully handle invalid String/Vec#155509
rust-bors[bot] merged 2 commits into
rust-lang:mainfrom
Walnut356:string_crash

Conversation

@Walnut356
Copy link
Copy Markdown
Contributor

@Walnut356 Walnut356 commented Apr 19, 2026

View all comments

Somewhat related to #150392.

Currently the handling can throw an exception, which we should absolutely not do. It causes issues with debugger adapters (e.g. CodeLLDB will hang forever. Trying to stop the debugger via vscode's interface causes a CodeLLDB to leak memory constantly until RAM is depleted and the OS starts killing processes). The exception has been replaced with a printed error message and a placeholder value.

Additionally, if a String/Vec is in an "invalid" state due to niche optimization (capacity >= (1 << 63), common with Option<String>/Option<Vec<T>>), the pointer and length values will be meaningless, but are not guaranteed to be 0'd. The debugger will happily proceed as if they are useful values, and often do things like <try to read multiple GB of data from the debugee>.

I added simple checks to ensure that the capacity and length are within bounds, and that the pointer is non-null. If any check fails, the string/vec just acts as if it's empty.

Eventually this problem will be solved on LLDB's end via llvm/llvm-project#188487 or similar, but preventing issues on our end in the short term will help a lot.


try-job: aarch64-apple

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 19, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 19, 2026

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @Mark-Simulacrum

Copy link
Copy Markdown
Member

@Mark-Simulacrum Mark-Simulacrum left a comment

Choose a reason for hiding this comment

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

r=me with if wording fixed, happy to skip/defer the helper, up to you.

View changes since this review

Comment thread src/etc/lldb_providers.py Outdated

if length <= 0:
return '""'

no_hi_bit_max: int = 1 << ((pointer.GetByteSize() * 8) - 1)
# technically length isn't a NoHighBit<usize>, but if length should always be <= capacity
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
# technically length isn't a NoHighBit<usize>, but if length should always be <= capacity
# technically length isn't a NoHighBit<usize>, but length should always be <= capacity

Not sure what if was meaning to refer to here?

Comment thread src/etc/lldb_providers.py Outdated
else:
raise Exception("ReadMemory error: %s", error.GetCString())
try:
data = process.ReadMemory(pointer.GetValueAsUnsigned(), length, error)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we aim for all process.ReadMemory calls to be wrapped like this? Maybe we should define our own helper to push for that? E.g., StdPathSummaryProvider probably needs the same treatment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, yeah that's a good question. It's probably best to, since swig FFI exceptions cause such catastrophic issues.

StdPathSummaryProvider probably needs the same treatment

Atm Path and OsStr providers defer directly to the vec synthetic's get_num_children and get_child_at_index. Since the vec synthetic can now detect invalid state, it'll just report an empty string.

It wouldn't be a bad idea to switch to using process.ReadMemory eventually since it's significantly more performant, but it's not too urgent since paths are usually quite short.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

data = process.ReadMemory(start, length, error)
- doesn't that need to get wrapped with try catch?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤦‍♂️ i might be blind lol

@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 26, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 26, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 26, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 27, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@Walnut356
Copy link
Copy Markdown
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 27, 2026
@Mark-Simulacrum
Copy link
Copy Markdown
Member

@bors r+

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 9, 2026

📌 Commit 0a4f89e has been approved by Mark-Simulacrum

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 9, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 9, 2026
…ulacrum

[Debug Info] Gracefully handle invalid `String`/`Vec`

Somewhat related to rust-lang#150392.

Currently the handling can throw an exception, which we should absolutely not do. It causes issues with debugger adapters (e.g. CodeLLDB will hang forever. Trying to stop the debugger via vscode's interface causes a CodeLLDB to leak memory constantly until RAM is depleted and the OS starts killing processes). The exception has been replaced with a printed error message and a placeholder value.

Additionally, if a String/Vec is in an "invalid" state due to niche optimization (`capacity >= (1 << 63)`, common with `Option<String>`/`Option<Vec<T>>`), the pointer and length values will be meaningless, but are not guaranteed to be 0'd. The debugger will happily proceed as if they are useful values, and often do things like \<try to read multiple GB of data from the debugee\>.

I added simple checks to ensure that the capacity and length are within bounds, and that the pointer is non-null. If any check fails, the string/vec just acts as if it's empty.

Eventually this problem will be solved on LLDB's end via llvm/llvm-project#188487 or similar, but preventing issues on our end in the short term will help a lot.
@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@bors r-
#156371 (comment)

Not sure if this is spurious
@bors try jobs=aarch64-apple

@rust-bors rust-bors Bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 9, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 9, 2026

This pull request was unapproved.

This PR was contained in a rollup (#156371), which was unapproved.

View changes since this unapproval

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request May 9, 2026
[Debug Info] Gracefully handle invalid `String`/`Vec`


try-job: aarch64-apple
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 9, 2026

💔 Test for 89a60ef failed: CI. Failed job:

@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 22, 2026
@Mark-Simulacrum
Copy link
Copy Markdown
Member

@bors r+

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 22, 2026

📌 Commit 23bd862 has been approved by Mark-Simulacrum

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 22, 2026
jhpratt added a commit to jhpratt/rust that referenced this pull request May 22, 2026
…ulacrum

[Debug Info] Gracefully handle invalid `String`/`Vec`

Somewhat related to rust-lang#150392.

Currently the handling can throw an exception, which we should absolutely not do. It causes issues with debugger adapters (e.g. CodeLLDB will hang forever. Trying to stop the debugger via vscode's interface causes a CodeLLDB to leak memory constantly until RAM is depleted and the OS starts killing processes). The exception has been replaced with a printed error message and a placeholder value.

Additionally, if a String/Vec is in an "invalid" state due to niche optimization (`capacity >= (1 << 63)`, common with `Option<String>`/`Option<Vec<T>>`), the pointer and length values will be meaningless, but are not guaranteed to be 0'd. The debugger will happily proceed as if they are useful values, and often do things like \<try to read multiple GB of data from the debugee\>.

I added simple checks to ensure that the capacity and length are within bounds, and that the pointer is non-null. If any check fails, the string/vec just acts as if it's empty.

Eventually this problem will be solved on LLDB's end via llvm/llvm-project#188487 or similar, but preventing issues on our end in the short term will help a lot.

---

try-job: aarch64-apple
rust-bors Bot pushed a commit that referenced this pull request May 22, 2026
Rollup of 4 pull requests

Successful merges:

 - #155509 ([Debug Info] Gracefully handle invalid `String`/`Vec`)
 - #156560 (compiler: fix duplicated "the" in two doc-comments)
 - #156725 (Remove stale RTN FIXME for assoc item constraint fallback)
 - #156818 (Privacy: enqueue type alias)
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request May 22, 2026
[Debug Info] Gracefully handle invalid `String`/`Vec`



Somewhat related to #150392. 

Currently the handling can throw an exception, which we should absolutely not do. It causes issues with debugger adapters (e.g. CodeLLDB will hang forever. Trying to stop the debugger via vscode's interface causes a CodeLLDB to leak memory constantly until RAM is depleted and the OS starts killing processes). The exception has been replaced with a printed error message and a placeholder value.

Additionally, if a String/Vec is in an "invalid" state due to niche optimization (`capacity >= (1 << 63)`, common with `Option<String>`/`Option<Vec<T>>`), the pointer and length values will be meaningless, but are not guaranteed to be 0'd. The debugger will happily proceed as if they are useful values, and often do things like \<try to read multiple GB of data from the debugee\>. 

I added simple checks to ensure that the capacity and length are within bounds, and that the pointer is non-null. If any check fails, the string/vec just acts as if it's empty.

Eventually this problem will be solved on LLDB's end via llvm/llvm-project#188487 or similar, but preventing issues on our end in the short term will help a lot.

---

try-job: aarch64-apple
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 22, 2026
…ulacrum

[Debug Info] Gracefully handle invalid `String`/`Vec`

Somewhat related to rust-lang#150392.

Currently the handling can throw an exception, which we should absolutely not do. It causes issues with debugger adapters (e.g. CodeLLDB will hang forever. Trying to stop the debugger via vscode's interface causes a CodeLLDB to leak memory constantly until RAM is depleted and the OS starts killing processes). The exception has been replaced with a printed error message and a placeholder value.

Additionally, if a String/Vec is in an "invalid" state due to niche optimization (`capacity >= (1 << 63)`, common with `Option<String>`/`Option<Vec<T>>`), the pointer and length values will be meaningless, but are not guaranteed to be 0'd. The debugger will happily proceed as if they are useful values, and often do things like \<try to read multiple GB of data from the debugee\>.

I added simple checks to ensure that the capacity and length are within bounds, and that the pointer is non-null. If any check fails, the string/vec just acts as if it's empty.

Eventually this problem will be solved on LLDB's end via llvm/llvm-project#188487 or similar, but preventing issues on our end in the short term will help a lot.

---

try-job: aarch64-apple
@JonathanBrouwer
Copy link
Copy Markdown
Contributor

@bors yield
Yielding to enclosing rollup

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 22, 2026

Auto build was cancelled. Cancelled workflows:

The next pull request likely to be tested is #156831.

rust-bors Bot pushed a commit that referenced this pull request May 22, 2026
…uwer

Rollup of 6 pull requests

Successful merges:

 - #155509 ([Debug Info] Gracefully handle invalid `String`/`Vec`)
 - #156560 (compiler: fix duplicated "the" in two doc-comments)
 - #156725 (Remove stale RTN FIXME for assoc item constraint fallback)
 - #156803 (Fix reborrow ICE in MIR place lowering)
 - #156818 (Privacy: enqueue type alias)
 - #156820 (delegation: visit body under elided-infer lifetime rib)
rust-bors Bot pushed a commit that referenced this pull request May 22, 2026
[Debug Info] Gracefully handle invalid `String`/`Vec`



Somewhat related to #150392. 

Currently the handling can throw an exception, which we should absolutely not do. It causes issues with debugger adapters (e.g. CodeLLDB will hang forever. Trying to stop the debugger via vscode's interface causes a CodeLLDB to leak memory constantly until RAM is depleted and the OS starts killing processes). The exception has been replaced with a printed error message and a placeholder value.

Additionally, if a String/Vec is in an "invalid" state due to niche optimization (`capacity >= (1 << 63)`, common with `Option<String>`/`Option<Vec<T>>`), the pointer and length values will be meaningless, but are not guaranteed to be 0'd. The debugger will happily proceed as if they are useful values, and often do things like \<try to read multiple GB of data from the debugee\>. 

I added simple checks to ensure that the capacity and length are within bounds, and that the pointer is non-null. If any check fails, the string/vec just acts as if it's empty.

Eventually this problem will be solved on LLDB's end via llvm/llvm-project#188487 or similar, but preventing issues on our end in the short term will help a lot.

---

try-job: aarch64-apple
@rust-bors

This comment has been minimized.

@rust-bors rust-bors Bot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 22, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 22, 2026

💔 Test for 1269094 failed: CI. Failed job:

rust-bors Bot pushed a commit that referenced this pull request May 22, 2026
…uwer

Rollup of 10 pull requests

Successful merges:

 - #155509 ([Debug Info] Gracefully handle invalid `String`/`Vec`)
 - #156229 (Install additional LLVM DLL on Windows)
 - #152821 (Allow forbidden target features to be hard errors)
 - #156560 (compiler: fix duplicated "the" in two doc-comments)
 - #156725 (Remove stale RTN FIXME for assoc item constraint fallback)
 - #156803 (Fix reborrow ICE in MIR place lowering)
 - #156815 (rustfmt: format const trait impls to `const impl` for syntax transition)
 - #156818 (Privacy: enqueue type alias)
 - #156820 (delegation: visit body under elided-infer lifetime rib)
 - #156829 (Turn `lint_index` from `Option<u16>` to `u16` for LintExpectationId)
@jieyouxu
Copy link
Copy Markdown
Member

@bors retry

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 22, 2026
@rust-log-analyzer
Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
fmt check
fmt: checked 6862 files
tidy check

thread 'deps (.)' (3888) panicked at src/tools/tidy/src/deps.rs:649:24:
cmd.exec() failed with `cargo metadata` exited with an error:     Updating crates.io index
error: failed to get `powerfmt` as a dependency of package `time v0.3.47`
    ... which satisfies dependency `time = "^0.3.47"` (locked to 0.3.47) of package `cargo-test-support v0.11.3 (/checkout/src/tools/cargo/crates/cargo-test-support)`

Caused by:
  failed to load source for dependency `powerfmt`

Caused by:
  unable to update registry `crates-io`

Caused by:
  download of po/we/powerfmt failed

Caused by:
  curl failed

Caused by:
---
   5: std::thread::scoped::scope::<rust_tidy::main::{closure#1}, ()>
   6: rust_tidy::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Bootstrap failed while executing `--stage 2 test --skip src/tools/rust-analyzer --skip tests --skip coverage-map --skip coverage-run --skip library --skip tidyselftest`
Command `/checkout/obj/build/aarch64-unknown-linux-gnu/stage1-tools-bin/rust-tidy --root-path=/checkout --cargo-path=/checkout/obj/build/aarch64-unknown-linux-gnu/stage0/bin/cargo --output-dir=/checkout/obj/build --concurrency=4 --npm-path=yarn --ci=true` failed with exit code 101
Created at: src/bootstrap/src/core/build_steps/tool.rs:1618:23
Executed at: src/bootstrap/src/core/build_steps/test.rs:1417:29

--- BACKTRACE vvv
   0: std::backtrace_rs::backtrace::libunwind::trace
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
   1: std::backtrace_rs::backtrace::trace_unsynchronized::<<std::backtrace::Backtrace>::create::{closure#0}>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/../../backtrace/src/backtrace/mod.rs:66:14
   2: <std::backtrace::Backtrace>::create
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/backtrace.rs:331:13
   3: <bootstrap::utils::exec::DeferredCommand>::finish_process
             at /checkout/src/bootstrap/src/utils/exec.rs:939:17
   4: <bootstrap::utils::exec::DeferredCommand>::wait_for_output::<&bootstrap::utils::exec::ExecutionContext>
             at /checkout/src/bootstrap/src/utils/exec.rs:831:21
   5: <bootstrap::utils::exec::ExecutionContext>::run
             at /checkout/src/bootstrap/src/utils/exec.rs:741:45
   6: <bootstrap::utils::exec::BootstrapCommand>::run::<&bootstrap::core::builder::Builder>
             at /checkout/src/bootstrap/src/utils/exec.rs:339:27
   7: <bootstrap::core::build_steps::test::Tidy as bootstrap::core::builder::Step>::run
             at /checkout/src/bootstrap/src/core/build_steps/test.rs:1417:29
   8: <bootstrap::core::builder::Builder>::ensure::<bootstrap::core::build_steps::test::Tidy>
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1595:36
   9: <bootstrap::core::build_steps::test::Tidy as bootstrap::core::builder::Step>::make_run
             at /checkout/src/bootstrap/src/core/build_steps/test.rs:1339:21
  10: <bootstrap::core::builder::StepDescription>::maybe_run
             at /checkout/src/bootstrap/src/core/builder/mod.rs:476:13
  11: bootstrap::core::builder::cli_paths::match_paths_to_steps_and_run
             at /checkout/src/bootstrap/src/core/builder/cli_paths.rs:141:22
  12: <bootstrap::core::builder::Builder>::run_step_descriptions
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1138:9
  13: <bootstrap::core::builder::Builder>::execute_cli
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1117:14
  14: <bootstrap::Build>::build
             at /checkout/src/bootstrap/src/lib.rs:803:25
  15: bootstrap::main
             at /checkout/src/bootstrap/src/bin/main.rs:130:11
  16: <fn() as core::ops::function::FnOnce<()>>::call_once
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/core/src/ops/function.rs:250:5
  17: std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/sys/backtrace.rs:166:18
  18: std::rt::lang_start::<()>::{closure#0}
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/rt.rs:206:18
  19: <&dyn core::ops::function::Fn<(), Output = i32> + core::panic::unwind_safe::RefUnwindSafe + core::marker::Sync as core::ops::function::FnOnce<()>>::call_once
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/core/src/ops/function.rs:287:21
  20: std::panicking::catch_unwind::do_call::<&dyn core::ops::function::Fn<(), Output = i32> + core::panic::unwind_safe::RefUnwindSafe + core::marker::Sync, i32>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/panicking.rs:581:40
  21: std::panicking::catch_unwind::<i32, &dyn core::ops::function::Fn<(), Output = i32> + core::panic::unwind_safe::RefUnwindSafe + core::marker::Sync>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/panicking.rs:544:19
  22: std::panic::catch_unwind::<&dyn core::ops::function::Fn<(), Output = i32> + core::panic::unwind_safe::RefUnwindSafe + core::marker::Sync, i32>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/panic.rs:359:14
  23: std::rt::lang_start_internal::{closure#0}
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/rt.rs:175:24
  24: std::panicking::catch_unwind::do_call::<std::rt::lang_start_internal::{closure#0}, isize>
             at /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/std/src/panicking.rs:581:40
---
  31: __libc_start_main
  32: _start


Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:00:35
  local time: Fri May 22 14:20:50 UTC 2026
  network time: Fri, 22 May 2026 14:20:50 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

rust-bors Bot pushed a commit that referenced this pull request May 22, 2026
…uwer

Rollup of 10 pull requests

Successful merges:

 - #155509 ([Debug Info] Gracefully handle invalid `String`/`Vec`)
 - #156229 (Install additional LLVM DLL on Windows)
 - #152821 (Allow forbidden target features to be hard errors)
 - #156560 (compiler: fix duplicated "the" in two doc-comments)
 - #156725 (Remove stale RTN FIXME for assoc item constraint fallback)
 - #156803 (Fix reborrow ICE in MIR place lowering)
 - #156815 (rustfmt: format const trait impls to `const impl` for syntax transition)
 - #156818 (Privacy: enqueue type alias)
 - #156820 (delegation: visit body under elided-infer lifetime rib)
 - #156829 (Turn `lint_index` from `Option<u16>` to `u16` for LintExpectationId)
@rust-bors rust-bors Bot merged commit 42bd6de into rust-lang:main May 22, 2026
12 of 13 checks passed
@rustbot rustbot added this to the 1.98.0 milestone May 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants