Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

supervacuus
Copy link
Collaborator

@supervacuus supervacuus commented Apr 8, 2025

This builds on top of #1049, provides a fix for #1193, and adds further parameterization for users who want to tune this to their use cases.

The PR does the following

  • Expose a compile-time parameter SENTRY_HANDLER_STACK_SIZE that sets the required stack size for the handler (for Linux/macOS using inproc and Windows using any backend, it defaults to 64KiB, which is also the current default).
  • Expose a compile-time parameter SENTRY_THREAD_STACK_GUARANTEE_FACTOR which is the factor that the stack reserve of a given thread must at least be larger than the specified SENTRY_HANDLER_STACK_SIZE to ask for a guarantee (only Windows, defaults to 10x).
  • Expose a compile-time option SENTRY_THREAD_STACK_GUARANTEE_AUTO_INIT that toggles between turning on and off auto-initialization of the thread stack guarantee for each thread after the sentry library has been loaded (if building as a dynamic library). This option only initializes the thread that calls sentry_init() when doing a static build (only Windows, defaults to On).
  • Expose a compile-time option SENTRY_THREAD_STACK_GUARANTEE_VERBOSE_LOG that toggles between turning on and off INFO level logging of successful setting of thread stack guarantees (only Windows, defaults to Off).
  • Provide a public interface (sentry_set_thread_stack_guarantee()) to allow users to set the stack guarantee for each thread manually if the auto-initialization doesn't behave as the use case requires it
  • Adapt the auto-initialization to be much more defensive about which threads it attempts to request a stack guarantee for so we don't eat into the stack budget of threads with tiny reserves. The reserve and above meta-parameters play into the decision, which essentially boils down to this:
    if a thread doesn't have at least SENTRY_HANDLER_STACK_SIZE x SENTRY_THREAD_STACK_GUARANTEE_FACTOR of stack reserve, we won't request a guarantee from that thread.

Reasoning

  • Most threads in users' processes will have enough stack reserve (1MiB) for our default guarantee (64KiB), so there is no reason to disable auto-initialization because most users will never be confronted with any issue
  • However, no auto initialization should itself lead to a stack overflow, and thus, it makes sense to introduce a boundary at which guarantees will no longer be attempted
  • The trade-off here is that users who have threads in their process that do not fit that boundary will have some threads without a handler guarantee (i.e. if these overflow, they will crash the application, but the crash won't be reported)
  • This might sound like a bad trade-off; however, most of these threads will be outside the control of our users, and as such, any reports will be non-actionable.
  • Further, we now expose parameters for the tiny group of users that control threads with limited stacks or with enough insight into third-party-controlled threads so that reports can be actionable if they are overflowing:
    • they can disable auto-initialization entirely and define guarantees for each thread as they see fit
    • they can change the handler stack size according to their usage of hooks (with or without auto-init)
    • they can change the thread stack guarantee factor so that threads with limited stacks will still be automatically initialized with a guarantee they have tested
  • We keep the current default guarantee of 64KiB to avoid breaking the current handler assumptions in the field (particularly concerning hooks being called from the handler).

Copy link
Member

@JoshuaMoelans JoshuaMoelans left a comment

Choose a reason for hiding this comment

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

Some first nitpicks/typos/questions

@supervacuus
Copy link
Collaborator Author

@stima, I just wanted to ping you with the soon-to-be-released approach regarding the previous conversations. In particular, this last comment also led to the current reasoning: #1049 (comment). In your scenario, you could leave the auto-init enabled to cover the trivial threads and only manually set the threads you know might be excluded anyway (or not assign a guarantee for those).

@pcorbineau, @robert-jamieson, and @MaxLeb: I will release this next week as a fix. If you have time to try out the PR, feedback would be welcome. The primary concern is that no stack overflow happens in your current setup without additional configuration.

Of course, I would also be happy to know if the exposed parameters make sense to you. In your scenario, at least based on what I gathered from your previous feedback, you could reduce the handler stack size to 32KiB and only require a factor of two. Of course, this may not be enough for these threads in all cases, so if overflows from these threads (however unlikely) aren't actionable due to missing symbols, you can leave it at the defaults, which won't set any guarantees for nVidia's driver threads.

@MaxLeb
Copy link

MaxLeb commented Apr 14, 2025

@supervacuus

Thank you.

We did the tests:

  1. We do not have any stack overflow happening with default settings
  2. Changing options to reduce to 32KiB with a factor of 2 does work but we indeed have errors when trying to reserve the stack (which might be ok for us)

@supervacuus
Copy link
Collaborator Author

We did the tests

Thanks a lot for the feedback!

  1. We do not have any stack overflow happening with default settings

Great!

  1. Changing options to reduce to 32KiB with a factor of 2 does work but we indeed have errors when trying to reserve the stack (which might be ok for us)

The default settings should work well for you, too. The parameterization is primarily there if you see an issue with the particular threads not being "covered" or if you own such a thread and have detailed stack usage bounds.

Copy link
Member

@JoshuaMoelans JoshuaMoelans left a comment

Choose a reason for hiding this comment

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

lgtm!

@supervacuus supervacuus force-pushed the fix/auto_thread_stack_guarantee branch from 4f60d29 to f43da87 Compare April 15, 2025 17:28
@supervacuus supervacuus merged commit 4150d41 into master Apr 15, 2025
34 checks passed
@supervacuus supervacuus deleted the fix/auto_thread_stack_guarantee branch April 15, 2025 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants