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

Side by Side Diff: chrome/app/breakpad_win.cc

Issue 457028: Ok, here is a different approach at this change. (Closed)
Patch Set: Be even more paranoid Created 11 years 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 | « chrome/app/breakpad_win.h ('k') | chrome/browser/extensions/extensions_service.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <vector> 10 #include <vector>
(...skipping 15 matching lines...) Expand all
26 namespace { 26 namespace {
27 27
28 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\"; 28 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
29 const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices"; 29 const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
30 30
31 // This is the well known SID for the system principal. 31 // This is the well known SID for the system principal.
32 const wchar_t kSystemPrincipalSid[] =L"S-1-5-18"; 32 const wchar_t kSystemPrincipalSid[] =L"S-1-5-18";
33 33
34 google_breakpad::ExceptionHandler* g_breakpad = NULL; 34 google_breakpad::ExceptionHandler* g_breakpad = NULL;
35 35
36 std::vector<wchar_t*>* g_url_chunks = NULL; 36 // A pointer to the custom entries that we send in the event of a crash. We need
37 37 // this pointer, along with the offsets into it below, so that we can keep the
38 // A string containing the user's unique metric services id. We send this 38 // data updated as the state of the browser changes.
39 // in the crash report. 39 static std::vector<google_breakpad::CustomInfoEntry>* g_custom_entries = NULL;
40 wchar_t* g_client_id = NULL; 40 static size_t g_url_chunks_offset;
41 static size_t g_extension_ids_offset;
42 static size_t g_client_id_offset;
41 43
42 // Dumps the current process memory. 44 // Dumps the current process memory.
43 extern "C" void __declspec(dllexport) __cdecl DumpProcess() { 45 extern "C" void __declspec(dllexport) __cdecl DumpProcess() {
44 if (g_breakpad) 46 if (g_breakpad)
45 g_breakpad->WriteMinidump(); 47 g_breakpad->WriteMinidump();
46 } 48 }
47 49
48 // Reduces the size of the string |str| to a max of 64 chars. Required because 50 // Reduces the size of the string |str| to a max of 64 chars. Required because
49 // breakpad's CustomInfoEntry raises an invalid_parameter error if the string 51 // breakpad's CustomInfoEntry raises an invalid_parameter error if the string
50 // we want to set is longer. 52 // we want to set is longer.
(...skipping 16 matching lines...) Expand all
67 product = version_info->product_short_name(); 69 product = version_info->product_short_name();
68 version = version_info->product_version(); 70 version = version_info->product_version();
69 if (!version_info->is_official_build()) 71 if (!version_info->is_official_build())
70 version.append(L"-devel"); 72 version.append(L"-devel");
71 } else { 73 } else {
72 // No version info found. Make up the values. 74 // No version info found. Make up the values.
73 product = L"Chrome"; 75 product = L"Chrome";
74 version = L"0.0.0.0-devel"; 76 version = L"0.0.0.0-devel";
75 } 77 }
76 78
77 // Common entries. 79 // We only expect this method to be called once per process.
78 google_breakpad::CustomInfoEntry ver_entry(L"ver", version.c_str()); 80 DCHECK(!g_custom_entries);
79 google_breakpad::CustomInfoEntry prod_entry(L"prod", product.c_str()); 81 g_custom_entries = new std::vector<google_breakpad::CustomInfoEntry>;
80 google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32"); 82
81 google_breakpad::CustomInfoEntry type_entry(L"ptype", type.c_str()); 83 // Common g_custom_entries.
84 g_custom_entries->push_back(
85 google_breakpad::CustomInfoEntry(L"ver", version.c_str()));
86 g_custom_entries->push_back(
87 google_breakpad::CustomInfoEntry(L"plat", L"Win32"));
88 g_custom_entries->push_back(
89 google_breakpad::CustomInfoEntry(L"ptype", type.c_str()));
90
91 g_extension_ids_offset = g_custom_entries->size();
92 for (int i = 0; i < kMaxReportedActiveExtensions; ++i) {
93 g_custom_entries->push_back(google_breakpad::CustomInfoEntry(
94 StringPrintf(L"extension-%i", i + 1).c_str(), L""));
95 }
82 96
83 // Read the id from registry. If reporting has never been enabled 97 // Read the id from registry. If reporting has never been enabled
84 // the result will be empty string. Its OK since when user enables reporting 98 // the result will be empty string. Its OK since when user enables reporting
85 // we will insert the new value at this location. 99 // we will insert the new value at this location.
86 std::wstring guid; 100 std::wstring guid;
87 GoogleUpdateSettings::GetMetricsId(&guid); 101 GoogleUpdateSettings::GetMetricsId(&guid);
88 google_breakpad::CustomInfoEntry guid_entry(L"guid", guid.c_str()); 102 g_client_id_offset = g_custom_entries->size();
103 g_custom_entries->push_back(
104 google_breakpad::CustomInfoEntry(L"guid", guid.c_str()));
89 105
90 if (type == L"renderer" || type == L"plugin") { 106 if (type == L"renderer" || type == L"plugin") {
91 // Create entries for the URL. Currently we only allow each chunk to be 64 107 // Create entries for the URL. Currently we only allow each chunk to be 64
92 // characters, which isn't enough for a URL. As a hack we create 8 entries 108 // characters, which isn't enough for a URL. As a hack we create 8 entries
93 // and split the URL across the entries. 109 // and split the URL across the g_custom_entries.
94 google_breakpad::CustomInfoEntry url1(L"url-chunk-1", L""); 110 g_url_chunks_offset = g_custom_entries->size();
95 google_breakpad::CustomInfoEntry url2(L"url-chunk-2", L""); 111 for (int i = 0; i < kMaxUrlChunks; ++i) {
96 google_breakpad::CustomInfoEntry url3(L"url-chunk-3", L""); 112 g_custom_entries->push_back(google_breakpad::CustomInfoEntry(
97 google_breakpad::CustomInfoEntry url4(L"url-chunk-4", L""); 113 StringPrintf(L"url-chunk-%i", i + 1).c_str(), L""));
98 google_breakpad::CustomInfoEntry url5(L"url-chunk-5", L""); 114 }
99 google_breakpad::CustomInfoEntry url6(L"url-chunk-6", L""); 115 } else {
100 google_breakpad::CustomInfoEntry url7(L"url-chunk-7", L""); 116 // Browser-specific g_custom_entries.
101 google_breakpad::CustomInfoEntry url8(L"url-chunk-8", L""); 117 google_breakpad::CustomInfoEntry switch1(L"switch-1", L"");
118 google_breakpad::CustomInfoEntry switch2(L"switch-2", L"");
102 119
103 static google_breakpad::CustomInfoEntry entries[] = 120 // Get the first two command line switches if they exist. The CommandLine
104 { ver_entry, prod_entry, plat_entry, type_entry, guid_entry, 121 // class does not allow to enumerate the switches so we do it by hand.
105 url1, url2, url3, url4, url5, url6, url7, url8 }; 122 int num_args = 0;
123 wchar_t** args = ::CommandLineToArgvW(::GetCommandLineW(), &num_args);
124 if (args) {
125 if (num_args > 1)
126 switch1.set_value(TrimToBreakpadMax(args[1]).c_str());
127 if (num_args > 2)
128 switch2.set_value(TrimToBreakpadMax(args[2]).c_str());
129 }
106 130
107 std::vector<wchar_t*>* tmp_url_chunks = new std::vector<wchar_t*>(8); 131 g_custom_entries->push_back(switch1);
108 for (size_t i = 0; i < 8; ++i) 132 g_custom_entries->push_back(switch2);
109 (*tmp_url_chunks)[i] = entries[5 + i].value;
110 g_url_chunks = tmp_url_chunks;
111
112 g_client_id = entries[4].value;
113
114 static google_breakpad::CustomClientInfo custom_info_renderer
115 = {entries, arraysize(entries)};
116 return &custom_info_renderer;
117 } 133 }
118 134
119 // Browser-specific entries. 135 static google_breakpad::CustomClientInfo custom_client_info;
120 google_breakpad::CustomInfoEntry switch1(L"switch-1", L""); 136 custom_client_info.entries = &g_custom_entries->front();
121 google_breakpad::CustomInfoEntry switch2(L"switch-2", L""); 137 custom_client_info.count = g_custom_entries->size();
122 138
123 // Get the first two command line switches if they exist. The CommandLine 139 return &custom_client_info;
124 // class does not allow to enumerate the switches so we do it by hand.
125 int num_args = 0;
126 wchar_t** args = ::CommandLineToArgvW(::GetCommandLineW(), &num_args);
127 if (args) {
128 if (num_args > 1)
129 switch1.set_value(TrimToBreakpadMax(args[1]).c_str());
130 if (num_args > 2)
131 switch2.set_value(TrimToBreakpadMax(args[2]).c_str());
132 }
133
134 static google_breakpad::CustomInfoEntry entries[] =
135 {ver_entry, prod_entry, plat_entry, type_entry, guid_entry,
136 switch1, switch2};
137 g_client_id = entries[4].value;
138 static google_breakpad::CustomClientInfo custom_info_browser =
139 {entries, arraysize(entries)};
140 return &custom_info_browser;
141 } 140 }
142 141
143 // Contains the information needed by the worker thread. 142 // Contains the information needed by the worker thread.
144 struct CrashReporterInfo { 143 struct CrashReporterInfo {
145 google_breakpad::CustomClientInfo* custom_info; 144 google_breakpad::CustomClientInfo* custom_info;
146 std::wstring dll_path; 145 std::wstring dll_path;
147 std::wstring process_type; 146 std::wstring process_type;
148 }; 147 };
149 148
150 // This callback is executed when the browser process has crashed, after 149 // This callback is executed when the browser process has crashed, after
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 205
207 if (previous_filter) 206 if (previous_filter)
208 return previous_filter(info); 207 return previous_filter(info);
209 208
210 return EXCEPTION_EXECUTE_HANDLER; 209 return EXCEPTION_EXECUTE_HANDLER;
211 } 210 }
212 211
213 extern "C" void __declspec(dllexport) __cdecl SetActiveURL( 212 extern "C" void __declspec(dllexport) __cdecl SetActiveURL(
214 const wchar_t* url_cstring) { 213 const wchar_t* url_cstring) {
215 DCHECK(url_cstring); 214 DCHECK(url_cstring);
216 if (!g_url_chunks)
217 return;
218 215
219 std::wstring url(url_cstring); 216 std::wstring url(url_cstring);
220 size_t num_chunks = g_url_chunks->size();
221 size_t chunk_index = 0; 217 size_t chunk_index = 0;
222 size_t url_size = url.size(); 218 size_t url_size = url.size();
223 219
224 // Split the url across all the chunks. 220 // Split the url across all the chunks.
225 for (size_t url_offset = 0; 221 for (size_t url_offset = 0;
226 chunk_index < num_chunks && url_offset < url_size; ++chunk_index) { 222 chunk_index < kMaxUrlChunks && url_offset < url_size; ++chunk_index) {
227 size_t current_chunk_size = std::min(url_size - url_offset, 223 size_t current_chunk_size = std::min(url_size - url_offset,
228 static_cast<size_t>( 224 static_cast<size_t>(
229 google_breakpad::CustomInfoEntry::kValueMaxLength - 1)); 225 google_breakpad::CustomInfoEntry::kValueMaxLength - 1));
230 url._Copy_s((*g_url_chunks)[chunk_index], 226
227 wchar_t* entry_value =
228 (*g_custom_entries)[g_url_chunks_offset + chunk_index].value;
229 url._Copy_s(entry_value,
231 google_breakpad::CustomInfoEntry::kValueMaxLength, 230 google_breakpad::CustomInfoEntry::kValueMaxLength,
232 current_chunk_size, url_offset); 231 current_chunk_size, url_offset);
233 (*g_url_chunks)[chunk_index][current_chunk_size] = L'\0'; 232 entry_value[current_chunk_size] = L'\0';
234 url_offset += current_chunk_size; 233 url_offset += current_chunk_size;
235 } 234 }
236 235
237 // And null terminate any unneeded chunks. 236 // And null terminate any unneeded chunks.
238 for (; chunk_index < num_chunks; ++chunk_index) 237 for (; chunk_index < kMaxUrlChunks; ++chunk_index)
239 (*g_url_chunks)[chunk_index][0] = L'\0'; 238 (*g_custom_entries)[g_url_chunks_offset + chunk_index].value[0] = L'\0';
240 } 239 }
241 240
242 extern "C" void __declspec(dllexport) __cdecl SetClientId( 241 extern "C" void __declspec(dllexport) __cdecl SetClientId(
243 const wchar_t* client_id) { 242 const wchar_t* client_id) {
244 if (client_id == NULL) 243 if (client_id == NULL)
245 return; 244 return;
246 245
247 wcscpy_s(g_client_id, 246 wcscpy_s((*g_custom_entries)[g_client_id_offset].value,
248 google_breakpad::CustomInfoEntry::kValueMaxLength, 247 google_breakpad::CustomInfoEntry::kValueMaxLength,
249 client_id); 248 client_id);
250 } 249 }
251 250
251 extern "C" void __declspec(dllexport) __cdecl SetExtensionID(
252 int index, const wchar_t* id) {
253 DCHECK(id);
254 DCHECK(index < kMaxReportedActiveExtensions);
255
256 wcscpy_s((*g_custom_entries)[g_extension_ids_offset + index].value,
257 google_breakpad::CustomInfoEntry::kValueMaxLength,
258 id);
259 }
260
252 } // namespace 261 } // namespace
253 262
254 // This function is executed by the child process that DumpDoneCallback() 263 // This function is executed by the child process that DumpDoneCallback()
255 // spawned and basically just shows the 'chrome has crashed' dialog if 264 // spawned and basically just shows the 'chrome has crashed' dialog if
256 // the CHROME_CRASHED environment variable is present. 265 // the CHROME_CRASHED environment variable is present.
257 bool ShowRestartDialogIfCrashed(bool* exit_now) { 266 bool ShowRestartDialogIfCrashed(bool* exit_now) {
258 if (!::GetEnvironmentVariableW(env_vars::kShowRestart, NULL, 0)) 267 if (!::GetEnvironmentVariableW(env_vars::kShowRestart, NULL, 0))
259 return false; 268 return false;
260 269
261 DWORD len = ::GetEnvironmentVariableW(env_vars::kRestartInfo, NULL, 0); 270 DWORD len = ::GetEnvironmentVariableW(env_vars::kRestartInfo, NULL, 0);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 if (QueueUserWorkItem( 414 if (QueueUserWorkItem(
406 &InitCrashReporterThread, 415 &InitCrashReporterThread,
407 info.release(), 416 info.release(),
408 WT_EXECUTELONGFUNCTION) == 0) { 417 WT_EXECUTELONGFUNCTION) == 0) {
409 // We failed to queue to the worker pool, initialize in this thread. 418 // We failed to queue to the worker pool, initialize in this thread.
410 InitCrashReporterThread(info.release()); 419 InitCrashReporterThread(info.release());
411 } 420 }
412 } 421 }
413 } 422 }
414 } 423 }
OLDNEW
« no previous file with comments | « chrome/app/breakpad_win.h ('k') | chrome/browser/extensions/extensions_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698