Issue metadata
Sign in to add a comment
|
Specify whether to emit or omit frame pointers for macOS. |
||||||||||||||||||||||
Issue descriptionRight now, we don't specify whether to emit frame pointers: https://cs.chromium.org/chromium/src/build/config/compiler/BUILD.gn?type=cs&q=omit-frame-pointer+file:Build+package:%5Echromium$&l=1387 This means we use the compiler default, which might change at any time. e.g., in 2011, the default switched to omit on Linux in 2011: http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20111212/050231.html The current default is to use frame pointers: https://github.com/llvm-mirror/clang/blob/a776ed1122e48f9ade40c454678226303d8fab52/lib/Driver/ToolChains/Clang.cpp#L519 There are currently 3 reasons why we might want to emit frame pointers: Faster native heap profiling on official, release builds. Faster sampling profiler on official, release builds. Note that both of these can use libunwind with a performance penalty. Also, note that some subsystems such as ffmpeg will never support frame pointers on official, release builds. https://cs.chromium.org/chromium/src/third_party/ffmpeg/BUILD.gn?type=cs&q=omit-frame-pointer+file:build+package:%5Echromium$&l=240 https://bugs.chromium.org/p/chromium/issues/detail?id=677362#c5 I think we should omit frame pointers if it shows a noticeable performance benefit, otherwise we should emit frame pointers.
,
Mar 28 2017
,
Mar 28 2017
As an additional data point, we used to omit frame pointers on Windows since it had some minor perf benefit, but eventually stopped doing so since it wasn't worth the cost (mostly worse crash stacks) in the long run. I think we should probably try and be consistent across platforms here, which is why we currently have them on.
,
Mar 28 2017
There are some stupid unwinders on macOS that don’t work in the absence of frame pointers. The kernel’s, which is used for “microstackshots,” is one example. See 10.12.3 xnu-3789.41.3/osfmk/kern/backtrace.c backtrace_thread_user(). We may not care about these rudimentary stackwalkers, but we should be aware of them and include them in our decision-making process.
,
Mar 28 2017
I don't know what the effect of omitting frame pointers would be on the sampling profiler on Mac, but I'd be concerned that it could make it harder to walk the stack reliably. We're currently in the process of bringing up a Mac implementation and are already encountering cases that libunwind fails to handle in Chrome built with frame pointers.
,
Mar 29 2017
What we’ve learned in https://codereview.chromium.org/2702463003/ is that Apple libunwind won’t blindly attempt frame pointer-based recovery at all. It won’t do anything unless there’s unwind info telling it what to do. The unwind info can tell it to do frame pointer-based recovery, but if there’s unwind info that tells it to do that now, why wouldn’t there be unwind info that tells it to do something else if a stack frame doesn’t use a frame pointer? In that review, we found that we did need to hold libunwind’s hand and attempt either frameless recovery or frame pointer-based recovery, but we’re only ever doing this to take the first step from the context frame, and I don’t think we’ve seen a case where we’ve needed to do this to recover a caller of our own C++ code. All of this stems from the fact that their libunwind only contemplates being called from user code, and we’re (ab)using it by forcing it to eat another thread’s context, where the other thread may not be in user code but in the problem cases we’ve seen, in a system call stub or a handwritten assembly leaf without unwind info from a system library. (It’s painful for me to see how badly this all works together, because it’s actually incredibly easy to decorate assembler source with directives to produce unwind info.) Still, it’s very possible that libunwind doesn’t deal well with frame pointer omission and the unwind info that comes along with it. Specifically if Apple’s “supported” toolchain doesn’t use FPO by default, it’d be very Apple-esque for their libunwind to skirt the issue altogether. I don’t know the answer to this. What I do know is that their libunwind does cope with both unwind info encodings that their toolchain produces, and so I don’t think that we have any particular reason to believe that this would be broken yet, absent further testing.
,
Mar 29 2017
Fwiw, I believe their libunwind is open source: https://github.com/llvm-mirror/libunwind
,
Mar 29 2017
Thanks for all the feedback. I'm going to keep emitting frame pointers, but I'm going to make it explicit rather than implicit.
,
Apr 6 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1 commit f7c8a0df4253be5271276dc7f3c1da5ce9b677c1 Author: erikchen <erikchen@chromium.org> Date: Thu Apr 06 21:15:27 2017 Explicitly specify whether to emit frame pointers by default. All platforms now specify whether to emit frame pointers by default, rather than relying on default compiler options. This CL moves the logic from config("default_stack_frames") into compiler.gni. The former is actually the right place for the logic to live, but there exists code that relies on whether a frame pointer is emitted by default. Right now, that logic is being duplicated/guessed by the code in question. This CL at least unifies the logic in a single location. There current exists code that uses a preprocessor definition HAVE_TRACE_STACK_FRAME_POINTERS. Despite the name, the code really wants to know if most stacks can be unwound using stack pointers. I've renamed it to CAN_UNWIND_WITH_FRAME_POINTERS. Arguably, any code that uses CAN_UNWIND_WITH_FRAME_POINTERS is broken and should be removed, since it relies on the assumption that all stacks will either have or not have frame pointers, but that can vary TU by TU. BUG=706116, 706654 Review-Url: https://codereview.chromium.org/2782063005 Cr-Commit-Position: refs/heads/master@{#462622} [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/base/BUILD.gn [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/base/android/jni_android.cc [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/base/android/jni_android.h [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/base/debug/stack_trace.cc [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/base/debug/stack_trace.h [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/base/debug/stack_trace_unittest.cc [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/base/trace_event/heap_profiler_allocation_context_tracker.cc [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/base/trace_event/memory_dump_manager.cc [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/build/config/compiler/BUILD.gn [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/build/config/compiler/compiler.gni [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/chrome/browser/chromeos/libc_close_tracking.cc [modify] https://crrev.com/f7c8a0df4253be5271276dc7f3c1da5ce9b677c1/tools/gn/bootstrap/bootstrap.py |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by primiano@chromium.org
, Mar 28 2017