OLD | NEW |
---|---|
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 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 CheckOpResult(std::string* message) : message_(message) {} | 489 CheckOpResult(std::string* message) : message_(message) {} |
490 // Returns true if the check succeeded. | 490 // Returns true if the check succeeded. |
491 operator bool() const { return !message_; } | 491 operator bool() const { return !message_; } |
492 // Returns the message. | 492 // Returns the message. |
493 std::string* message() { return message_; } | 493 std::string* message() { return message_; } |
494 | 494 |
495 private: | 495 private: |
496 std::string* message_; | 496 std::string* message_; |
497 }; | 497 }; |
498 | 498 |
499 // Crashes in the fastest, simplest possible way with no attempt at logging. | 499 // Crashes in the fastest possible way with no attempt at logging. |
500 // There are different constraints to satisfy here, see http://crbug.com/664209 | |
501 // for more context: | |
502 // - The trap instructions, and hence the PC value at crash time, have to be | |
503 // distinct and not get folded into the same opcode by the compiler. | |
504 // On Linux/Android this is tricky because GCC still folds identical | |
505 // asm volatile blocks. The workaround is generating distinct opcodes for | |
506 // each CHECK using the __COUNTER__ macro. | |
507 // - The debug info for the trap instruction has to be attributed to the source | |
508 // line that has the CHECK(), to make crash reports actionable. This rules | |
509 // out the ability of using a inline function, at least as long as clang | |
510 // doesn't support attribute(artificial). | |
511 // - Failed CHECKs should produce a signal that is distinguishable from an | |
512 // invalid memory access, to improve the actionability of crash reports. | |
513 // - The compiler should treat the CHECK as no-return instructions, so that the | |
514 // trap code can be efficiently packed in the prologue of the function and | |
515 // doesn't interfere with the main execution flow. | |
516 // - When debugging, developers shouldn't be able to accidentally step over a | |
517 // CHECK. This is achieved by putting opcodes that will cause a non | |
518 // continuable exception after the actual trap instruction. | |
519 // - Don't cause too much binary bloat. | |
500 #if defined(COMPILER_GCC) | 520 #if defined(COMPILER_GCC) |
501 #define IMMEDIATE_CRASH() __builtin_trap() | 521 |
522 #if defined(ARCH_CPU_X86_FAMILY) | |
523 // int 3 will generate a SIGTRAP. | |
524 #define TRAP_SEQUENCE() \ | |
525 asm volatile("int3; ud2; push %0;" ::"i"((uint8_t)__COUNTER__)) | |
Mark Mentovai
2017/02/17 15:04:33
I suggested a fundamental type because this header
Primiano Tucci (use gerrit)
2017/02/17 15:08:47
Ah right. fixed both the cast and switched to unsi
| |
526 | |
527 #elif defined(ARCH_CPU_ARMEL) | |
528 // bkpt will generate a SIGBUS when running on armv7 and a SIGTRAP when running | |
529 // as a 32 bit userspace app on arm64. There doesn't seem to be any way to | |
530 // cause a SIGTRAP from userspace without using a syscall (which would be a | |
531 // problem for sandboxing). | |
532 #define TRAP_SEQUENCE() \ | |
533 asm volatile("bkpt #0; udf %0;" ::"i"(__COUNTER__ % 256)) | |
534 | |
535 #elif defined(ARCH_CPU_ARM64) | |
536 | |
537 // This will always generate a SIGTRAP on arm64. | |
538 #define TRAP_SEQUENCE() \ | |
539 asm volatile("brk #0; hlt %0;" ::"i"(__COUNTER__ % 65536)) | |
540 #else | |
541 // Crash report accuracy will not be guaranteed on other architectures, but at | |
542 // least this will crash as expected. | |
543 #define TRAP_SEQUENCE() __builtin_trap() | |
544 #endif | |
545 | |
546 #define IMMEDIATE_CRASH() \ | |
547 ({ \ | |
548 TRAP_SEQUENCE(); \ | |
549 __builtin_unreachable(); \ | |
550 }) | |
551 | |
502 #elif defined(COMPILER_MSVC) | 552 #elif defined(COMPILER_MSVC) |
503 #define IMMEDIATE_CRASH() __debugbreak() | 553 #define IMMEDIATE_CRASH() __debugbreak() |
504 #else | 554 #else |
505 #error Port | 555 #error Port |
506 #endif | 556 #endif |
507 | 557 |
508 // CHECK dies with a fatal error if condition is not true. It is *not* | 558 // CHECK dies with a fatal error if condition is not true. It is *not* |
509 // controlled by NDEBUG, so the check will be executed regardless of | 559 // controlled by NDEBUG, so the check will be executed regardless of |
510 // compilation mode. | 560 // compilation mode. |
511 // | 561 // |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1057 #elif NOTIMPLEMENTED_POLICY == 5 | 1107 #elif NOTIMPLEMENTED_POLICY == 5 |
1058 #define NOTIMPLEMENTED() do {\ | 1108 #define NOTIMPLEMENTED() do {\ |
1059 static bool logged_once = false;\ | 1109 static bool logged_once = false;\ |
1060 LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\ | 1110 LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\ |
1061 logged_once = true;\ | 1111 logged_once = true;\ |
1062 } while(0);\ | 1112 } while(0);\ |
1063 EAT_STREAM_PARAMETERS | 1113 EAT_STREAM_PARAMETERS |
1064 #endif | 1114 #endif |
1065 | 1115 |
1066 #endif // BASE_LOGGING_H_ | 1116 #endif // BASE_LOGGING_H_ |
OLD | NEW |