Skip to content

Limit the number of frames in backtrace collection#12542

Merged
fitzgen merged 8 commits intobytecodealliance:mainfrom
adambratschikaye:abk/limit-backtrace-size
Feb 18, 2026
Merged

Limit the number of frames in backtrace collection#12542
fitzgen merged 8 commits intobytecodealliance:mainfrom
adambratschikaye:abk/limit-backtrace-size

Conversation

@adambratschikaye
Copy link
Contributor

Add Config::wasm_backtrace_max_frames option to limit the number of frames collected in backtraces and set the default at 20. This helps prevent expensive work from very deep call stacks.

Setting the value to 0 is the same as disabling backtraces and so this change deprecates Config::wasm_backtrace.

Addresses #5052

Add `Config::wasm_backtrace_max_frames` option to limit the number of
frames collected in backtraces and set the default at 20. This helps
prevent expensive work from very deep call stacks.

Setting the value to 0 is the same as disabling backtraces and so this
change deprecates `Config::wasm_backtrace`.

Addresses bytecodealliance#5052
@adambratschikaye adambratschikaye requested a review from a team as a code owner February 9, 2026 15:23
@adambratschikaye adambratschikaye requested review from fitzgen and removed request for a team February 9, 2026 15:23
@github-actions github-actions bot added wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:config Issues related to the configuration of Wasmtime labels Feb 9, 2026
Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Thanks! A couple nitpicks inline below before we merge this.

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Label Messager: wasmtime:config

It looks like you are changing Wasmtime's configuration options. Make sure to
complete this check list:

  • If you added a new Config method, you wrote extensive documentation for
    it.

    Details

    Our documentation should be of the following form:

    Short, simple summary sentence.
    
    More details. These details can be multiple paragraphs. There should be
    information about not just the method, but its parameters and results as
    well.
    
    Is this method fallible? If so, when can it return an error?
    
    Can this method panic? If so, when does it panic?
    
    # Example
    
    Optional example here.
    
  • If you added a new Config method, or modified an existing one, you
    ensured that this configuration is exercised by the fuzz targets.

    Details

    For example, if you expose a new strategy for allocating the next instance
    slot inside the pooling allocator, you should ensure that at least one of our
    fuzz targets exercises that new strategy.

    Often, all that is required of you is to ensure that there is a knob for this
    configuration option in wasmtime_fuzzing::Config (or one
    of its nested structs).

    Rarely, this may require authoring a new fuzz target to specifically test this
    configuration. See our docs on fuzzing for more details.

  • If you are enabling a configuration option by default, make sure that it
    has been fuzzed for at least two weeks before turning it on by default.


Details

To modify this label's message, edit the .github/label-messager/wasmtime-config.md file.

To add new label messages or remove existing label messages, edit the
.github/label-messager.json configuration file.

Learn more.

@adambratschikaye
Copy link
Contributor Author

Regarding the note on fuzzing - I guess we don't need to do anything because fuzzing always used the default of enabling backtraces and that isn't changing.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Thanks!

@fitzgen fitzgen added this pull request to the merge queue Feb 10, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 10, 2026
@adambratschikaye adambratschikaye requested a review from a team as a code owner February 16, 2026 16:12
@adambratschikaye adambratschikaye requested review from alexcrichton and removed request for a team February 16, 2026 16:12
@adambratschikaye
Copy link
Contributor Author

@fitzgen Looks like there was a fuzz testing failure and a docs failure when merging. They should be fixed now.

@github-actions github-actions bot added the fuzzing Issues related to our fuzzing infrastructure label Feb 16, 2026
@github-actions
Copy link

Subscribe to Label Action

cc @fitzgen

Details This issue or pull request has been labeled: "fuzzing", "wasmtime:api", "wasmtime:config"

Thus the following users have been cc'd because of the following labels:

  • fitzgen: fuzzing

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Thanks! Just one more small thing before we land this. Thanks for your patience!

Comment on lines 110 to 111
// Default configuration will only allow the host to see at most 20 frames.
let trace_limit = 20;
Copy link
Member

Choose a reason for hiding this comment

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

Rather than hard-coding a second copy of the default, which means this test will start failing if we ever change the default, can we explicitly set a limit and rely on that in the test here? Even better would be to generate an arbitrary limit as part of the wasmtime_fuzzing::generators::Stacks struct, so we fuzz different stack trace limits as well.

Should just require adding a pub limit: Option<NonZeroUsize>, field here:

/// Generate a Wasm module that keeps track of its current call stack, to
/// compare to the host.
#[derive(Debug)]
pub struct Stacks {
funcs: Vec<Function>,
inputs: Vec<u8>,
}

And then adding something like let limit = NonZeroUsize::new(u.int_in_range(0..=256)?); inside here:

impl<'a> Arbitrary<'a> for Stacks {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let funcs = Self::arbitrary_funcs(u)?;
let n = u.len().min(200);
let inputs = u.bytes(n)?.to_vec();
Ok(Stacks { funcs, inputs })
}
}

And finally creating the config with the limit and an engine from that config inside this current function, rather than using a default config and default engine:

let mut config = Config::new();
config.wasm_backtrace_max_frames(stacks.limit);
let engine = Engine::new(&config)?;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem, I made those changes.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

Thanks!

@fitzgen fitzgen added this pull request to the merge queue Feb 18, 2026
Merged via the queue into bytecodealliance:main with commit c8764ed Feb 18, 2026
45 checks passed
@adambratschikaye
Copy link
Contributor Author

Thanks @fitzgen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fuzzing Issues related to our fuzzing infrastructure wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:config Issues related to the configuration of Wasmtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments