-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New feature flag to allow for stack backtrace/unwind #8703
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
Conversation
I'm working on it -- sorry, I figured the weekend would be an OK time to mess with the bots. |
|
Aha hahahah! Carry on. 🫡 Lemme know once you think it's fixed, then I'll retrigger the bots. Thanks Alex! |
src/CodeGen_Internal.cpp
Outdated
| for (const char *s : {"halide_use_soft_float_abi", | ||
| "halide_use_pic"}) { | ||
| "halide_use_pic", | ||
| "halide_keep_frame_pointer"}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I very much prefer the term "keep frame pointer", but in being consistent with compilers out there, should we change to "no_omit_frame_pointer"?
|
I wonder if we need to add Halide/src/runtime/CMakeLists.txt Line 160 in 4d8c660
|
|
Oh, and we are also purposedly stripping unwind information from the runtime with Halide/src/runtime/CMakeLists.txt Line 165 in 4d8c660
I think unwind tables are there to assist unwinding callstacks (maybe exceptions too?) when frame pointers are omitted. |
|
Compiler flags in the cmakefile should be irrelevant here, if we do things right. There are other ways to build libHalide, so these should be controlled in code, not in the build. These flags should just set the initial state of the function attributes in the runtime functions, but they should get clobbered by CodeGen_LLVM.cpp line 629. These functions are currently marked nounwind because it's impossible to throw exceptions safely through Halide-generated code (we'd leak all over the place), and according to the llvm docs, nounwind is for functions you can't throw exceptions through. There's another attribute "uwtable" which indicates "the ABI being targeted requires that an unwind table entry be produced for this function even if we can show that no exceptions passes by it." We could try adding that, with fn.addFnAttr("uwtable") in CodeGen_Internal.cpp in set_function_attributes_from_halide_target_options. |
|
Yeah, I was doing some reading, and found out that the unwind tables for callstack unwinding just piggy-backs on the infrastructure arounf exception handling @shoaibkamil I tried adding |
We could add those flags for the runtime functions too. I'll try that tomorrow and push it. You can try again. I'll ping you when I did this. |
|
Working with Marcos, the thing that worked on windows was: Turns out windows x64 doesn't really do frame pointers at all. |
What does that mean? The windows debugger ignores them for back tracing the call stack? I see two options, and the "New Proposal" would get my preference. Backwards-compatible way forwardWhat do we do with this flag? Unwind tables are big to store in the I'm assuming Unwind Tables generated by LLVM would replace the need for the frame pointer. This is kinda pity, because on Linux, it does suffice to produce a backtrace. So do we keep both flags as feature flags? New ProposalI'm sort of thinking that the @slomp @shoaibkamil @abadams @alexreinking @steven-johnson @vksnk |
According to the MSVC compiler: "/Oy enables frame-pointer omission and /Oy- disables omission. In x64 compilers, /Oy and /Oy- are not available" Going a bit deeper into the Windows 64 ABI, for proper unwinding, the PE image must include Now, whether or not providing frame pointers on top of that will work and have benefits, is unclear. I am sure third-party libraries could use them to do the unwind, but I can't find much about the behavior of the "Windows unwinder" when frame pointers are used. |
The thing is: callstacks are also invaluable for profiling, and profiling Debug modules is not ideal.
The safe thing to do for now is for unwinding to be "opt-in". We would need to do some research to see if the impact of adding |
|
My inclination would be to have a single flag that turns on frame pointers and unwind tables, and call it something to do with backtraces or call stacks. EnableBacktraces? PreserveCallStack? |
61ea8e1 to
4246ad3
Compare
…efault in that case. Also enable that feature when Target::Feature::Debug is set. Cleanup some helper functions.
4246ad3 to
f3dc266
Compare
|
Update: changed the flag name to |
|
That |
| fn.addFnAttr("target-features", mattrs); | ||
| if (enable_bt) { | ||
| fn.addFnAttr("frame-pointer", "all"); | ||
| fn.setUWTableKind(llvm::UWTableKind::Default); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting both frame pointer and unwind tables is fine for now, but I'd add a comment mentioning that having both set is not necessary, and which one is more appropriate depends on the system/arch/abi.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well both is nice, because unwinding is very fast if you have frame pointers enabled. Unwinding via unwind information in .eh_frame is very slow in comparison. Although I don't think it would be a big deal, as the callstack depth in Halide routines is never very big. So perhaps its better to only rely on the unwind table...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this stage, we don't need to overthink too much, since it's opt-in.
Have both enabled, and we can tune things later, once we start using and having a better understanding of the implications in practice.
|
@slomp is this working for you, on Windows? |
Yes, just tested the |
|
Where do we all stand with this one? |
|
I'm also in favor of merging as is. Waiting for approval. |
|
@abadams @alexreinking @slomp Approval to land? I'm juggling PRs. |
src/runtime/HalideRuntime.h
Outdated
| halide_target_feature_no_bounds_query, ///< Disable the bounds querying functionality. | ||
| halide_target_feature_jit = 0, ///< Generate code that will run immediately inside the calling process. | ||
| halide_target_feature_debug, ///< Turn on debug info and output for runtime code. | ||
| halide_target_feature_enable_backtraces, ///< Keep the frame pointer in tact in functions produced by LLVM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be something about unwind tables. Maybe "Preserve frame pointers and include unwind tables to support accurate backtraces for debugging and profiling."
abadams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me with a minor comment about the description of the feature flag
|
@mcourteaux - go ahead and make the documentation tweak @abadams suggested and then just merge. |
alexreinking
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs a one-line change for Python 😭
alexreinking
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, let's get this in
I implemented this as a target feature flag. This way we can still disable this for actual performance optimized releases of software.
We could use Feature::Debug as another reason to enable this LLVM flag.
Fixes #8440
Fixes #8702
Fixes #8754