New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 706116 link

Starred by 1 user

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Mac
Pri: 3
Type: Bug
Hotlist-MemoryInfra



Sign in to add a comment

Specify whether to emit or omit frame pointers for macOS.

Project Member Reported by erikc...@chromium.org, Mar 28 2017

Issue description

Right 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.
 
Cc: asvitk...@chromium.org
+asvitkine as he might be interested in the "UMA sampling profiler" part.

Cc: wittman@chromium.org a...@chromium.org

Comment 3 by thakis@chromium.org, 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.

Comment 4 by mark@chromium.org, 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.
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.

Comment 6 by mark@chromium.org, 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.

Comment 7 by thakis@chromium.org, Mar 29 2017

Fwiw, I believe their libunwind is open source: https://github.com/llvm-mirror/libunwind
Owner: erikc...@chromium.org
Status: Assigned (was: Available)
Thanks for all the feedback. 

I'm going to keep emitting frame pointers, but I'm going to make it explicit rather than implicit.
Project Member

Comment 9 by bugdroid1@chromium.org, 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