Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Issue 2705053002: [Reland] base: make CHECK macros trap at distinct addresses in official builds (Closed)

Created:
3 years, 10 months ago by Primiano Tucci (use gerrit)
Modified:
3 years, 10 months ago
Reviewers:
Mark Mentovai
CC:
chromium-reviews, vmpstr+watch_chromium.org, Torne, Nico, scottmg, Will Harris, esprehn, tkent
Target Ref:
refs/pending/heads/master
Project:
chromium
Visibility:
Public.

Description

[Reland] base: make CHECK macros trap at distinct addresses in official builds Original CL: https://crrev.com/2502953003 Revert: https://crrev.com/2706453004 Reason for relanding: masked out OS_NACL which was failing to build because of this error: "GNU-style inline assembly is disabled" Original CL Description: > Abstract > -------- > CHECK() is the macro used all over the places (~4K occurrences without > counting for dupes due to inlining) for release-time assertions. > It is enabled in a minimal form (crash without a message) in official builds. > It needs to be fast as it is used in lot of fastpath. > It needs to not emit too much code, as it is used in lot of places. > It needs to guarantee that crash reports can pinpoint to the right > location when hitting a CHECK. > > - Back in the days CHECK was fat, slow, but crash-friendly. > - After crrev.com/1982123002 it became tiny, fast but not crash friendly. > - This CL is making it a bit less tiny (+28/+128K), fast and crash friendly. > > The problem this CL deals with is the case of multiple CHECK()s within > the same function. Also, adds a test that covers Mac, Linux and Android. > > A bit of history: > ----------------- > Before crrev.com/1982123002 (reverted and later re-landed in > crrev.com/2125923002) CHECK() in official builds was essentially: > if (!condition) BreakDebugger() > It was later found that this approach was not efficient, both in terms > of binary size and performance. More importantly it was a regression > w.r.t. blink's assert that were later switched to CHECK(). > "[blink-dev] Update of wtf/Assertions.h, and ASSERT macros deprecation" > The major reason for this is DebuggerBreak being quite complex and > not treated as noreturn by the compiler. > It seems (see crbug.com/664209 for more) that the most efficient way to > handle these checks is ending up with: > > Source code: > CHECK(cond1); > CHECK(cond2); > ... > > Ideal assembly: > (ideal for perf and binary, but not for crash reports, more below) > compare_opcode cond1; > jump_if_zero prologue; > compare_opcode cond2; > jump_if_zero prologue; > ... > prologue: > trap_instruction(s) > > Rather than something like: > compare_opcode cond1; > jump_if_NOT_zero next1; > trap_instruction(s) > next1: > compare_opcode cond2; > jump_if_NOT_zero next2; > trap_instruction(s) > next2: > ... > Where essentially the trap instructions are interleaved within the > main execution flow. This is even worse if the trap instruction is > actually a call to a function, with annex frame initialization, > as in the case of BreakDebugger(). That bloats the binary and > reduces i-cache hotness for the main flow. > > crrev.com/1982123002 recently fixed the situation making the > assembly look like the ideal case above. Unfortunately this caused > another problem due the extreme optimization: once the program > crashes in "trap_instruction(s)", there is no easy way to tell which condition > caused the trap. In practice this translates into the inability of > tell which CHECK failed in a function that has more than one check. > > This CL: > -------- > Re-addresses crrev.com/2125923002, adding an extra instruction after > the trap which creates an opcode with a unique counter. This prevents > the compiler from folding the trap instructions, still applying no-return > optimizations. > Also by doing this the various prologue get properly attributed to the > CHECK line in debugging symbols. > > Binary size inflation on official builds: > ----------------------------------------- > Android arm: 48684276 -> 48712948 = 28 K > Android arm64: 85611800 -> 85665048 = 53 K > Android x86_64: 91904944 -> 91933616 = 28 K > Linux x86_64: 124219488 -> 124346464 = 124 K > (Android build with -Os, hence why the difference between the two) > BUG=664209, 599867 TBR=mark@chromium.org Review-Url: https://codereview.chromium.org/2705053002 Cr-Commit-Position: refs/heads/master@{#451749} Committed: https://chromium.googlesource.com/chromium/src/+/f53167270c44da971a2f085299404319e42756f4

Patch Set 1 : Original CL #

Patch Set 2 : New changes to exclude nacl #

Patch Set 3 : rebase #

Total comments: 2
Unified diffs Side-by-side diffs Delta from patch set Stats (+159 lines, -3 lines) Patch
M base/logging.h View 1 2 1 chunk +53 lines, -2 lines 2 comments Download
M base/logging_unittest.cc View 1 2 chunks +106 lines, -1 line 0 comments Download

Messages

Total messages: 19 (11 generated)
Primiano Tucci (use gerrit)
3 years, 10 months ago (2017-02-21 10:05:41 UTC) #7
commit-bot: I haz the power
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.org/2705053002/20001
3 years, 10 months ago (2017-02-21 10:06:08 UTC) #9
commit-bot: I haz the power
Failed to apply patch for base/logging.h: While running git apply --index -p1; error: patch failed: ...
3 years, 10 months ago (2017-02-21 10:11:16 UTC) #11
commit-bot: I haz the power
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.org/2705053002/40001
3 years, 10 months ago (2017-02-21 10:45:28 UTC) #13
Mark Mentovai
LGTM
3 years, 10 months ago (2017-02-21 12:45:49 UTC) #14
commit-bot: I haz the power
Committed patchset #3 (id:40001) as https://chromium.googlesource.com/chromium/src/+/f53167270c44da971a2f085299404319e42756f4
3 years, 10 months ago (2017-02-21 13:10:05 UTC) #17
Mark Mentovai
https://codereview.chromium.org/2705053002/diff/40001/base/logging.h File base/logging.h (right): https://codereview.chromium.org/2705053002/diff/40001/base/logging.h#newcode565 base/logging.h:565: (__debugbreak(), (void)(*reinterpret_cast<volatile unsigned char*>(0) = \ If Lexan supports ...
3 years, 10 months ago (2017-02-21 14:21:50 UTC) #18
Primiano Tucci (use gerrit)
3 years, 10 months ago (2017-02-21 14:27:51 UTC) #19
Message was sent while issue was closed.
https://codereview.chromium.org/2705053002/diff/40001/base/logging.h
File base/logging.h (right):

https://codereview.chromium.org/2705053002/diff/40001/base/logging.h#newcode565
base/logging.h:565: (__debugbreak(), (void)(*reinterpret_cast<volatile unsigned
char*>(0) = \
On 2017/02/21 14:21:50, Mark Mentovai wrote:
> If Lexan supports GCC-style inline asm, we could use the above for this.

Yup, realized the same too late. I just left a comment on Scott's CL in
https://codereview.chromium.org/2701253005/diff/1/base/logging.h#newcode515

Powered by Google App Engine
This is Rietveld 408576698