| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |