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

Side by Side Diff: components/crash/content/app/breakpad_linux.cc

Issue 2635493002: Suppress browser microdump when renderer crashes in multiprocess WebView. (Closed)
Patch Set: reorder functions. again. Created 3 years, 11 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 | « components/crash/content/app/breakpad_linux.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 // For linux_syscall_support.h. This makes it safe to call embedded system 5 // For linux_syscall_support.h. This makes it safe to call embedded system
6 // calls when in seccomp mode. 6 // calls when in seccomp mode.
7 7
8 #include "components/crash/content/app/breakpad_linux.h" 8 #include "components/crash/content/app/breakpad_linux.h"
9 9
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 bool g_is_crash_reporter_enabled = false; 94 bool g_is_crash_reporter_enabled = false;
95 uint64_t g_process_start_time = 0; 95 uint64_t g_process_start_time = 0;
96 pid_t g_pid = 0; 96 pid_t g_pid = 0;
97 char* g_crash_log_path = nullptr; 97 char* g_crash_log_path = nullptr;
98 ExceptionHandler* g_breakpad = nullptr; 98 ExceptionHandler* g_breakpad = nullptr;
99 99
100 #if defined(ADDRESS_SANITIZER) 100 #if defined(ADDRESS_SANITIZER)
101 const char* g_asan_report_str = nullptr; 101 const char* g_asan_report_str = nullptr;
102 #endif 102 #endif
103 #if defined(OS_ANDROID) 103 #if defined(OS_ANDROID)
104 #define G_DUMPS_SUPPRESSED_MAGIC 0x5AFECEDE
105 uint32_t g_dumps_suppressed = 0;
104 char* g_process_type = nullptr; 106 char* g_process_type = nullptr;
105 ExceptionHandler* g_microdump = nullptr; 107 ExceptionHandler* g_microdump = nullptr;
106 int g_signal_code_pipe_fd = -1; 108 int g_signal_code_pipe_fd = -1;
107 109
108 class MicrodumpInfo { 110 class MicrodumpInfo {
109 public: 111 public:
110 MicrodumpInfo() 112 MicrodumpInfo()
111 : microdump_build_fingerprint_(nullptr), 113 : microdump_build_fingerprint_(nullptr),
112 microdump_product_info_(nullptr), 114 microdump_product_info_(nullptr),
113 microdump_gpu_fingerprint_(nullptr) {} 115 microdump_gpu_fingerprint_(nullptr) {}
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 my_strlcat(buf, " v", kMaxSize); 570 my_strlcat(buf, " v", kMaxSize);
569 my_strlcat(buf, android_build_info->package_version_code(), kMaxSize); 571 my_strlcat(buf, android_build_info->package_version_code(), kMaxSize);
570 my_strlcat(buf, " (", kMaxSize); 572 my_strlcat(buf, " (", kMaxSize);
571 my_strlcat(buf, android_build_info->package_version_name(), kMaxSize); 573 my_strlcat(buf, android_build_info->package_version_name(), kMaxSize);
572 my_strlcat(buf, ")", kMaxSize); 574 my_strlcat(buf, ")", kMaxSize);
573 575
574 writer.AddPairString("package", buf); 576 writer.AddPairString("package", buf);
575 } 577 }
576 #endif // defined(OS_ANDROID) 578 #endif // defined(OS_ANDROID)
577 579
578 void DumpProcess() {
579 if (g_breakpad)
580 g_breakpad->WriteMinidump();
581
582 #if defined(OS_ANDROID)
583 // If microdumps are enabled write also a microdump on the system log.
584 if (g_microdump)
585 g_microdump->WriteMinidump();
586 #endif
587 }
588
589 #if defined(OS_ANDROID) 580 #if defined(OS_ANDROID)
590 const char kGoogleBreakpad[] = "google-breakpad"; 581 const char kGoogleBreakpad[] = "google-breakpad";
591 #endif 582 #endif
592 583
593 size_t WriteLog(const char* buf, size_t nbytes) { 584 size_t WriteLog(const char* buf, size_t nbytes) {
594 #if defined(OS_ANDROID) 585 #if defined(OS_ANDROID)
595 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf); 586 return __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, buf);
596 #else 587 #else
597 return sys_write(2, buf, nbytes); 588 return sys_write(2, buf, nbytes);
598 #endif 589 #endif
599 } 590 }
600 591
601 size_t WriteNewline() { 592 size_t WriteNewline() {
602 return WriteLog("\n", 1); 593 return WriteLog("\n", 1);
603 } 594 }
604 595
605 #if defined(OS_ANDROID) 596 #if defined(OS_ANDROID)
597 bool ShouldGenerateDump(void *context) {
598 return g_dumps_suppressed != G_DUMPS_SUPPRESSED_MAGIC;
599 }
600
606 void AndroidLogWriteHorizontalRule() { 601 void AndroidLogWriteHorizontalRule() {
607 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, 602 __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad,
608 "### ### ### ### ### ### ### ### ### ### ### ### ###"); 603 "### ### ### ### ### ### ### ### ### ### ### ### ###");
609 } 604 }
610 605
611 // Android's native crash handler outputs a diagnostic tombstone to the device 606 // Android's native crash handler outputs a diagnostic tombstone to the device
612 // log. By returning false from the HandlerCallbacks, breakpad will reinstall 607 // log. By returning false from the HandlerCallbacks, breakpad will reinstall
613 // the previous (i.e. native) signal handlers before returning from its own 608 // the previous (i.e. native) signal handlers before returning from its own
614 // handler. A Chrome build fingerprint is written to the log, so that the 609 // handler. A Chrome build fingerprint is written to the log, so that the
615 // specific build of Chrome and the location of the archived Chrome symbols can 610 // specific build of Chrome and the location of the archived Chrome symbols can
(...skipping 21 matching lines...) Expand all
637 // TODO(cjhopman): There should be some way to recover the crash stack from 632 // TODO(cjhopman): There should be some way to recover the crash stack from
638 // non-uploading user clients. See http://crbug.com/273706. 633 // non-uploading user clients. See http://crbug.com/273706.
639 __android_log_write(ANDROID_LOG_WARN, 634 __android_log_write(ANDROID_LOG_WARN,
640 kGoogleBreakpad, 635 kGoogleBreakpad,
641 "Tombstones are disabled on JB MR2+ user builds."); 636 "Tombstones are disabled on JB MR2+ user builds.");
642 AndroidLogWriteHorizontalRule(); 637 AndroidLogWriteHorizontalRule();
643 return true; 638 return true;
644 } 639 }
645 return false; 640 return false;
646 } 641 }
647 #endif 642
643 bool MicrodumpCrashDone(const MinidumpDescriptor& minidump,
644 void* context,
645 bool succeeded) {
646 // WARNING: this code runs in a compromised context. It may not call into
647 // libc nor allocate memory normally.
648 if (!succeeded) {
649 static const char msg[] = "Microdump crash handler failed.\n";
650 WriteLog(msg, sizeof(msg) - 1);
651 return false;
652 }
653
654 const bool is_browser_process = (context != nullptr);
655 return FinalizeCrashDoneAndroid(is_browser_process);
656 }
657 #endif // defined(OS_ANDROID)
648 658
649 bool CrashDone(const MinidumpDescriptor& minidump, 659 bool CrashDone(const MinidumpDescriptor& minidump,
650 const bool upload, 660 const bool upload,
651 const bool should_finalize, 661 const bool should_finalize,
652 const bool succeeded) { 662 const bool succeeded) {
653 // WARNING: this code runs in a compromised context. It may not call into 663 // WARNING: this code runs in a compromised context. It may not call into
654 // libc nor allocate memory normally. 664 // libc nor allocate memory normally.
655 if (!succeeded) { 665 if (!succeeded) {
656 const char msg[] = "Failed to generate minidump."; 666 const char msg[] = "Failed to generate minidump.";
657 WriteLog(msg, sizeof(msg) - 1); 667 WriteLog(msg, sizeof(msg) - 1);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 718
709 #if !defined(OS_ANDROID) 719 #if !defined(OS_ANDROID)
710 // Wrapper function, do not add more code here. 720 // Wrapper function, do not add more code here.
711 bool CrashDoneUpload(const MinidumpDescriptor& minidump, 721 bool CrashDoneUpload(const MinidumpDescriptor& minidump,
712 void* context, 722 void* context,
713 bool succeeded) { 723 bool succeeded) {
714 return CrashDone(minidump, true, true, succeeded); 724 return CrashDone(minidump, true, true, succeeded);
715 } 725 }
716 #endif 726 #endif
717 727
728 void DumpProcess() {
729 #if defined(OS_ANDROID)
730 // Don't use g_breakpad and g_microdump directly here, because their
731 // output might currently be suppressed.
732 if (g_breakpad) {
733 ExceptionHandler(g_breakpad->minidump_descriptor(),
734 nullptr,
735 CrashDoneNoUpload,
736 nullptr,
737 false, -1).WriteMinidump();
738 }
739 // If microdumps are enabled write also a microdump on the system log.
740 if (g_microdump) {
741 ExceptionHandler(g_microdump->minidump_descriptor(),
742 nullptr,
743 MicrodumpCrashDone,
744 nullptr,
745 false, -1).WriteMinidump();
746 }
747 #else
748 if (g_breakpad)
749 g_breakpad->WriteMinidump();
750 #endif
751 }
752
718 #if defined(ADDRESS_SANITIZER) 753 #if defined(ADDRESS_SANITIZER)
719 extern "C" 754 extern "C"
720 void __asan_set_error_report_callback(void (*cb)(const char*)); 755 void __asan_set_error_report_callback(void (*cb)(const char*));
721 756
722 extern "C" 757 extern "C"
723 void AsanLinuxBreakpadCallback(const char* report) { 758 void AsanLinuxBreakpadCallback(const char* report) {
724 g_asan_report_str = report; 759 g_asan_report_str = report;
725 // Send minidump here. 760 // Send minidump here.
726 g_breakpad->SimulateSignalDelivery(SIGKILL); 761 g_breakpad->SimulateSignalDelivery(SIGKILL);
727 } 762 }
(...skipping 21 matching lines...) Expand all
749 minidump_descriptor.set_size_limit(-1); // unlimited. 784 minidump_descriptor.set_size_limit(-1); // unlimited.
750 } else { 785 } else {
751 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); 786 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize);
752 } 787 }
753 #if defined(OS_ANDROID) 788 #if defined(OS_ANDROID)
754 unattended = true; // Android never uploads directly. 789 unattended = true; // Android never uploads directly.
755 #endif 790 #endif
756 if (unattended) { 791 if (unattended) {
757 g_breakpad = new ExceptionHandler( 792 g_breakpad = new ExceptionHandler(
758 minidump_descriptor, 793 minidump_descriptor,
794 #if defined(OS_ANDROID)
795 ShouldGenerateDump,
796 #else
759 nullptr, 797 nullptr,
798 #endif
760 CrashDoneNoUpload, 799 CrashDoneNoUpload,
761 nullptr, 800 nullptr,
762 true, // Install handlers. 801 true, // Install handlers.
763 -1); // Server file descriptor. -1 for in-process. 802 -1); // Server file descriptor. -1 for in-process.
764 return; 803 return;
765 } 804 }
766 805
767 #if !defined(OS_ANDROID) 806 #if !defined(OS_ANDROID)
768 // Attended mode 807 // Attended mode
769 g_breakpad = new ExceptionHandler( 808 g_breakpad = new ExceptionHandler(
770 minidump_descriptor, 809 minidump_descriptor,
771 nullptr, 810 nullptr,
772 CrashDoneUpload, 811 CrashDoneUpload,
773 nullptr, 812 nullptr,
774 true, // Install handlers. 813 true, // Install handlers.
775 -1); // Server file descriptor. -1 for in-process. 814 -1); // Server file descriptor. -1 for in-process.
776 #endif 815 #endif
777 } 816 }
778 817
779 #if defined(OS_ANDROID) 818 #if defined(OS_ANDROID)
780 bool MicrodumpCrashDone(const MinidumpDescriptor& minidump,
781 void* context,
782 bool succeeded) {
783 // WARNING: this code runs in a compromised context. It may not call into
784 // libc nor allocate memory normally.
785 if (!succeeded) {
786 static const char msg[] = "Microdump crash handler failed.\n";
787 WriteLog(msg, sizeof(msg) - 1);
788 return false;
789 }
790
791 const bool is_browser_process = (context != nullptr);
792 return FinalizeCrashDoneAndroid(is_browser_process);
793 }
794
795 bool WriteSignalCodeToPipe(const void* crash_context, 819 bool WriteSignalCodeToPipe(const void* crash_context,
796 size_t crash_context_size, 820 size_t crash_context_size,
797 void* context) { 821 void* context) {
798 if (g_signal_code_pipe_fd == -1) 822 if (g_signal_code_pipe_fd == -1)
799 return false; 823 return false;
800 int signo = INT_MAX; 824 int signo = INT_MAX;
801 if (crash_context_size == sizeof(ExceptionHandler::CrashContext)) { 825 if (crash_context_size == sizeof(ExceptionHandler::CrashContext)) {
802 const ExceptionHandler::CrashContext* eh_context = 826 const ExceptionHandler::CrashContext* eh_context =
803 static_cast<const ExceptionHandler::CrashContext*>(crash_context); 827 static_cast<const ExceptionHandler::CrashContext*>(crash_context);
804 signo = eh_context->siginfo.si_signo; 828 signo = eh_context->siginfo.si_signo;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 return; 882 return;
859 } 883 }
860 SetProcessStartTime(); 884 SetProcessStartTime();
861 g_pid = getpid(); 885 g_pid = getpid();
862 886
863 g_is_crash_reporter_enabled = true; 887 g_is_crash_reporter_enabled = true;
864 // Save the process type (it is leaked). 888 // Save the process type (it is leaked).
865 const size_t process_type_len = process_type.size() + 1; 889 const size_t process_type_len = process_type.size() + 1;
866 g_process_type = new char[process_type_len]; 890 g_process_type = new char[process_type_len];
867 strncpy(g_process_type, process_type.c_str(), process_type_len); 891 strncpy(g_process_type, process_type.c_str(), process_type_len);
868 new google_breakpad::ExceptionHandler(MinidumpDescriptor(minidump_fd), 892 new ExceptionHandler(MinidumpDescriptor(minidump_fd), ShouldGenerateDump,
869 nullptr, CrashDoneInProcessNoUpload, nullptr, true, -1); 893 CrashDoneInProcessNoUpload, nullptr, true, -1);
870 } 894 }
871 895
872 void MicrodumpInfo::SetGpuFingerprint(const std::string& gpu_fingerprint) { 896 void MicrodumpInfo::SetGpuFingerprint(const std::string& gpu_fingerprint) {
873 DCHECK(thread_checker_.CalledOnValidThread()); 897 DCHECK(thread_checker_.CalledOnValidThread());
874 DCHECK(!microdump_gpu_fingerprint_); 898 DCHECK(!microdump_gpu_fingerprint_);
875 microdump_gpu_fingerprint_ = strdup(gpu_fingerprint.c_str()); 899 microdump_gpu_fingerprint_ = strdup(gpu_fingerprint.c_str());
876 ANNOTATE_LEAKING_OBJECT_PTR(microdump_gpu_fingerprint_); 900 ANNOTATE_LEAKING_OBJECT_PTR(microdump_gpu_fingerprint_);
877 901
878 if (g_microdump) { 902 if (g_microdump) {
879 MinidumpDescriptor minidump_descriptor(g_microdump->minidump_descriptor()); 903 MinidumpDescriptor minidump_descriptor(g_microdump->minidump_descriptor());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 descriptor.microdump_extra_info()->build_fingerprint = 940 descriptor.microdump_extra_info()->build_fingerprint =
917 microdump_build_fingerprint_; 941 microdump_build_fingerprint_;
918 } 942 }
919 943
920 if (microdump_gpu_fingerprint_) { 944 if (microdump_gpu_fingerprint_) {
921 descriptor.microdump_extra_info()->gpu_fingerprint = 945 descriptor.microdump_extra_info()->gpu_fingerprint =
922 microdump_gpu_fingerprint_; 946 microdump_gpu_fingerprint_;
923 } 947 }
924 948
925 g_microdump = 949 g_microdump =
926 new ExceptionHandler(descriptor, nullptr, MicrodumpCrashDone, 950 new ExceptionHandler(descriptor, ShouldGenerateDump, MicrodumpCrashDone,
927 reinterpret_cast<void*>(is_browser_process), 951 reinterpret_cast<void*>(is_browser_process),
928 true, // Install handlers. 952 true, // Install handlers.
929 -1); // Server file descriptor. -1 for in-process. 953 -1); // Server file descriptor. -1 for in-process.
930 954
931 if (process_type != kWebViewSingleProcessType && 955 if (process_type != kWebViewSingleProcessType &&
932 process_type != kBrowserProcessType && 956 process_type != kBrowserProcessType &&
933 !process_type.empty()) { 957 !process_type.empty()) {
934 g_signal_code_pipe_fd = 958 g_signal_code_pipe_fd =
935 GetCrashReporterClient()->GetAndroidCrashSignalFD(); 959 GetCrashReporterClient()->GetAndroidCrashSignalFD();
936 if (g_signal_code_pipe_fd != -1) 960 if (g_signal_code_pipe_fd != -1)
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 1963
1940 void GenerateMinidumpOnDemandForAndroid(int dump_fd) { 1964 void GenerateMinidumpOnDemandForAndroid(int dump_fd) {
1941 if (dump_fd >= 0) { 1965 if (dump_fd >= 0) {
1942 MinidumpDescriptor minidump_descriptor(dump_fd); 1966 MinidumpDescriptor minidump_descriptor(dump_fd);
1943 minidump_descriptor.set_size_limit(-1); 1967 minidump_descriptor.set_size_limit(-1);
1944 ExceptionHandler(minidump_descriptor, nullptr, MinidumpGenerated, nullptr, 1968 ExceptionHandler(minidump_descriptor, nullptr, MinidumpGenerated, nullptr,
1945 false, -1) 1969 false, -1)
1946 .WriteMinidump(); 1970 .WriteMinidump();
1947 } 1971 }
1948 } 1972 }
1973
1974 void SuppressDumpGeneration() {
1975 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC;
1976 }
1949 #endif // OS_ANDROID 1977 #endif // OS_ANDROID
1950 1978
1951 bool IsCrashReporterEnabled() { 1979 bool IsCrashReporterEnabled() {
1952 return g_is_crash_reporter_enabled; 1980 return g_is_crash_reporter_enabled;
1953 } 1981 }
1954 1982
1955 } // namespace breakpad 1983 } // namespace breakpad
OLDNEW
« no previous file with comments | « components/crash/content/app/breakpad_linux.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698