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

Side by Side Diff: base/logging.h

Issue 2502953003: base: make CHECK macros trap at distinct addresses in official builds (Closed)
Patch Set: fix comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/logging_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_LOGGING_H_ 5 #ifndef BASE_LOGGING_H_
6 #define BASE_LOGGING_H_ 6 #define BASE_LOGGING_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <cassert> 10 #include <cassert>
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 operator bool() const { return !message_; } 455 operator bool() const { return !message_; }
456 // Returns the message. 456 // Returns the message.
457 std::string* message() { return message_; } 457 std::string* message() { return message_; }
458 458
459 private: 459 private:
460 std::string* message_; 460 std::string* message_;
461 }; 461 };
462 462
463 // Crashes in the fastest, simplest possible way with no attempt at logging. 463 // Crashes in the fastest, simplest possible way with no attempt at logging.
464 #if defined(COMPILER_GCC) || defined(__clang__) 464 #if defined(COMPILER_GCC) || defined(__clang__)
465 #define IMMEDIATE_CRASH() __builtin_trap() 465
466 // This is to make sure that the crash report can pinpoint to the right source
467 // line even in presence of multiple CHECK()s in the same function. See
468 // http://crbug.com/664209 for more context.
469 // There are three things we need to guarantee here:
470 // - The trap instructions, and hence the PC value at crash time, are distinct
471 // and don't get collapsed into the same op due to compiler optimizations.
472 // - The debug line info for the trap instructions get attributed to the caller
473 // of CHECK(), to make sure that crash reports show actionable data. This in
474 // practice rules out the ability of using a inline function, at least as
475 // long as clang doesn't support attribute(artificial).
476 // - The compiler should treat the CHECK as no-return instructions, so that the
477 // trap code can be efficiently packed in the prologue of the function and
478 // doesn't interfere with the main execution flow.
479 // Code-wise:
480 // - asm volatile seems to be enough to make the compiler emit distinct
481 // instructions for each CHECK() and not fold them together.
482 // - the actual instructions (e.g., "ud2") are borrowed from implementation of
483 // __builtin_trap() in the various toolchain.
484 // either a SIGTRAP or a SIGABRT depending on the platform.
Mark Mentovai 2017/02/13 16:22:09 On x86 and x86_64, ud2 will be SIGILL. That’s good
485 // - __builtin_unreachable() enables no-return optimizations.
486
487 #if defined(ARCH_CPU_X86_FAMILY)
488 #define TRAP_INSTRUCTION() asm volatile("ud2" ::: "memory")
489 #elif defined(ARCH_CPU_ARMEL)
490 #define TRAP_INSTRUCTION() asm volatile("udf $0xff" ::: "memory")
491 #elif defined(ARCH_CPU_ARM64)
492 #define TRAP_INSTRUCTION() asm volatile("brk #0x3e8" ::: "memory")
466 #else 493 #else
494 // Crash report accuracy will not be guaranteed on other architectures, but at
495 // least this will crash as expected.
496 #define TRAP_INSTRUCTION() __builtin_trap()
497 #endif
498
499 #define IMMEDIATE_CRASH() \
500 ({ \
501 TRAP_INSTRUCTION(); \
502 __builtin_unreachable(); \
503 })
504
505 #else // defined(COMPILER_GCC) || defined(__clang__)
467 #define IMMEDIATE_CRASH() ((void)(*(volatile char*)0 = 0)) 506 #define IMMEDIATE_CRASH() ((void)(*(volatile char*)0 = 0))
468 #endif 507 #endif
469 508
470 // CHECK dies with a fatal error if condition is not true. It is *not* 509 // CHECK dies with a fatal error if condition is not true. It is *not*
471 // controlled by NDEBUG, so the check will be executed regardless of 510 // controlled by NDEBUG, so the check will be executed regardless of
472 // compilation mode. 511 // compilation mode.
473 // 512 //
474 // We make sure CHECK et al. always evaluates their arguments, as 513 // We make sure CHECK et al. always evaluates their arguments, as
475 // doing CHECK(FunctionWithSideEffect()) is a common idiom. 514 // doing CHECK(FunctionWithSideEffect()) is a common idiom.
476 515
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 #elif NOTIMPLEMENTED_POLICY == 5 1110 #elif NOTIMPLEMENTED_POLICY == 5
1072 #define NOTIMPLEMENTED() do {\ 1111 #define NOTIMPLEMENTED() do {\
1073 static bool logged_once = false;\ 1112 static bool logged_once = false;\
1074 LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\ 1113 LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\
1075 logged_once = true;\ 1114 logged_once = true;\
1076 } while(0);\ 1115 } while(0);\
1077 EAT_STREAM_PARAMETERS 1116 EAT_STREAM_PARAMETERS
1078 #endif 1117 #endif
1079 1118
1080 #endif // BASE_LOGGING_H_ 1119 #endif // BASE_LOGGING_H_
OLDNEW
« no previous file with comments | « no previous file | base/logging_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698