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 #include "chrome/app/breakpad_win.h" | 5 #include "chrome/app/breakpad_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <shellapi.h> | 8 #include <shellapi.h> |
9 #include <tchar.h> | 9 #include <tchar.h> |
10 #include <userenv.h> | 10 #include <userenv.h> |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 google_breakpad::CustomInfoEntry* entry = NULL; | 694 google_breakpad::CustomInfoEntry* entry = NULL; |
695 if (it == g_dynamic_entries->end()) { | 695 if (it == g_dynamic_entries->end()) { |
696 if (g_dynamic_keys_offset >= g_dynamic_entries_count) | 696 if (g_dynamic_keys_offset >= g_dynamic_entries_count) |
697 return; | 697 return; |
698 entry = &(*g_custom_entries)[g_dynamic_keys_offset++]; | 698 entry = &(*g_custom_entries)[g_dynamic_keys_offset++]; |
699 g_dynamic_entries->insert(std::make_pair(key_string, entry)); | 699 g_dynamic_entries->insert(std::make_pair(key_string, entry)); |
700 } else { | 700 } else { |
701 entry = it->second; | 701 entry = it->second; |
702 } | 702 } |
703 | 703 |
704 entry->set(UTF8ToWide(key).data(), UTF8ToWide(value).data()); | 704 entry->set(base::UTF8ToWide(key).data(), base::UTF8ToWide(value).data()); |
705 } | 705 } |
706 | 706 |
707 void ClearCrashKeyValue(const base::StringPiece& key) { | 707 void ClearCrashKeyValue(const base::StringPiece& key) { |
708 DynamicEntriesMap::iterator it = g_dynamic_entries->find(key.as_string()); | 708 DynamicEntriesMap::iterator it = g_dynamic_entries->find(key.as_string()); |
709 if (it == g_dynamic_entries->end()) | 709 if (it == g_dynamic_entries->end()) |
710 return; | 710 return; |
711 | 711 |
712 it->second->set_value(NULL); | 712 it->second->set_value(NULL); |
713 } | 713 } |
714 | 714 |
(...skipping 21 matching lines...) Expand all Loading... |
736 chrome::RESULT_CODE_RESPAWN_FAILED); | 736 chrome::RESULT_CODE_RESPAWN_FAILED); |
737 } | 737 } |
738 | 738 |
739 return true; | 739 return true; |
740 } | 740 } |
741 | 741 |
742 // This function is executed by the child process that DumpDoneCallback() | 742 // This function is executed by the child process that DumpDoneCallback() |
743 // spawned and basically just shows the 'chrome has crashed' dialog if | 743 // spawned and basically just shows the 'chrome has crashed' dialog if |
744 // the CHROME_CRASHED environment variable is present. | 744 // the CHROME_CRASHED environment variable is present. |
745 bool ShowRestartDialogIfCrashed(bool* exit_now) { | 745 bool ShowRestartDialogIfCrashed(bool* exit_now) { |
746 if (!::GetEnvironmentVariableW(ASCIIToWide(env_vars::kShowRestart).c_str(), | 746 if (!::GetEnvironmentVariableW( |
747 NULL, 0)) { | 747 base::ASCIIToWide(env_vars::kShowRestart).c_str(), NULL, 0)) { |
748 return false; | 748 return false; |
749 } | 749 } |
750 | 750 |
751 // Only show this for the browser process. See crbug.com/132119. | 751 // Only show this for the browser process. See crbug.com/132119. |
752 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 752 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
753 std::string process_type = | 753 std::string process_type = |
754 command_line.GetSwitchValueASCII(switches::kProcessType); | 754 command_line.GetSwitchValueASCII(switches::kProcessType); |
755 if (!process_type.empty()) { | 755 if (!process_type.empty()) { |
756 return false; | 756 return false; |
757 } | 757 } |
758 | 758 |
759 DWORD len = ::GetEnvironmentVariableW( | 759 DWORD len = ::GetEnvironmentVariableW( |
760 ASCIIToWide(env_vars::kRestartInfo).c_str(), NULL, 0); | 760 base::ASCIIToWide(env_vars::kRestartInfo).c_str(), NULL, 0); |
761 if (!len) | 761 if (!len) |
762 return true; | 762 return true; |
763 | 763 |
764 wchar_t* restart_data = new wchar_t[len + 1]; | 764 wchar_t* restart_data = new wchar_t[len + 1]; |
765 ::GetEnvironmentVariableW(ASCIIToWide(env_vars::kRestartInfo).c_str(), | 765 ::GetEnvironmentVariableW(base::ASCIIToWide(env_vars::kRestartInfo).c_str(), |
766 restart_data, len); | 766 restart_data, len); |
767 restart_data[len] = 0; | 767 restart_data[len] = 0; |
768 // The CHROME_RESTART var contains the dialog strings separated by '|'. | 768 // The CHROME_RESTART var contains the dialog strings separated by '|'. |
769 // See ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment() | 769 // See ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment() |
770 // for details. | 770 // for details. |
771 std::vector<std::wstring> dlg_strings; | 771 std::vector<std::wstring> dlg_strings; |
772 base::SplitString(restart_data, L'|', &dlg_strings); | 772 base::SplitString(restart_data, L'|', &dlg_strings); |
773 delete[] restart_data; | 773 delete[] restart_data; |
774 if (dlg_strings.size() < 3) | 774 if (dlg_strings.size() < 3) |
775 return true; | 775 return true; |
776 | 776 |
777 // If the UI layout is right-to-left, we need to pass the appropriate MB_XXX | 777 // If the UI layout is right-to-left, we need to pass the appropriate MB_XXX |
778 // flags so that an RTL message box is displayed. | 778 // flags so that an RTL message box is displayed. |
779 UINT flags = MB_OKCANCEL | MB_ICONWARNING; | 779 UINT flags = MB_OKCANCEL | MB_ICONWARNING; |
780 if (dlg_strings[2] == ASCIIToWide(env_vars::kRtlLocale)) | 780 if (dlg_strings[2] == base::ASCIIToWide(env_vars::kRtlLocale)) |
781 flags |= MB_RIGHT | MB_RTLREADING; | 781 flags |= MB_RIGHT | MB_RTLREADING; |
782 | 782 |
783 return WrapMessageBoxWithSEH(dlg_strings[1].c_str(), dlg_strings[0].c_str(), | 783 return WrapMessageBoxWithSEH(dlg_strings[1].c_str(), dlg_strings[0].c_str(), |
784 flags, exit_now); | 784 flags, exit_now); |
785 } | 785 } |
786 | 786 |
787 // Crashes the process after generating a dump for the provided exception. Note | 787 // Crashes the process after generating a dump for the provided exception. Note |
788 // that the crash reporter should be initialized before calling this function | 788 // that the crash reporter should be initialized before calling this function |
789 // for it to do anything. | 789 // for it to do anything. |
790 extern "C" int __declspec(dllexport) CrashForException( | 790 extern "C" int __declspec(dllexport) CrashForException( |
791 EXCEPTION_POINTERS* info) { | 791 EXCEPTION_POINTERS* info) { |
792 if (g_breakpad) { | 792 if (g_breakpad) { |
793 g_breakpad->WriteMinidumpForException(info); | 793 g_breakpad->WriteMinidumpForException(info); |
794 if (g_crash_analysis) | 794 if (g_crash_analysis) |
795 g_crash_analysis->Analyze(info); | 795 g_crash_analysis->Analyze(info); |
796 ::TerminateProcess(::GetCurrentProcess(), content::RESULT_CODE_KILLED); | 796 ::TerminateProcess(::GetCurrentProcess(), content::RESULT_CODE_KILLED); |
797 } | 797 } |
798 return EXCEPTION_CONTINUE_SEARCH; | 798 return EXCEPTION_CONTINUE_SEARCH; |
799 } | 799 } |
800 | 800 |
801 // Determine whether configuration management allows loading the crash reporter. | 801 // Determine whether configuration management allows loading the crash reporter. |
802 // Since the configuration management infrastructure is not initialized at this | 802 // Since the configuration management infrastructure is not initialized at this |
803 // point, we read the corresponding registry key directly. The return status | 803 // point, we read the corresponding registry key directly. The return status |
804 // indicates whether policy data was successfully read. If it is true, |result| | 804 // indicates whether policy data was successfully read. If it is true, |result| |
805 // contains the value set by policy. | 805 // contains the value set by policy. |
806 static bool MetricsReportingControlledByPolicy(bool* result) { | 806 static bool MetricsReportingControlledByPolicy(bool* result) { |
807 std::wstring key_name = UTF8ToWide(policy::key::kMetricsReportingEnabled); | 807 std::wstring key_name = |
| 808 base::UTF8ToWide(policy::key::kMetricsReportingEnabled); |
808 DWORD value = 0; | 809 DWORD value = 0; |
809 base::win::RegKey hklm_policy_key(HKEY_LOCAL_MACHINE, | 810 base::win::RegKey hklm_policy_key(HKEY_LOCAL_MACHINE, |
810 policy::kRegistryMandatorySubKey, KEY_READ); | 811 policy::kRegistryMandatorySubKey, KEY_READ); |
811 if (hklm_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) { | 812 if (hklm_policy_key.ReadValueDW(key_name.c_str(), &value) == ERROR_SUCCESS) { |
812 *result = value != 0; | 813 *result = value != 0; |
813 return true; | 814 return true; |
814 } | 815 } |
815 | 816 |
816 base::win::RegKey hkcu_policy_key(HKEY_CURRENT_USER, | 817 base::win::RegKey hkcu_policy_key(HKEY_CURRENT_USER, |
817 policy::kRegistryMandatorySubKey, KEY_READ); | 818 policy::kRegistryMandatorySubKey, KEY_READ); |
(...skipping 26 matching lines...) Expand all Loading... |
844 | 845 |
845 // Check whether configuration management controls crash reporting. | 846 // Check whether configuration management controls crash reporting. |
846 bool crash_reporting_enabled = true; | 847 bool crash_reporting_enabled = true; |
847 bool controlled_by_policy = | 848 bool controlled_by_policy = |
848 MetricsReportingControlledByPolicy(&crash_reporting_enabled); | 849 MetricsReportingControlledByPolicy(&crash_reporting_enabled); |
849 | 850 |
850 const CommandLine& command = *CommandLine::ForCurrentProcess(); | 851 const CommandLine& command = *CommandLine::ForCurrentProcess(); |
851 bool use_crash_service = !controlled_by_policy && | 852 bool use_crash_service = !controlled_by_policy && |
852 ((command.HasSwitch(switches::kNoErrorDialogs) || | 853 ((command.HasSwitch(switches::kNoErrorDialogs) || |
853 GetEnvironmentVariable( | 854 GetEnvironmentVariable( |
854 ASCIIToWide(env_vars::kHeadless).c_str(), NULL, 0))); | 855 base::ASCIIToWide(env_vars::kHeadless).c_str(), NULL, 0))); |
855 | 856 |
856 std::wstring pipe_name; | 857 std::wstring pipe_name; |
857 if (use_crash_service) { | 858 if (use_crash_service) { |
858 // Crash reporting is done by crash_service.exe. | 859 // Crash reporting is done by crash_service.exe. |
859 pipe_name = kChromePipeName; | 860 pipe_name = kChromePipeName; |
860 } else { | 861 } else { |
861 // We want to use the Google Update crash reporting. We need to check if the | 862 // We want to use the Google Update crash reporting. We need to check if the |
862 // user allows it first (in case the administrator didn't already decide | 863 // user allows it first (in case the administrator didn't already decide |
863 // via policy). | 864 // via policy). |
864 if (!controlled_by_policy) | 865 if (!controlled_by_policy) |
(...skipping 15 matching lines...) Expand all Loading... |
880 if (!base::win::GetUserSidString(&user_sid)) { | 881 if (!base::win::GetUserSidString(&user_sid)) { |
881 return; | 882 return; |
882 } | 883 } |
883 } else { | 884 } else { |
884 user_sid = kSystemPrincipalSid; | 885 user_sid = kSystemPrincipalSid; |
885 } | 886 } |
886 | 887 |
887 pipe_name = kGoogleUpdatePipeName; | 888 pipe_name = kGoogleUpdatePipeName; |
888 pipe_name += user_sid; | 889 pipe_name += user_sid; |
889 } | 890 } |
890 env->SetVar(kPipeNameVar, WideToASCII(pipe_name)); | 891 env->SetVar(kPipeNameVar, base::WideToASCII(pipe_name)); |
891 } | 892 } |
892 | 893 |
893 void InitCrashReporter() { | 894 void InitCrashReporter() { |
894 const CommandLine& command = *CommandLine::ForCurrentProcess(); | 895 const CommandLine& command = *CommandLine::ForCurrentProcess(); |
895 if (command.HasSwitch(switches::kDisableBreakpad)) | 896 if (command.HasSwitch(switches::kDisableBreakpad)) |
896 return; | 897 return; |
897 | 898 |
898 // Disable the message box for assertions. | 899 // Disable the message box for assertions. |
899 _CrtSetReportMode(_CRT_ASSERT, 0); | 900 _CrtSetReportMode(_CRT_ASSERT, 0); |
900 | 901 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 std::string pipe_name_ascii; | 940 std::string pipe_name_ascii; |
940 if (!env->GetVar(kPipeNameVar, &pipe_name_ascii)) { | 941 if (!env->GetVar(kPipeNameVar, &pipe_name_ascii)) { |
941 // Breakpad is not enabled. Configuration is managed or the user | 942 // Breakpad is not enabled. Configuration is managed or the user |
942 // did not allow Google Update to send crashes. We need to use | 943 // did not allow Google Update to send crashes. We need to use |
943 // our default crash handler instead, but only for the | 944 // our default crash handler instead, but only for the |
944 // browser/service processes. | 945 // browser/service processes. |
945 if (default_filter) | 946 if (default_filter) |
946 InitDefaultCrashCallback(default_filter); | 947 InitDefaultCrashCallback(default_filter); |
947 return; | 948 return; |
948 } | 949 } |
949 std::wstring pipe_name = ASCIIToWide(pipe_name_ascii); | 950 std::wstring pipe_name = base::ASCIIToWide(pipe_name_ascii); |
950 | 951 |
951 #ifdef _WIN64 | 952 #ifdef _WIN64 |
952 // The protocol for connecting to the out-of-process Breakpad crash | 953 // The protocol for connecting to the out-of-process Breakpad crash |
953 // reporter is different for x86-32 and x86-64: the message sizes | 954 // reporter is different for x86-32 and x86-64: the message sizes |
954 // are different because the message struct contains a pointer. As | 955 // are different because the message struct contains a pointer. As |
955 // a result, there are two different named pipes to connect to. The | 956 // a result, there are two different named pipes to connect to. The |
956 // 64-bit one is distinguished with an "-x64" suffix. | 957 // 64-bit one is distinguished with an "-x64" suffix. |
957 pipe_name += L"-x64"; | 958 pipe_name += L"-x64"; |
958 #endif | 959 #endif |
959 | 960 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 previous_filter = SetUnhandledExceptionFilter(filter); | 1007 previous_filter = SetUnhandledExceptionFilter(filter); |
1007 } | 1008 } |
1008 | 1009 |
1009 void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings, | 1010 void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings, |
1010 std::vector<const wchar_t*>* cstrings) { | 1011 std::vector<const wchar_t*>* cstrings) { |
1011 cstrings->clear(); | 1012 cstrings->clear(); |
1012 cstrings->reserve(wstrings.size()); | 1013 cstrings->reserve(wstrings.size()); |
1013 for (size_t i = 0; i < wstrings.size(); ++i) | 1014 for (size_t i = 0; i < wstrings.size(); ++i) |
1014 cstrings->push_back(wstrings[i].c_str()); | 1015 cstrings->push_back(wstrings[i].c_str()); |
1015 } | 1016 } |
OLD | NEW |