Changeset 234335 in webkit
- Timestamp:
- Jul 27, 2018, 3:44:47 PM (7 years ago)
- Location:
- trunk/Source
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r234331 r234335 1 2018-07-27 Mark Lam <mark.lam@apple.com> 2 3 Add some crash info to Heap::checkConn() RELEASE_ASSERTs. 4 https://bugs.webkit.org/show_bug.cgi?id=188123 5 <rdar://problem/42672268> 6 7 Reviewed by Keith Miller. 8 9 1. Add VM::m_id and Heap::m_lastPhase fields. Both of these fit within existing 10 padding space in VM and Heap, and should not cost any measurable perf to 11 initialize and update. 12 13 2. Add some crash info to the RELEASE_ASSERTs in Heap::checkConn(): 14 15 worldState tells us the value we failed the assertion on. 16 17 m_lastPhase, m_currentPhase, and m_nextPhase tells us the GC phase transition 18 that led us here. 19 20 VM::id(), and VM::numberOfIDs() tells us how many VMs may be in play. 21 22 VM::isEntered() tells us if the current VM is currently executing JS code. 23 24 Some of this data may be redundant, but the redundancy is intentional so that 25 we can double check what is really happening at the time of crash. 26 27 * heap/Heap.cpp: 28 (JSC::asInt): 29 (JSC::Heap::checkConn): 30 (JSC::Heap::changePhase): 31 * heap/Heap.h: 32 * runtime/VM.cpp: 33 (JSC::VM::nextID): 34 (JSC::VM::VM): 35 * runtime/VM.h: 36 (JSC::VM::numberOfIDs): 37 (JSC::VM::id const): 38 (JSC::VM::isEntered const): 39 1 40 2018-07-25 Yusuke Suzuki <utatane.tea@gmail.com> 2 41 -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r233765 r234335 1122 1122 } 1123 1123 1124 ALWAYS_INLINE int asInt(CollectorPhase phase) 1125 { 1126 return static_cast<int>(phase); 1127 } 1128 1124 1129 void Heap::checkConn(GCConductor conn) 1125 1130 { 1131 unsigned worldState = m_worldState.load(); 1126 1132 switch (conn) { 1127 1133 case GCConductor::Mutator: 1128 RELEASE_ASSERT( m_worldState.load() & mutatorHasConnBit);1134 RELEASE_ASSERT(worldState & mutatorHasConnBit, worldState, asInt(m_lastPhase), asInt(m_currentPhase), asInt(m_nextPhase), vm()->id(), VM::numberOfIDs(), vm()->isEntered()); 1129 1135 return; 1130 1136 case GCConductor::Collector: 1131 RELEASE_ASSERT(!( m_worldState.load() & mutatorHasConnBit));1137 RELEASE_ASSERT(!(worldState & mutatorHasConnBit), worldState, asInt(m_lastPhase), asInt(m_currentPhase), asInt(m_nextPhase), vm()->id(), VM::numberOfIDs(), vm()->isEntered()); 1132 1138 return; 1133 1139 } … … 1520 1526 checkConn(conn); 1521 1527 1528 m_lastPhase = m_currentPhase; 1522 1529 m_nextPhase = nextPhase; 1523 1530 -
trunk/Source/JavaScriptCore/heap/Heap.h
r233123 r234335 694 694 Ticket m_lastServedTicket { 0 }; 695 695 Ticket m_lastGrantedTicket { 0 }; 696 CollectorPhase m_lastPhase { CollectorPhase::NotRunning }; 696 697 CollectorPhase m_currentPhase { CollectorPhase::NotRunning }; 697 698 CollectorPhase m_nextPhase { CollectorPhase::NotRunning }; -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r234171 r234335 183 183 #endif 184 184 185 Atomic<unsigned> VM::s_numberOfIDs; 186 185 187 // Note: Platform.h will enforce that ENABLE(ASSEMBLER) is true if either 186 188 // ENABLE(JIT) or ENABLE(YARR_JIT) or both are enabled. The code below … … 248 250 } 249 251 252 inline unsigned VM::nextID() 253 { 254 for (;;) { 255 unsigned currentNumberOfIDs = s_numberOfIDs.load(); 256 unsigned newID = currentNumberOfIDs + 1; 257 if (s_numberOfIDs.compareExchangeWeak(currentNumberOfIDs, newID)) 258 return newID; 259 } 260 } 261 262 250 263 VM::VM(VMType vmType, HeapType heapType) 251 : m_apiLock(adoptRef(new JSLock(this))) 264 : m_id(nextID()) 265 , m_apiLock(adoptRef(new JSLock(this))) 252 266 #if USE(CF) 253 267 , m_runLoop(CFRunLoopGetCurrent()) -
trunk/Source/JavaScriptCore/runtime/VM.h
r234171 r234335 290 290 #endif 291 291 292 static unsigned numberOfIDs() { return s_numberOfIDs.load(); } 293 unsigned id() const { return m_id; } 294 bool isEntered() const { return !!entryScope; } 295 292 296 private: 297 unsigned nextID(); 298 299 static Atomic<unsigned> s_numberOfIDs; 300 301 unsigned m_id; 293 302 RefPtr<JSLock> m_apiLock; 294 303 #if USE(CF) -
trunk/Source/WTF/ChangeLog
r234332 r234335 1 2018-07-27 Mark Lam <mark.lam@apple.com> 2 3 Add some crash info to Heap::checkConn() RELEASE_ASSERTs. 4 https://bugs.webkit.org/show_bug.cgi?id=188123 5 <rdar://problem/42672268> 6 7 Reviewed by Keith Miller. 8 9 1. Rename STUFF_FOR_CRASH_REGISTERx to CRASH_GPRx. These are only used in 10 locally in Assertions.cpp. There is little to no chance of a name collision, 11 and the shorter names will be much easier to read and grok in the code. 12 13 2. Added an additional 2 registers so that we can pass more info. 14 15 3. Change the WTFCrashWithInfo() implementations to issue only a single asm 16 statement so that the compiler does not inadvertently move values out of the 17 CRASH_GPRs that we want them to be in. 18 19 4. Use register targeting for local variables to get the compiler to put our 20 desired values in specific registers. For how this works, see 21 https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables 22 23 "The only supported use for this feature is to specify registers for input and 24 output operands when calling Extended asm (see Extended Asm). This may be 25 necessary if the constraints for a particular machine don’t provide sufficient 26 control to select the desired register." 27 28 5. Enhance ASSERT, ASSERT_UNUSED, RELEASE_ASSERT, RELEASE_ASSERT_NOT_REACHED to 29 accept crash info arguments. We no longer need to use an if statement with a 30 call to CRASH_WITH_INFO instead of these assertions. The only case not handled 31 yet is one where we might want to dataLog some info before the crash. I'll 32 add that functionality in a subsequent patch. 33 34 6. Move UNREACHABLE_FOR_PLATFORM to the bottom of Assertions.h because it depends 35 on the definition of RELEASE_ASSERT_NOT_REACHED, which now depends on the 36 definiton of CRASH_WITH_INFO. 37 38 * wtf/Assertions.cpp: 39 (WTFCrashWithInfo): 40 * wtf/Assertions.h: 41 1 42 2018-07-27 Alex Christensen <achristensen@webkit.org> 2 43 -
trunk/Source/WTF/wtf/Assertions.cpp
r234278 r234335 567 567 #if OS(DARWIN) && (CPU(X86_64) || CPU(ARM64)) 568 568 #if CPU(X86_64) 569 #define STUFF_REGISTER_FOR_CRASH(reg, info) __asm__ volatile ("movq %0, %%" reg : : "r" (static_cast<uint64_t>(info)) : reg) 569 570 #define CRASH_INST "int3" 570 571 571 572 // This ordering was chosen to be consistent with JSC's JIT asserts. We probably shouldn't change this ordering 572 573 // since it would make tooling crash reports much harder. If, for whatever reason, we decide to change the ordering 573 574 // here we should update the abortWithuint64_t functions. 574 #define STUFF_FOR_CRASH_REGISTER1 "r11" 575 #define STUFF_FOR_CRASH_REGISTER2 "r10" 576 #define STUFF_FOR_CRASH_REGISTER3 "r9" 577 #define STUFF_FOR_CRASH_REGISTER4 "r8" 578 #define STUFF_FOR_CRASH_REGISTER5 "r15" 575 #define CRASH_GPR0 "r11" 576 #define CRASH_GPR1 "r10" 577 #define CRASH_GPR2 "r9" 578 #define CRASH_GPR3 "r8" 579 #define CRASH_GPR4 "r15" 580 #define CRASH_GPR5 "r14" 581 #define CRASH_GPR6 "r13" 579 582 580 583 #elif CPU(ARM64) // CPU(X86_64) 581 #define STUFF_REGISTER_FOR_CRASH(reg, info) __asm__ volatile ("mov " reg ", %0" : : "r" (static_cast<uint64_t>(info)) : reg) 584 585 #define CRASH_INST "brk #0" 582 586 583 587 // See comment above on the ordering. 584 #define STUFF_FOR_CRASH_REGISTER1 "x16" 585 #define STUFF_FOR_CRASH_REGISTER2 "x17" 586 #define STUFF_FOR_CRASH_REGISTER3 "x18" 587 #define STUFF_FOR_CRASH_REGISTER4 "x19" 588 #define STUFF_FOR_CRASH_REGISTER5 "x20" 588 #define CRASH_GPR0 "x16" 589 #define CRASH_GPR1 "x17" 590 #define CRASH_GPR2 "x18" 591 #define CRASH_GPR3 "x19" 592 #define CRASH_GPR4 "x20" 593 #define CRASH_GPR5 "x21" 594 #define CRASH_GPR6 "x22" 589 595 590 596 #endif // CPU(ARM64) 591 597 598 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5, uint64_t misc6) 599 { 600 register uint64_t reasonGPR asm(CRASH_GPR0) = reason; 601 register uint64_t misc1GPR asm(CRASH_GPR1) = misc1; 602 register uint64_t misc2GPR asm(CRASH_GPR2) = misc2; 603 register uint64_t misc3GPR asm(CRASH_GPR3) = misc3; 604 register uint64_t misc4GPR asm(CRASH_GPR4) = misc4; 605 register uint64_t misc5GPR asm(CRASH_GPR5) = misc5; 606 register uint64_t misc6GPR asm(CRASH_GPR6) = misc6; 607 __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR), "r"(misc4GPR), "r"(misc5GPR), "r"(misc6GPR)); 608 __builtin_unreachable(); 609 } 610 611 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5) 612 { 613 register uint64_t reasonGPR asm(CRASH_GPR0) = reason; 614 register uint64_t misc1GPR asm(CRASH_GPR1) = misc1; 615 register uint64_t misc2GPR asm(CRASH_GPR2) = misc2; 616 register uint64_t misc3GPR asm(CRASH_GPR3) = misc3; 617 register uint64_t misc4GPR asm(CRASH_GPR4) = misc4; 618 register uint64_t misc5GPR asm(CRASH_GPR5) = misc5; 619 __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR), "r"(misc4GPR), "r"(misc5GPR)); 620 __builtin_unreachable(); 621 } 622 592 623 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4) 593 624 { 594 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason); 595 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1); 596 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2); 597 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER4, misc3); 598 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER5, misc4); 599 CRASH(); 625 register uint64_t reasonGPR asm(CRASH_GPR0) = reason; 626 register uint64_t misc1GPR asm(CRASH_GPR1) = misc1; 627 register uint64_t misc2GPR asm(CRASH_GPR2) = misc2; 628 register uint64_t misc3GPR asm(CRASH_GPR3) = misc3; 629 register uint64_t misc4GPR asm(CRASH_GPR4) = misc4; 630 __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR), "r"(misc4GPR)); 631 __builtin_unreachable(); 600 632 } 601 633 602 634 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3) 603 635 { 604 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason); 605 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1); 606 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2); 607 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER4, misc3); 608 CRASH(); 636 register uint64_t reasonGPR asm(CRASH_GPR0) = reason; 637 register uint64_t misc1GPR asm(CRASH_GPR1) = misc1; 638 register uint64_t misc2GPR asm(CRASH_GPR2) = misc2; 639 register uint64_t misc3GPR asm(CRASH_GPR3) = misc3; 640 __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR)); 641 __builtin_unreachable(); 609 642 } 610 643 611 644 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2) 612 645 { 613 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason); 614 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1); 615 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2); 616 CRASH(); 646 register uint64_t reasonGPR asm(CRASH_GPR0) = reason; 647 register uint64_t misc1GPR asm(CRASH_GPR1) = misc1; 648 register uint64_t misc2GPR asm(CRASH_GPR2) = misc2; 649 __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR)); 650 __builtin_unreachable(); 617 651 } 618 652 619 653 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1) 620 654 { 621 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason); 622 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1); 623 CRASH(); 655 register uint64_t reasonGPR asm(CRASH_GPR0) = reason; 656 register uint64_t misc1GPR asm(CRASH_GPR1) = misc1; 657 __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR)); 658 __builtin_unreachable(); 624 659 } 625 660 626 661 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason) 627 662 { 628 STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason); 629 CRASH(); 663 register uint64_t reasonGPR asm(CRASH_GPR0) = reason; 664 __asm__ volatile (CRASH_INST : : "r"(reasonGPR)); 665 __builtin_unreachable(); 630 666 } 631 667 632 668 void WTFCrashWithInfo(int, const char*, const char*, int) 633 669 { 634 CRASH(); 670 __asm__ volatile (CRASH_INST : : ); 671 __builtin_unreachable(); 635 672 } 636 673 637 674 #else 638 675 676 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t) { CRASH(); } 677 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t) { CRASH(); } 639 678 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t) { CRASH(); } 640 679 void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t, uint64_t, uint64_t, uint64_t) { CRASH(); } -
trunk/Source/WTF/wtf/Assertions.h
r233577 r234335 290 290 #if ASSERT_DISABLED 291 291 292 #define ASSERT(assertion ) ((void)0)292 #define ASSERT(assertion, ...) ((void)0) 293 293 #define ASSERT_UNDER_CONSTEXPR_CONTEXT(assertion) ((void)0) 294 294 #define ASSERT_AT(assertion, file, line, function) ((void)0) 295 #define ASSERT_NOT_REACHED( ) ((void)0)295 #define ASSERT_NOT_REACHED(...) ((void)0) 296 296 #define ASSERT_NOT_IMPLEMENTED_YET() ((void)0) 297 297 #define ASSERT_IMPLIES(condition, assertion) ((void)0) 298 298 #define NO_RETURN_DUE_TO_ASSERT 299 299 300 #define ASSERT_UNUSED(variable, assertion ) ((void)variable)300 #define ASSERT_UNUSED(variable, assertion, ...) ((void)variable) 301 301 302 302 #if ENABLE(SECURITY_ASSERTIONS) … … 315 315 #else 316 316 317 #define ASSERT(assertion ) do { \317 #define ASSERT(assertion, ...) do { \ 318 318 if (!(assertion)) { \ 319 319 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \ 320 CRASH (); \320 CRASH_WITH_INFO(__VA_ARGS__); \ 321 321 } \ 322 322 } while (0) … … 336 336 } while (0) 337 337 338 #define ASSERT_NOT_REACHED( ) do { \338 #define ASSERT_NOT_REACHED(...) do { \ 339 339 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \ 340 CRASH (); \340 CRASH_WITH_INFO(__VA_ARGS__); \ 341 341 } while (0) 342 342 … … 353 353 } while (0) 354 354 355 #define ASSERT_UNUSED(variable, assertion ) ASSERT(assertion)355 #define ASSERT_UNUSED(variable, assertion, ...) ASSERT(assertion, __VA_ARGS__) 356 356 357 357 #define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH … … 511 511 512 512 #if ASSERT_DISABLED 513 #define RELEASE_ASSERT(assertion ) do { \513 #define RELEASE_ASSERT(assertion, ...) do { \ 514 514 if (UNLIKELY(!(assertion))) \ 515 CRASH (); \515 CRASH_WITH_INFO(__VA_ARGS__); \ 516 516 } while (0) 517 517 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion) 518 518 #define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) RELEASE_ASSERT(assertion) 519 #define RELEASE_ASSERT_NOT_REACHED( ) CRASH()520 #else 521 #define RELEASE_ASSERT(assertion ) ASSERT(assertion)519 #define RELEASE_ASSERT_NOT_REACHED(...) CRASH_WITH_INFO(__VA_ARGS__) 520 #else 521 #define RELEASE_ASSERT(assertion, ...) ASSERT(assertion, __VA_ARGS__) 522 522 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__) 523 523 #define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT_WITH_SECURITY_IMPLICATION(assertion) 524 524 #define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED() 525 525 #endif 526 527 #ifdef __cplusplus 528 529 // The combination of line, file, function, and counter should be a unique number per call to this crash. This tricks the compiler into not coalescing calls to WTFCrashWithInfo. 530 // The easiest way to fill these values per translation unit is to pass __LINE__, __FILE__, WTF_PRETTY_FUNCTION, and __COUNTER__. 531 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5, uint64_t misc6); 532 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5); 533 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4); 534 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3); 535 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2); 536 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1); 537 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason); 538 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter); 539 540 541 namespace WTF { 542 inline void isIntegralType() { } 543 544 template<typename T, typename... Types> 545 void isIntegralType(T, Types... types) 546 { 547 static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "All types need to be integral bitwise_cast to integral type for logging"); 548 isIntegralType(types...); 549 } 550 } 551 552 inline void compilerFenceForCrash() 553 { 554 #if OS(WINDOWS) && !COMPILER(GCC_OR_CLANG) 555 _ReadWriteBarrier(); 556 #else 557 asm volatile("" ::: "memory"); 558 #endif 559 } 560 561 #ifndef CRASH_WITH_INFO 562 // This is useful if you are going to stuff data into registers before crashing. Like the crashWithInfo functions below... 563 // GCC doesn't like the ##__VA_ARGS__ here since this macro is called from another macro so we just CRASH instead there. 564 #if COMPILER(CLANG) || COMPILER(MSVC) 565 #define CRASH_WITH_INFO(...) do { \ 566 WTF::isIntegralType(__VA_ARGS__); \ 567 compilerFenceForCrash(); \ 568 WTFCrashWithInfo(__LINE__, __FILE__, WTF_PRETTY_FUNCTION, __COUNTER__, ##__VA_ARGS__); \ 569 } while (false) 570 #else 571 #define CRASH_WITH_INFO(...) CRASH() 572 #endif 573 #endif // CRASH_WITH_INFO 574 575 #ifndef CRASH_WITH_SECURITY_IMPLICATION_AND_INFO 576 #define CRASH_WITH_SECURITY_IMPLICATION_AND_INFO CRASH_WITH_INFO 577 #endif // CRASH_WITH_SECURITY_IMPLICATION_AND_INFO 578 579 #else /* not __cplusplus */ 580 581 #ifndef CRASH_WITH_INFO 582 #define CRASH_WITH_INFO() CRASH() 583 #endif 584 585 #endif /* __cplusplus */ 526 586 527 587 /* UNREACHABLE_FOR_PLATFORM */ … … 543 603 #endif 544 604 545 #ifdef __cplusplus546 547 // The combination of line, file, function, and counter should be a unique number per call to this crash. This tricks the compiler into not coalescing calls to WTFCrashWithInfo.548 // The easiest way to fill these values per translation unit is to pass __LINE__, __FILE__, WTF_PRETTY_FUNCTION, and __COUNTER__.549 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4);550 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3);551 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2);552 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1);553 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason);554 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter);555 556 557 namespace WTF {558 inline void isIntegralType() { }559 560 template<typename T, typename... Types>561 void isIntegralType(T, Types... types)562 {563 static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "All types need to be integral bitwise_cast to integral type for logging");564 isIntegralType(types...);565 }566 }567 568 inline void compilerFenceForCrash()569 {570 #if OS(WINDOWS) && !COMPILER(GCC_OR_CLANG)571 _ReadWriteBarrier();572 #else573 asm volatile("" ::: "memory");574 #endif575 }576 577 #ifndef CRASH_WITH_INFO578 // This is useful if you are going to stuff data into registers before crashing. Like the crashWithInfo functions below...579 // GCC doesn't like the ##__VA_ARGS__ here since this macro is called from another macro so we just CRASH instead there.580 #if COMPILER(CLANG) || COMPILER(MSVC)581 #define CRASH_WITH_INFO(...) do { \582 WTF::isIntegralType(__VA_ARGS__); \583 compilerFenceForCrash(); \584 WTFCrashWithInfo(__LINE__, __FILE__, WTF_PRETTY_FUNCTION, __COUNTER__, ##__VA_ARGS__); \585 } while (false)586 #else587 #define CRASH_WITH_INFO(...) CRASH()588 #endif589 #endif // CRASH_WITH_INFO590 591 #ifndef CRASH_WITH_SECURITY_IMPLICATION_AND_INFO592 #define CRASH_WITH_SECURITY_IMPLICATION_AND_INFO CRASH_WITH_INFO593 #endif // CRASH_WITH_SECURITY_IMPLICATION_AND_INFO594 595 #endif // __cplusplus596 597 605 #endif /* WTF_Assertions_h */
Note:
See TracChangeset
for help on using the changeset viewer.